Wenn ich gut verstanden habe, versuchen Sie symmetric difference zwischen den beiden Karteneintragsmengen zu berechnen.
In Anbetracht des umständlichen Verhaltens, das Sie erwähnt haben, wollen wir uns das obige Codeverhalten genauer ansehen. Zum Beispiel, wenn wir das Zahlenbeispiel aus dem oben angegebenen Link nehmen:
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("a", 1);
map1.put("b", 2);
map1.put("c", 3);
map1.put("d", 4);
Map<String, Object> map2 = new HashMap<String, Object>();
map2.put("a", 1);
map2.put("d", 4);
map2.put("e", 5);
Nachdem Sie den Unterschied, wie gezeigt, die Ausgabe zu berechnen:
System.out.println(Arrays.deepToString(diff12.toArray()));
gibt:
[e=5, c=3, b=2]
das ist das richtige Ergebnis Aber wenn wir es tun, wie folgt:
public class CustomInteger {
public int val;
public CustomInteger(int val) {
this.val = val;
}
@Override
public String toString() {
return String.valueOf(val);
}
}
map1.put("a", new CustomInteger(1));
map1.put("b", new CustomInteger(2));
map1.put("c", new CustomInteger(3));
map1.put("d", new CustomInteger(4));
map2.put("a", new CustomInteger(1));
map2.put("d", new CustomInteger(4));
map2.put("e", new CustomInteger(5));
der gleiche Algorithmus gibt die folgende Ausgabe:
[e=5, a=1, d=4, d=4, b=2, a=1, c=3]
, die nicht korrekt ist (und könnte genauso umständlich :) beschrieben)
In Im ersten Beispiel wird die Map mit int-Werten gefüllt, die automatisch boxed zu Integer-Werten sind.
The class Integer hat eine eigene Implementierung von equals und hashCode Methoden.
Die Klasse CustomInteger implementiert diese Methoden nicht, so dass sie inherits sie aus dem omnipräsent Object class.
Die API doc für die removeAll method vom Set interface sagt der folgende:
aus dieser Menge alle Elemente entfernt, die (optional Betrieb) in der angegebenen Auflistung enthalten sind. Wenn die angegebene Auflistung ebenfalls eine Menge ist, ändert diese Operation diese Menge effektiv, so dass ihr Wert die asymmetrische Mengenabweichung der zwei Mengen ist.
Um zu bestimmen, welche Elemente in beiden Sammlungen enthalten sind, verwendet die Methode removeAll das Gleichheits Verfahren des Sammelelements.
Und das ist der Haken: Integer ist gleich Methode true zurück, wenn die beiden numerischen Werte gleich sind, während Objekts gleich wird Methode true zurück, nur, wenn es die gleiche Objekt, z.B. :
Integer a = 1; //autoboxing
Integer b = new Integer(1);
Integer c = 2;
a.equals(b); // true
a.equals(c); // false
CustomInteger d = new CustomInteger(1);
CustomInteger e = new CustomInteger(1);
CustomInteger f = new CustomInteger(2);
d.equals(e); //false
d.equals(f) // false
d.val == e.val //true
d.val == f.val //false
Wenn ich die folgenden Tutorials stark noch ein wenig unscharf ist schlagen Lesen:
Danke. Ich habe über Guave nachgedacht, aber dafür muss ich eine neue Bibliothek in das Projekt einführen, aber machen Sie das nicht. – user710818
@ user710818 Sie würden es nicht bereuen - es ist eine großartige Bibliothek – vitaly
@ user710818 Sie sollten es in Ihrem Projekt verwenden – Koerr