2016-08-05 5 views
1

Ich habe eine große Menge an großen Listen von Objekten. Jedes Objekt hat eine eindeutige ID. Es sieht etwa so aus:Optimize Hashing Java

List a = {obj1, obj2, obj3} 
List b = {obj3, obj4, obj5} 
List c = {obj1, obj2, obj3} 
// up to 100 million of them 

Jetzt würde ich entfernen „Liste c“ mögen, da sie den gleichen Inhalt wie „-Liste ein“, um Speicherplatz zu sparen hat.

Zu diesem Zweck füge ich sie einfach alle zu einer Hashmap hinzu und überprüfe, ob der Schlüssel bereits existiert. Die Objekte sind tatsächlich Referenzen in einem großen Netzwerkdiagramm. Wenn nur einer falsch ist, stürzt die gesamte Anwendung ab. Denn es ist sehr wichtig, dass es nie für verschiedene Objekte der gleiche Schlüssel ist ich den Standard nicht

List.hashCode() 

Funktion verwenden, aber dies stattdessen tun:

StringBuilder sb = new StringBuilder(); 
    for (List list : myList) 
    sb.append(list.getId()); 
return Hashing.sha256().hashString(sb.toString(), Charsets.US_ASCII).toString(); 

Die perfekt funktioniert gut. Nur ist es sehr langsam. Gibt es eine Möglichkeit, das gleiche Ergebnis in kürzerer Zeit zu erzielen?

+0

Haben Sie versucht, mit dem Standard-Hash-Code Ihrer Liste? java.util.AbstractList berechnet einen Hash von jedem Objekt in der Liste. toString ist ein langsamer Vorgang und wird nicht benötigt. Wenn der Standard-Hashcode der Liste zu langsam ist, sollten Sie sich den Hashcode des Objekts in der Liste ansehen. –

+0

Ich folge nicht, warum Sie denken, dass 'List' 'hashCode()' Implementierung nicht Ihren Zweck erfüllt. –

+1

* Da es sehr wichtig ist, dass es nie den gleichen Schlüssel für verschiedene Objekte gibt *: Warum ist das so wichtig für dich? Offensichtlich wird ein SHA256-Hash sehr langsam sein. – sstan

Antwort

4

Verwenden Sie ein HashSet und die regelmäßige hashcode und methods von List Duplikate zu entfernen. Ihre Implementierungen ähneln Ihrer Idee.

So:

Set<List<String>> uniques = 
    new HashSet<>(Arrays.List<String>asList(a, b, c)); // {a, b} 
+0

Sorry, ich verstehe es nicht. Wenn ich die standardmäßige 'hashcode' Methode von' List' verwende, bekomme ich einen 'int'. Mit 100 Millionen Objekten ist die Wahrscheinlichkeit einer Kollision sehr hoch, da der Bereich von int nur etwa 4 Milliarden beträgt. Es ist wichtig, Kollisionen zu vermeiden. – Yojimbo

+0

Dann kommt '' equals'' ins Spiel: Wenn 2 Listen denselben Hashcode haben, wird die Gleichheit überprüft. –

+0

Ja! Und denken Sie daran, dass es effizient ist, weil die equals-Methode nur aufgerufen wird, wenn eine Kollision vorliegt. – JavaHopper