2010-06-19 100 views
5

thể trùng lặp:
How to sort a Map<Key, Value> on the values in Java?Sắp xếp một HashMap dựa trên Giá trị rồi Khóa?

Tôi có một HashMap loại:

HashMap<String, Integer> h = new HashMap<String, Integer>(); 

HashMap chứa một danh sách các Strings và Integer là một bộ đếm cho số lần chuỗi đã được tìm thấy. Những gì tôi muốn có thể làm là sắp xếp HashMap dựa trên các số nguyên, sau đó theo thứ tự bảng chữ cái của các chuỗi.

Tại thời điểm tôi đang giữ kỷ lục về sự xuất hiện lớn nhất của một từ (biến có tên max) và hiển thị các giá trị như sau:

public void print(){ 
    while(max > 0){ 
     for (String key : h.keySet()){ 
      if(h.get(key) == max){ 
       System.out.println(key + " " + h.get(key)); 
      } 
     } 
     max--; 
    } 
} 

Mà không sắp xếp các giá trị theo thứ tự abc, cũng nó truy cập HashMap max * h (kích thước) lần.

Giải pháp tốt hơn là gì?

+0

@krock tìm tốt. Đúng, cùng một câu hỏi. – cletus

Trả lời

3

Nhìn vào Google Guava libraries. Nó có một số Multiset tính toán cho bạn và sau đó bạn có Ordering lớp đơn giản hóa việc sắp xếp.

Tất cả những gì bạn cần làm là điền Multiset bằng các chuỗi của bạn. Nó sẽ duy trì tần số cho bạn. Sau đó, bạn có thể sắp xếp các chuỗi đó bằng cách sử dụng Ordering.

1

Có lẽ không phải là giải pháp thanh lịch nhất, nhưng làm thế nào về điều này?

//TreeSet with reversed natural ordering (big integers first) 
Map<Integer, Set<String>> h = 
    new TreeMap<Integer, Set<String>>(Collections.reverseOrder()); 
//and use TreeSet for the set... 
// ...  
// 
for(Map.Entry<Integer,Set<String>> entry : h.entrySet()){ 
    for(String str : entry.getValue()){ 
     System.out.println(str + " has occured " + entry.getKey() + " times."); 
    } 
} 
+1

'-1 * o1.compareTo (o2)' là thiếu sót. Hãy xem xét trường hợp 'compareTo' trả về' Integer.MIN_VALUE'. –

+0

@Stephen: Cảm ơn bạn đã chỉ ra! –

+0

Thực ra tôi không nên viết mã của riêng mình để đảo ngược thứ tự tự nhiên: P Thay thế bằng phương thức 'Collections.reverseOrder()' .. –

8

Dưới đây là một Comparator mà sắp xếp Map.Entry đối tượng với Comparable khóa và giá trị:

public class ValueThenKeyComparator<K extends Comparable<? super K>, 
            V extends Comparable<? super V>> 
    implements Comparator<Map.Entry<K, V>> { 

    public int compare(Map.Entry<K, V> a, Map.Entry<K, V> b) { 
     int cmp1 = a.getValue().compareTo(b.getValue()); 
     if (cmp1 != 0) { 
      return cmp1; 
     } else { 
      return a.getKey().compareTo(b.getKey()); 
     } 
    } 

} 

Bạn muốn đặt tất cả các mục bản đồ vào một danh sách và sau đó sắp xếp rằng:

List<Map.Entry<String, Integer>> list = new ArrayList<Map.Entry<String, Integer>>(h.entrySet()); 
Collections.sort(list, new ValueThenKeyComparator<String, Integer>()); 
+0

Hầu như, tôi đoán bởi vì vì cách này với những từ ít xảy ra đầu tiên hơn .. –

-2

bạn có thể sử dụng giao diện SortedMap để sắp xếp HashMap của bạn. Nó rất dễ dàng - Tự động phân loại. Tham khảo http://java.sun.com/j2se/1.4.2/docs/api/java/util/SortedMap.html. Tôi không bao gồm bất kỳ mã nào ở đây, nhưng nếu bạn cần, chỉ cần thêm nhận xét. Tôi sẽ cung cấp cho bạn một mã mẫu.

+1

- 1, SortedMap sắp xếp theo khóa, thay vì theo giá trị – whiskeysierra

+0

Bản đồ tiếp tục đảm bảo rằng nó sẽ nằm trong thứ tự khóa tăng dần, sắp xếp theo thứ tự tự nhiên của các khóa của nó (xem giao diện Comparable), hoặc bằng một bộ so sánh được cung cấp tại bản đồ đã sắp xếp thời gian sáng tạo – Vishal

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