2010-08-09 32 views
7

Tôi đã thiết lập một HashMap như vậy:Làm thế nào tôi có thể trích xuất ArrayList từ HashMap và lặp qua nó trong Java?

Map<String, ArrayList<String>> theAccused = new HashMap<String, ArrayList<String>>(); 

... và tôi cư này bằng cách lưu trữ cho mỗi tên (key), một danh sách tên (giá trị). Vì vậy:

ArrayList<String> saAccused = new ArrayList<String>(); 
// populate 'saAccused' ArrayList 
... 
// done populating 
theAccused.put(sAccuser, saAccused); 

Vì vậy, bây giờ, tôi muốn xem xét thông qua tất cả các mục trong HashMap và xem nếu (đối với từng 'sAccuser'), danh sách 'saAccused' chứa một tên nào đó. Đây là thất bại của tôi cho đến nay:

Set<String> setAccusers = theAccused.keySet(); 
Iterator<String> iterAccusers = setAccusers.iterator(); 
iterAccusers.next(); 
ArrayList<String> saTheAccused; 

// check if 'sAccuser' has been accused by anyone before 
for (int i = 0; i < theAccused.size(); i++) { 
    saTheAccused = theAccused.get(iterAccusers); 

    if (saTheAccused.contains(sAccuser)) { 

    } 
    iterAccusers.next(); 
} 

... tuy nhiên tôi không chắc chắn như thế nào SetIterator lớp làm việc:/Vấn đề là tôi không có "giá trị" ... các tên ... các 'sAccuser' s ... cho HashMap có sẵn.

Tóm lại, tôi muốn lặp qua HashMap và kiểm tra xem tên cụ thể có được lưu trữ trong bất kỳ danh sách nào không. Vì vậy, làm thế nào tôi có thể làm điều này? Hãy cho tôi biết nếu bạn cần tôi đi sâu vào chi tiết hơn hoặc làm sáng tỏ bất kỳ sự nhầm lẫn nào.

Cảm ơn.

+1

+1 Sheesh! Một loạt các câu trả lời nhưng không một trong những người trả lời làm phiền để upvote câu hỏi? Một upvote có nghĩa là câu hỏi được viết tốt, cụ thể và hiển thị những gì người dùng đã thử. Câu hỏi này đáp ứng tất cả các yêu cầu cho một upvote. –

+0

@Jim ... :) Cảm ơn bạn! Wow ... cảm thấy thật tuyệt khi cuối cùng cũng có ai đó nhận ra tôi theo cách này. Cảm ơn bạn rất nhiều ... Tôi muốn một số người hơn nghĩ như bạn :) Cảm ơn! 1 để xác định rằng câu hỏi của tôi đáp ứng tất cả các yêu cầu cho một upvote. – Hristo

+0

@Jim Garrison bạn nói đúng, nhưng đối với tôi có thêm hai yêu cầu - câu hỏi nên khó và lợi ích chung - tức là khi bạn gặp vấn đề, googling nên dẫn đến câu hỏi này. – Bozho

Trả lời

4

Tóm lại, tôi muốn lặp qua HashMap và kiểm tra xem một tên cụ thể có được lưu trữ trong bất kỳ danh sách nào không. Vì vậy, làm thế nào tôi có thể làm điều này?

Có hai cách để lặp qua bản đồ có thể quan tâm ở đây. Thứ nhất, bạn có thể lặp qua tất cả các ánh xạ (tức là các cặp quan hệ khóa-giá trị) bằng cách sử dụng phương thức entrySet(), phương pháp này sẽ cho bạn biết khóa là gì cho mỗi danh sách. Ngoài ra, nếu bạn không cần khóa, bạn có thể chỉ cần nhận tất cả danh sách lần lượt thông qua phương thức values(). Sử dụng tùy chọn đầu tiên có thể trông như thế này:

for (Map.Entry<String, ArrayList<String>> entry : theAccused.entrySet()) 
{ 
    String sListName = entry.getKey(); 
    ArrayList<String> saAccused = entry.getValue(); 
    if (saAccused.contains(sAccuser)) 
    { 
     // Fire your logic for when you find a match, which can 
     // depend on the list's key (name) as well 
    } 
} 

Để trả lời những câu hỏi rộng hơn - giao diện đơn giản Set đại diện cho một (có thứ tự) tập hợp các giá trị không trùng lặp. Như bạn có thể thấy bởi Javadoc được liên kết, có các phương thức có sẵn mà bạn có thể mong đợi cho một bộ sưu tập không có thứ tự như vậy. An Iterator là một đối tượng truyền tải một số cấu trúc dữ liệu trình bày từng phần tử lần lượt.sử dụng điển hình của một iterator sẽ trông giống như sau:

Iterator<?> it = ...; // get the iterator somehow; often by calling iterator() on a Collection 
while (it.hasNext()) 
{ 
    Object obj = it.next(); 
    // Do something with the obj 
} 

có nghĩa là, kiểm tra xem các iterator được nonexhausted (có nhiều yếu tố) sau đó gọi các next() phương pháp để có được yếu tố đó. Tuy nhiên, vì mô hình trên là rất phổ biến, nó có thể được elided với Java 5 của foreach loop, sparing bạn từ giao dịch với iterator chính nó, như tôi đã lợi dụng trong ví dụ đầu tiên của tôi.

+0

Wow ... Cảm ơn phản hồi đó! Câu hỏi nhanh ... khi bạn nói 'Iterater it = ...;', nó bằng với một phần tử, trong trường hợp của tôi, nó có bằng một phần tử từ Set không? Cảm ơn bạn đã liên kết tới 'for-each'. Tôi chưa bao giờ sử dụng nó. Câu trả lời sao! – Hristo

