2014-09-17 26 views
5

tôi có một hashmap như thế này:Trong Java, bản đồ loại băm bởi key.length của nó()

HashMap<String,Integer> map = new HashMap<String,Integer>(); 
map.put("java",4); 
map.put("go",2); 
map.put("objective-c",11); 
map.put("c#",2); 

bây giờ tôi muốn sắp xếp bản đồ này theo chiều dài then chốt của nó, nếu hai phím dài đều bình đẳng (ví dụ đi và C# cả hai chiều dài 2), sau đó được sắp xếp theo thứ tự alphba. nên kết quả tôi mong đợi để nhận được là cái gì đó như:

kết quả in: Objective-C, 11 java, 4 C#, 2 đi, 2

đây là attamp của riêng tôi, nhưng nó không làm việc tại tất cả ...

 HashMap<String,Integer> map = new HashMap<String,Integer>(); 
      map.put("java",4); 
      map.put("go",2); 
      map.put("objective-c",11); 
      map.put("c#",2); 

     Map<String,Integer> treeMap = new TreeMap<String, Integer>(
       new Comparator<String>() { 
        @Override 
        public int compare(String s1, String s2) { 
         return s1.length().compareTo(s2.length()); 
        } 
       } 
     ); 

thực sự phương pháp 'compareTo' xuất hiện như màu đỏ (không có khả năng biên dịch) .... xin vui lòng ai đó giúp tôi với một số ví dụ mã ... tôi là một chút bối rối với cách sử dụng lớp so sánh để tùy chỉnh compa đối tượng lại ...

Trả lời

12

Trình biên dịch được phàn nàn vì bạn không thể gọi compareTo trên một int. Các cách chính xác để sắp xếp bản đồ như sau:

Map<String, Integer> treeMap = new TreeMap<String, Integer>(
    new Comparator<String>() { 
     @Override 
     public int compare(String s1, String s2) { 
      if (s1.length() > s2.length()) { 
       return -1; 
      } else if (s1.length() < s2.length()) { 
       return 1; 
      } else { 
       return s1.compareTo(s2); 
      } 
     } 
}); 

Hai điều kiện đầu tiên so sánh độ dài của hai String s và trả về một tích cực hay một số âm cho phù hợp. Điều kiện thứ ba sẽ so sánh từ String theo từ điển nếu độ dài của chúng bằng nhau.

2

length() không xác định phương thức compareTo đó là lý do bạn thấy lỗi. Để khắc phục nó sử dụng Integer.compare(s1.length(), s2.length()); cập nhật mã bên dưới

import java.util.Comparator; 
import java.util.HashMap; 
import java.util.Map; 
import java.util.TreeMap; 

public class Test { 

    public static void main(String[] args) { 

     HashMap<String,Integer> map = new HashMap<String,Integer>(); 
     map.put("java",4); 
     map.put("go",2); 
     map.put("objective-c",11); 
     map.put("c#",2); 


     Map<String,Integer> treeMap = new TreeMap<String, Integer>(
       new Comparator<String>() { 
        @Override 
        public int compare(String s1, String s2) { 
         return Integer.compare(s1.length(), s2.length()); 
        } 
       } 
     ); 

     treeMap.putAll(map); 

     System.out.println(treeMap); 
    } 
} 
+1

khi bạn chạy mã của bạn, kết quả là {C# = 2, java = 4, Objective-C = 11}. câu hỏi là "đi", 2 ở đâu? –

+0

Do thực tế là TreeMap đang sử dụng Comparator và so sánh được định nghĩa để xử lý 2 chuỗi có chiều dài bằng nhau như nhau. Vì OP đã chơi với TreeMap nên tôi mở rộng câu trả lời của mình để sửa chỉ phần Comparator. – sol4me

+0

ồ, bạn nghĩ gì về câu trả lời của tôi? kể từ khi op đã không đề cập rằng sử dụng treemap là bắt buộc tôi sử dụng một phong cách –

-1

Các Comparator nên là:

new Comparator<String>() { 
    @Override 
    public int compare(String s1, String s2) { 
     return Integer.compare(s1.length(), s2.length()); 
    } 
} 
+3

Không hoạt động. Nếu hai chuỗi có cùng độ dài và sử dụng TreeMap để sắp xếp, nó sẽ xem xét các khóa String có cùng độ dài như các bản sao và loại bỏ chúng. –

4

Bạn gọi String#length(), mà trả về một nguyên thủy int. Bạn cần phương thức tĩnh Integer.compare(int,int). Nếu bạn đang ở trên Java 8, bạn có thể tiết kiệm cho mình rất nhiều cách gõ:

Map<String,Integer> treeMap = new TreeMap<>(
     Comparator.comparingInt(String::length) 
        .thenComparing(Function.identity())); 
+0

thưa bạn đặt ra là {}? –

+1

Mã của tôi không thử bất kỳ đầu ra nào, nhưng nếu bạn hỏi về biểu diễn Chuỗi của một bản đồ trống, thì bạn đã đúng. –

+0

Tôi đã đăng câu hỏi này. nếu bạn có thể trả lời http://stackoverflow.com/questions/25905445/apply-distinct-function-on-treemap –

1

Nếu sử dụng TreeMapkhông bắt buộc

explantion: Xác định một Comaprator, và bước tiếp theo, hãy xác định danh sách để chúng tôi có thể thêm tất cả các mục bản đồ vào danh sách.Cuối cùng, sắp xếp danh sách bằng cách định nghĩa Comaprator

:

Comparator<Map.Entry<String,Integer>> byMapValues = 
     (Map.Entry<String,Integer> left, Map.Entry<String,Integer> right) ->left.getValue().compareTo(right.getValue()); 

List<Map.Entry<String,Integer>> list = new ArrayList<>(); 
list.addAll(map.entrySet()); 
Collections.sort(list, byMapValues); 
list.forEach(i -> System.out.println(i)); 

Output:

c#=2 
go=2 
java=4 
objective-c=11 

Lưu ý: được sắp xếp theo số

nếu có cần phải so sánh dựa trên khóa, dòng sau có thể được sử dụng.

Comparator<Map.Entry<String,Integer>> byMapKeys = 
      (Map.Entry<String,Integer> left, Map.Entry<String,Integer> right) -> left.getKey().compareTo(right.getKey()); 
1
 public int compare(String o1, String o2) { 
      return o1.length() == o2.length() ? o1.compareTo(o2) : o1.length() - o2.length(); 
     } 
Các vấn đề liên quan