2013-02-22 3 views
5

Ich brauche eine Sammelklasse, die beides hat: schnellen Index- und Hash-Zugriff. Jetzt habe ich ArrayList. Es hat gute Indexzugriffe, aber seine contains Methode ist nicht performant. HashSet hat eine gute contains Implementierung, aber keinen indizierten Zugriff. Welche Sammlung hat beides? Wahrscheinlich etwas von Apache? Oder sollte ich meine eigene Sammlungsklasse erstellen, die beide hat: ArrayList für indizierte Zugriffe und HashSet für contains überprüfen?Sammlung mit Index- und Hash-Zugriff

Nur zur Klarstellung: Ich brauche beide get(int index) und contains(Object o)

+2

Sie besitzen Datenstruktur, die beide enthält (oder eine Variation davon) ist wahrscheinlich der Weg zu gehen. – Dukeling

+0

Können Sie erklären, warum Sie das wollen? –

+0

Ja kann ich. Ich habe Legacy-Code, der fast alle Methoden eines List-Objekts (ArrayList) verwendet. Ich habe keine Chance, es neu zu schreiben, aber ich möchte seine Leistung erhöhen.Das Hauptproblem hier sind die Methoden contains und indexOf, da sie eine lineare Leistung haben. –

Antwort

0

Wenn Sie den Index von Anfang bis Ende durchqueren, ich denke, das Ihre Bedürfnisse befriedigen könnte: LinkedHashSet

Wenn Sie zufällig über die zugreifen müssen Index, sowie Hash-Zugriff, wenn niemand sonst einen besseren Vorschlag hat, denke ich, dass Sie Ihre eigene Sammlung machen können, die beides tut.

+2

Soweit ich sehen kann, wäre indizierter Zugriff "O (n)", was nicht besonders effizient ist. – Dukeling

+0

LinkedHashSet hat keine Methode 'get (int index)' –

+0

@SergiyMedvynskyy Ja, aber Sie können den Iterator verwenden, um es zu simulieren. – Dukeling

1

indizierte Zugriffsleistung kein Problem ist, ist die nächste Übereinstimmung LinkedHashSet API ist, das sagt, dass es

Hash-Tabelle und verknüpfte Liste Implementierung der Set-Schnittstelle, mit vorhersagbaren Iterationsreihenfolge.

zumindest denke ich nicht, dass die Leistung schlechter sein wird als die von LinkedListPerformance. Sonst kann ich keine Alternative sehen, aber Ihre ArrayList + HashTable-Lösung

+0

Ich bin mir nicht sicher, dass es wirklich besser ist –

0

Tun Sie dies; verwenden Kombination von Hash Technik sowie Liste Beste aus beiden Welten zu bekommen :)

class DataStructure<Integer>{ 
    Hash<Integer,Integer> hash = new HashMap<Integer, Integer>(); 
    List<Integer> list = new ArrayList<Integer>(); 

    public void add(Integer i){ 
     hash.add(i,i); 
     list.add(i); 
    } 
    public Integer get(int index){ 
     return list.get(index); 
    } 
    ... 
} //used Integers to make it simpler 

So Objekt; Sie halten in HashMap/HashSet sowie ArrayList.

Also, wenn Sie wollen

contains method : call hashed contains method. 

get an object with index: use array to return the value 

So stellen Sie sicher bedienen, dass Sie diese beiden Sammlungen synchron sind. Und kümmern sich um Aktualisierung/Löschung in beiden Datenstrukturen.

+0

Es ist die letzte Lücke, die ich verwenden würde, wenn ich nicht etwas besseres finden kann –

0

Ich weiß nicht die genaue Nachschlagen Zeiten, aber vielleicht könnten Sie einige Implementierung der Map interface verwenden. Sie können Ihre Objekte mit map.put(objectHash, obj) speichern.

Dann könnten Sie überprüfen, ob Sie mit einem bestimmten Objekt haben:

boolean contained = map.containsValue(obj); 

Und Sie den Hash verwenden können, um ein Objekt in der Karte zum Nachschlagen:

MyObject object = map.get(objectHash); 

Obwohl, ist der einzige Nachteil dass Sie Ihre Hashes für diesen Suchaufruf kennen müssen, der möglicherweise nicht in Ihrer Implementierung enthalten ist.

+0

containsValue für HashMap hat die gleiche Leistung wie enthält eine Liste - die lineare. Ich wünsche den Logarithmus (wenn möglich natürlich). –

+0

@SergiyMedvynskyy Ahh, das war mir nicht bewusst. Hast du einen Hinweis darauf, wo du das herausgefunden hast? –

+0

Einfach die Implementierung von HashMap sehen. Die Methode containsValue iteriert über alle Einträge und prüft auf Gleichheit wie die Methode contains von ArrayList. –

Verwandte Themen