2017-12-29 27 views
5

ähnliche Frage: How to make HashMap work with Arrays as key?Wie TreeMap mit Arrays als Schlüssel arbeiten? siehe

Aber ich brauche TreeMap wie ((int key1, int key2) -> String), zu vergleichen key1 dann key2 zu vergleichen.

Meine Lösung ist:

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

Aber wenn ich ((int key1, int key2, int key3) -> String müssen, muss ich mehr schreiben.

Gibt es eine Möglichkeit, den Vergleicher für Arrays mit beliebiger Länge zu generieren?

+1

wahrscheinlich der beste Weg wäre, nur einen 'Comparator' zu schreiben, die genau das tut. Ich bezweifle, dass das vernünftig und verständlicherweise mit lambdas gemacht werden könnte. Wenn Sie es mit einem Lambda tun können, gehen Sie dafür, aber persönlich würde ich nur normales Java verwenden. – Obicere

Antwort

6

Ein Komparator mit einer Schleife sollte den Trick machen. So etwas, wenn ich deine Anforderung richtig verstanden habe. Ich sollte erwähnen, dass es davon ausgeht, dass alle Schlüssel die gleiche Länge haben.

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

Überprüfen Sie zuerst die Längen. Geben Sie die Schleife nur ein, wenn die Längen gleich sind. Andernfalls +1. – Obicere

+0

Guter Punkt - das habe ich bemerkt, als ich es gepostet habe. Ich habe die ursprüngliche Antwort aktualisiert, um die Annahme anzuzeigen. –

+3

@Obicere Wenn Sie dies tun, brechen Sie die Symmetrieanforderung. Sie sollten '+ 1' zurückgeben, falls das erste Array länger ist und andernfalls '-1' (oder umgekehrt, je nachdem, was Sie wollen). – talex

1

Sie könnten eine Factory-Methode machen, die einen Komparator vergleicht die Längen der Felder und deren Werte schafft:

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; 
     } 
    }; 
} 

, die Sie mögen das nennen könnte dann folgendes:

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

Der obige Vergleicher hat folgende Fälle:

  • links größer als rechts: return 1
  • links kleiner als rechts: return -1
  • Artikel bei Index i in der linken Reihe ist größer als die von der rechten Array: return 1
  • Artikel bei Index i im linken Array ist kleiner als das vom rechten Array: zurück -1
  • Links ist tief gleich nach rechts: zurück 0;
10

Da Java-9 dies stark mit vereinfacht werden könnte:

TreeMap<int[], String> map = new TreeMap<>(Arrays::compare);