Lazy nicht modifizierbare Liste in Google Sammlungen

8

Ich habe nach einer anständigen Implementierung einer generischen faulen nicht modifizierbaren Listenimplementierung gesucht, um meine Suchergebnisse einzubinden. Der unmodifizierbare Teil der Aufgabe ist einfach, wie es von Collections.unmodifiableList() erreicht werden kann, so dass ich nur den faulen Teil aussortieren muss.

Überraschenderweise hat google-collections nichts anzubieten. während LazyList von Apache Commons Collections keine Generika unterstützt .

Ich habe einen Versuch gefunden, etwas aufzubauen über google-collections, aber es scheint unvollständig zu sein (zB unterstützt size() nicht), veraltet (kompiliert nicht mit 1.0 final) und erfordert einige externe Klassen, könnte aber als guter Ausgangspunkt für meine eigenen verwendet werden Klasse.

Kennt jemand eine gute Implementierung einer LazyList? Wenn nicht, welche Option ist Ihrer Meinung nach besser?

  • schreibe meine eigene Implementierung, basierend auf google-collections ForwardingList, ähnlich wie Peter Maas;
  • schreibe meinen eigenen Wrapper um Commons Collections LazyList (der Wrapper würde nur Generics hinzufügen, so dass ich nicht überall, sondern nur in den Wrapper selbst werfen muss);
  • schreibe einfach etwas über java.util.AbstractList ;

Alle anderen Vorschläge sind willkommen.

EDIT: Erklärung, warum ich eine faule Liste brauche.

Ich habe ein Lucene-Suchergebnis (TopDocs), das im Grunde eine Reihe von Zeigern zu Lucene-Dokumenten ist. Meine Suchergebnisklasse würde diese Zeiger als Eingabe nehmen und eine Liste von Objekten zurückgeben, die aus extrahierten und anderweitig verarbeiteten Lucene-Dokumenten bestehen. Indem ich alles in eine faule Liste verpacke, möchte ich sicherstellen, dass ich keine teure Verarbeitung mache, wenn sie unnötig ist.

    
mindas 22.04.2010, 21:07
quelle

4 Antworten

4

Ich habe das tatsächlich auf andere Weise gelöst. Statt faul und unveränderbar zu bleiben, habe ich einfach java.lang.Iterable<T> implementiert. Die Implementierung löst UnsupportedOperationException auf remove() aus.

Ich musste einige andere Code-Teile etwas modifizieren, etwas aufgeben, aber ich glaube, das war die beste Wahl. Iterable erlaubt das Einfügen in eine foreach-Schleife.

Entschuldigen Sie die Enttäuschung, wenn dies für jemanden in einer ähnlichen Situation keine gangbare Wahl ist, und vielen Dank für die Ideen.

    
mindas 23.04.2010, 16:47
quelle
5

Google-Sammlungen und Guavas Lists.transform Methode gibt Ihnen die Faulheit, die Sie suchen. Das Festhalten mit Iterables.transform sollte genauso gut sein.

Aber wenn Sie auch besorgt sind, dass die Ergebnisse im Cache gespeichert werden sollen, sobald sie erstellt wurden, nun ... gerade jetzt, das ist das Beste, was ich vorhabe, und es wird nicht sehr beruhigend sein:

%Vor%

Ja, du kannst lachen. Und du solltest es wahrscheinlich tun. Ich ... empfehle das nicht wirklich. Immer noch weniger Code als das, was Sie gerade tun. Und ich habe es gerade getestet ... es funktioniert.

    
Kevin Bourrillion 23.04.2010 18:10
quelle
4

Es gibt ein Projekt, in dem Apache commons-collections generische Funktionen hinzugefügt haben:

Ссылка

(Commons-Sammlungen mit Generika)

    
Grzegorz Oledzki 23.04.2010 10:04
quelle
2

Die Lösung von Peter Maas, die Sie verlinken, sieht gut aus - ich schlage vor, dass Sie damit arbeiten, anstatt Zeit damit zu verbringen, dies neu zu erfinden. Ersetzen Sie einfach Factory<T> durch Supplier<T> (in Google Collections enthalten). Seine Implementierung von subList ist auch ziemlich clever, obwohl sie einige besondere Implikationen hat: Wenn Sie subList() erhalten und versuchen, ein Element aus den Grenzen der SubList hinzuzufügen, erhalten Sie keine IndexOutOfBoundsException (als korrekte SubList sollte tun), aber Sie werden zusätzliche Elemente in die Liste einfügen. Die Wahrscheinlichkeit ist, dass Sie keine Unterlisten benötigen, also wäre es am sichersten, diese Methode zu implementieren, indem Sie UnsupportedOperationException (oder eine LazyList mit einem zusätzlichen Flag dafür, ob sie um get() Aufrufe über ihre Größe hinaus wachsen darf) erstellen: wenn es von subList erstellt wurde, dann ist es nicht).

size() wird unterstützt (automatisch, von ForwardingList selbst).

Update: Beachten Sie, dass, wie Kevin sagte, Sie nicht erklärt haben, warum so etwas wirklich das ist, was Sie brauchen. Vielleicht möchten Sie auch überlegen, ob so etwas anwendbar ist:

%Vor%

Da List<T> und Map<Integer, T> mehr oder weniger den gleichen abstrakten Datentyp darstellen, und da aus Ihrem Kommentar hervorgeht, dass (1) Nullen nicht als Elemente (gut!) und ( 2) dass Ihre Struktur spärlich sein könnte, wo eine tatsächliche ArrayList verschwenderisch wäre.

    
Dimitris Andreou 22.04.2010 21:19
quelle

Tags und Links