2012-09-27 8 views
10

(Es gibt einige Fragen über zeiteffiziente spärliche Arrays, aber ich bin auf der Suche für die Speichereffizienz.)speichereffiziente spärliche Array in Java

Ich brauche das Äquivalent eines List<T> oder Map<Integer,T> die

  1. Kann bei Bedarf wachsen, indem ein Schlüssel größer als zuvor festgelegt wird. (Kann davon ausgehen, Schlüssel sind nicht negativ.)
  2. Ist etwa so speichereffizient wie ein ArrayList<T> in dem Fall, dass die meisten Indizes nicht null, d. H. Wenn die tatsächlichen Daten nicht sehr spärlich ist.
  3. Wenn die Indizes spärlich sind, wird Platz verbraucht, der proportional zur Anzahl der Indizes ist, die nicht null sind.
  4. Verwendet weniger Speicher als HashMap<Integer,T> (da dies die Schlüssel automatisch autoboxiert und wahrscheinlich nicht den skalaren Schlüsseltyp nutzt).
  5. Kann ein Element in amortisierter Log (N) Zeit erhalten oder setzen, wobei N die Anzahl der Einträge ist: Es muss keine lineare Zeit sein, binäre Suche wäre akzeptabel.
  6. Implementiert in einer nichtviralen Open-Source-Java-Bibliothek (vorzugsweise in Maven Central).

Kennt jemand solch eine Nutzungsklasse?

Ich hätte erwartet, dass Commons Collections eins haben, aber es scheint nicht zu sein.

Ich bin auf org.apache.commons.math.util.OpenIntToFieldHashMap gestoßen, das fast richtig aussieht, außer dem Werttyp ist ein FieldElement, der unentgeltlich scheint; Ich möchte nur T extends Object. Es sieht so aus, als ob es einfacher wäre, seinen Quellcode zu bearbeiten, um allgemeiner zu sein, obwohl ich lieber eine binäre Abhängigkeit verwenden würde, wenn eine verfügbar ist.

Antwort

6

Ich würde versuchen mit trove Sammlungen, gibt es TIntObjectMap, die für Ihre Absichten arbeiten können.

+0

Das sieht gut aus. Ich habe versucht, 'OpenIntToFieldHashMap' an einen generischen Werttyp anzupassen, der mit ~ 10min Arbeit funktioniert zu haben scheint, aber nur geringfügig besser als' TIntObjectMap' funktioniert. –

1

Ich habe meinen Testfall als jglick/inthashmap gespeichert. Die Ergebnisse:

HashMap size: 1017504 
TIntObjectMap size: 853216 
IntHashMap size: 846984 
OpenIntObjectHashMap size: 760472 
+1

Wo finde ich IntHashMap? – oleh

+0

@oleh wahrscheinlich Apache commons (?) – Karussell

+1

Sorry, 'IntHashMap' war meine Adaption von' OpenIntToFieldHashMap' von Commons Math. Da es kaum besser als "TIntObjectMap" war, habe ich diesen Ansatz abgelehnt. –

4

Ich würde Android SparseArray Implementierung für Inspiration betrachten. Sie können die Quelle anzeigen, indem Sie den Quellcode von AOSP hier herunterladen http://source.android.com/source/downloading.html

+0

https://code.google.com/p/android-source-browsing/source/browse/core/java/android/util/SparseArray.java?spec=svn.platform--frameworks--base.58aff7debfdab8ca99dd6bfcfa0c7bebdf2d303b&repo=platform --frameworks - base & r = 58aff7debfdab8ca99dd6bfcfa0c7bebdf2d303b scheint angemessen zu sein - die amortisierte Laufzeit ist undokumentiert, aber von der Inspektion her vermute ich, dass sie logarithmisch ist - und ist unter ASL 2.0, was in Ordnung ist. Leider ist es nicht in Central, die ich kenne, und würde es von nicht verwandten Dingen wie Android Bluetooth-Unterstützung, die alle in der gleichen Quelle root ist entkoppelt werden wollen. –

+1

Hier ist eine in sich geschlossene Version, die für die Spitze von android https://github.com/frostwire/frostwire-jlibtorrent/blob/b4b3f9a90d7a1dade864d7e3eaa88b616f200a9a/src/com/frostwire/jlibtorrent/SparseArray.java – Gubatron

1

Ich werde vorschlagen, dass Sie OpenIntObjectHashMap von Colt Bibliothek verwenden. Link

+0

Dank all den notwendigen Code verwendet . Es hat tatsächlich einen moderat, aber signifikant geringeren Platzverbrauch als die Alternativen. Ich habe dies in meinen überarbeiteten Testfall aufgenommen. –