+0

Ngoài ra ... nếu chúng ta quay trở lại vòng lặp của bạn ... nếu tôi tìm thấy một trận đấu, làm thế nào tôi có thể trích xuất tên (khóa) của ArrayList có chứa 'sAccuser'? – Hristo

+1

@Hristo - biến 'it' sẽ là một đối tượng sẽ trả về các phần tử kế tiếp của bộ sưu tập cơ bản mỗi khi phương thức' next() 'của nó được gọi, không phải là một phần tử. Đối với câu hỏi thứ hai của bạn, tôi đã sửa đổi ví dụ của tôi để hiển thị nó bằng cách sử dụng 'entrySet()', vì đây là cách để lặp lại trên một Map khi bạn quan tâm đến cả hai khóa * và * các giá trị. –

0

Bạn cần sử dụng giá trị từ Iterator.next() để lập chỉ mục vào Map.

String key = iterAccusers.next(); 
saTheAccused = theAccused.get(key); 

Hiện tại bạn đang nhận được giá trị từ Map dựa trên iterator, không phải là giá trị được trả về bởi các iterator.

3

Một cái gì đó như thế này?

for (List<String> list : theAccused.values()) { 
    if (list.contains("somename")) { 
     // found somename 
    } 
} 
2

này nên làm cho nó hoạt:

saTheAccused = theAccused.get(iterAccused.next()); 

Tuy nhiên, để làm cho mã của bạn dễ đọc hơn, bạn có thể có một trong hai:

for (List<String> values : theAccused.values()) { 
    if (value.contains(sAcuser)) { 
     .. 
    } 
} 

hoặc, nếu bạn cần chìa khóa:

for (String key : theAccused.keySet()) { 
    List<String> accused = theAccused.get(key); 
    if (accused.contains(sAccuser)) { 
    } 
} 
+0

Cảm ơn. Đây là những gì tôi cần. Do sửa đổi câu trả lời của bạn mặc dù ... Tôi đã tìm kiếm một ArrayList ... Tôi không muốn bạn nhận được downvoted cho một lý do ngu ngốc :) – Hristo

+0

@ Bạn có được một ArrayList', nhưng bạn tham khảo nó bằng giao diện của nó - ' List', được coi là một thực hành tốt hơn (trừ khi bạn thực sự cần các phương thức cụ thể cho 'ArrayList') – Bozho

+2

Nếu bạn cần cả khóa và giá trị, bạn nên sử dụng entrySet, thay vì keySet và get. – ILMTitan

0

Thực hiện một phương pháp nào đó:

private String findListWithKeyword(Map<String, ArrayList<String>> map, String keyword) { 
    Iterator<String> iterAccusers = map.keySet().iterator(); 
    while(iterAccusers.hasNext()) { 
     String key = iterAccusers.next(); 
     ArrayList<String> list = theAccused.get(key); 
     if (list.contains(keyword)) { 
     return key; 
     } 
    } 
} 

Và khi bạn gọi phương thức:

String key = findListWithKeyword(map, "foobar"); 
ArrayList<String> theCorrectList = map.get(key); 
+0

.. cảm ơn phản hồi của bạn. Tôi đã viết một phương pháp đang làm điều này. Đây là điểm của câu hỏi của tôi :) Câu hỏi nhanh ... khi bạn nói 'Iterater iterAccusers = ...;', là iterAccusers tương đương với một phần tử, trong trường hợp của tôi, nó bằng với một phần tử từ Set, hoặc là nó chưa được khởi tạo để bắt đầu? – Hristo

+0

Ngoài ra, một câu hỏi nữa ... nếu tôi tìm thấy một kết quả phù hợp, làm thế nào tôi có thể trích xuất tên (khóa) của ArrayList chứa 'sAccuser' mà nó thuộc về? – Hristo

+0

iterAccusers là một Iterator, tức là bạn có thể gọi next() trên nó và lấy phần tử tiếp theo. Nó giống như một vòng lặp for-each. Trình lặp không phải là một phần tử trong tập hợp, nó là một đối tượng được sử dụng để lặp qua bộ này. Để trích xuất khóa. Thay vì trả lại danh sách, chỉ cần trả lại khóa. Xem mã đã chỉnh sửa. – Jes

0

Có vẻ như bạn cần phải làm hai việc: thứ nhất, tìm hiểu xem một tên được đặt là "bị cáo buộc" và thứ hai, tìm ra người tố cáo là ai. Để làm được điều đó, bạn cần lặp lại các đối tượng Entry trong Map của bạn.

for (Entry<String, List<String>> entry : theAccused.entrySet()) { 
     if (entry.getValue().contains(accused)) { 
      return entry.getKey(); 
     } 
    } 

    return null; // Or throw NullPointerException, or whatever. 

Trong vòng lặp này, đối tượng Nhập giữ một ánh xạ khóa-giá trị duy nhất. Vì vậy, entry.getValue() chứa danh sách bị cáo, và entry.getKey() chứa người tố cáo của họ.

+0

.. đối tượng Entry là gì? Tôi chưa gặp phải điều đó. – Hristo

+0

Nó thực sự là một lớp bên trong của bản đồ. Tên lớp đầy đủ là java.util.Map.Entry. (JavaDoc là ở đây: http://download.oracle.com/javase/1.5.0/docs/api/java/util/Map.Entry.html) Theo kinh nghiệm của tôi, nó hiếm khi được sử dụng. Tuy nhiên, trong trường hợp này nó phục vụ độc đáo, và vì nó là một phần của Map API, nên không có lý do gì để không sử dụng nó. – DeathB4Decaf

Các vấn đề liên quan