2017-12-29 173 views
5

tương tự câu hỏi see: How to make HashMap work with Arrays as key?Làm thế nào để TreeMap hoạt động với các mảng làm khóa?

Nhưng tôi cần TreeMap như ((int key1, int key2) -> String), so sánh key1 sau đó so sánh key2.

giải pháp của tôi là:

Map<int[], String> map = new TreeMap<>(Comparator. 
      <int[]>comparingInt(key -> key[0]).thenComparingInt(key -> key[1])); 

Nhưng khi tôi cần ((int key1, int key2, int key3) -> String, tôi phải viết thêm.

Có cách nào để tạo Bộ so sánh cho các mảng có độ dài tùy ý không?

+1

Có lẽ cách tốt nhất là nên chỉ cần viết một 'Comparator' mà không chính xác điều đó. Tôi nghi ngờ rằng có thể được thực hiện hợp lý và dễ hiểu với lambdas. Nếu bạn có thể làm điều đó với một lambda, đi cho nó, nhưng cá nhân tôi chỉ cần sử dụng Java thường xuyên. – Obicere

Trả lời

6

Một bộ so sánh với vòng lặp sẽ thực hiện thủ thuật. Một cái gì đó như thế này, nếu tôi hiểu yêu cầu của bạn một cách chính xác. Tôi nên đề cập rằng nó giả định rằng tất cả các phím có cùng độ dài.

Map<int[], String> treeMap = new TreeMap<>((o1, o2) -> { 
     for (int i = 0; i < o1.length; i++) { 
      if (o1[i] > o2[i]) { 
       return 1; 
      } else if (o1[i] < o2[i]) { 
       return -1; 
      } 
     } 

     return 0; 
    }); 
+2

Đảm bảo kiểm tra độ dài trước. Chỉ nhập vòng lặp nếu độ dài bằng nhau. Nếu không, +1. – Obicere

+0

Điểm tốt - Tôi nhận thấy rằng khi tôi đăng nó. Tôi đã cập nhật câu trả lời ban đầu để chỉ ra giả định. –

+3

@Obicere nếu bạn làm điều này bạn phá vỡ yêu cầu đối xứng. Bạn nên trả về '+ 1' trong trường hợp mảng đầu tiên dài hơn và' -1' ngược lại (hoặc ngược lại, tùy thuộc vào thứ bạn muốn). – talex

1

Bạn có thể tạo ra một phương pháp nhà máy, mà tạo ra một so sánh so sánh độ dài của mảng và giá trị của họ:

public static Comparator<int[]> intArrayComparator(){ 
    return (left, right) -> { 
     int comparedLength = Integer.compare(left.length, right.length); 
     if(comparedLength == 0){ 
      for(int i = 0; i < left.length; i++){ 
       int comparedValue = Integer.compare(left[i], right[i]); 
       if(comparedValue != 0){ 
        return comparedValue; 
       } 
      } 
      return 0; 
     } else { 
      return comparedLength; 
     } 
    }; 
} 

nào bạn có thể gọi như sau thì:

Map<int[], String> treeMap = new TreeMap<>(intArrayComparator()); 

Trên máy so sánh có các trường hợp sau:

  • trái lớn hơn bên phải: trở 1
  • trái nhỏ hơn bên phải: trở -1
  • mục tại chỉ số i trong mảng trái lớn hơn một từ mảng bên phải: trở 1
  • mục tại chỉ số i trong mảng bên trái nhỏ hơn mảng từ mảng bên phải: trả về -1
  • Trái là chiều sâu tương đương với quyền: return 0;
10

Kể từ java-9 này có thể được đơn giản hóa rất nhiều với:

TreeMap<int[], String> map = new TreeMap<>(Arrays::compare); 
Các vấn đề liên quan