Karte der Grundelemente in Java

1. Übersicht

In diesem Tutorial erfahren Sie, wie Sie eine Karte mit primitiven Schlüsseln und Werten erstellen.

Wie wir wissen, erlauben die Java- Kernkarten nicht die Speicherung primitiver Schlüssel oder Werte. Aus diesem Grund werden wir einige externe Bibliotheken von Drittanbietern vorstellen, die primitive Kartenimplementierungen bereitstellen.

2. Eclipse-Sammlungen

Eclipse Collections ist ein leistungsstarkes Sammlungsframework für Java . Es bietet verbesserte Implementierungen sowie einige zusätzliche Datenstrukturen, einschließlich mehrerer primitiver Sammlungen.

2.1. Veränderbare und unveränderliche Karten

Erstellen wir eine leere Karte, in der sowohl Schlüssel als auch Werte primitive int s sind. Dafür verwenden wir die IntIntMaps- Factory-Klasse:

MutableIntIntMap mutableIntIntMap = IntIntMaps.mutable.empty();

Die IntIntMaps- Factory-Klasse ist die bequemste Methode zum Erstellen primitiver Karten . Es ermöglicht uns, sowohl veränderbare als auch unveränderliche Instanzen des gewünschten Kartentyps zu erstellen. In unserem Beispiel haben wir die veränderbare Instanz von IntIntMap erstellt . In ähnlicher Weise können wir ein unveränderliches Beispiel durch einfaches Austauschen des erstellen IntIntMaps.mutable statischen Factory - Aufrufs mit IntIntMaps.immutable :

ImmutableIntIntMap immutableIntIntMap = IntIntMaps.immutable.empty();

Fügen wir also unserer veränderlichen Karte ein Schlüssel-Wert-Paar hinzu:

mutableIntIntMap.addToValue(1, 1);

Ebenso können wir gemischte Karten mit Schlüssel-Wert-Paaren vom Referenz- und Primitivtyp erstellen. Erstellen wir eine Map mit String- Schlüsseln und doppelten Werten:

MutableObjectDoubleMap dObject = ObjectDoubleMaps.mutable.empty();

Hier haben wir die Factory-Klasse ObjectDoubleMaps verwendet , um eine veränderbare Instanz für MutableObjectDoubleMap zu erstellen .

Fügen wir nun einige Einträge hinzu:

dObject.addToValue("price", 150.5); dObject.addToValue("quality", 4.4); dObject.addToValue("stability", 0.8);

2.2. Ein primitiver API-Baum

In Eclipse Collections gibt es eine Basisschnittstelle namens PrimitiveIterable. Dies ist die Basisschnittstelle für jeden der primitiven Container der Bibliothek. Alle sind genannt PrimitiveTypeIterable , wo PrimitiveType sein kann Int, Lang , Kurz , Byte , Char , Float , Doppel- oder Boolean .

Alle diese Basisschnittstellen haben wiederum einen Baum von XY- Map- Implementierungen, der danach unterteilt ist, ob die Map veränderlich oder unveränderlich ist . Als Beispiel für IntIntMap haben wir MutableIntIntMap und ImmutableIntIntMap .

Schließlich haben wir, wie wir oben gesehen haben, Schnittstellen, um alle Arten von Kombinationen von Typen für Schlüssel und Werte für primitive und Objektwerte abzudecken . So können wir beispielsweise IntObjectMap für einen primitiven Schlüssel mit einem Objektwert oder ObjectIntMap für den umgekehrten Fall verwenden.

3. HPPC

HPPC ist eine Bibliothek, die auf hohe Leistung und Speichereffizienz ausgerichtet ist. Dies bedeutet, dass die Bibliothek weniger abstrakt ist als andere. Dies hat jedoch den Vorteil, dass die Einbauten nützlichen Manipulationen auf niedriger Ebene ausgesetzt werden. Es bietet sowohl Karten als auch Sets.

3.1. Ein einfaches Beispiel

Beginnen wir mit der Erstellung einer Karte mit einem int- Schlüssel und einem langen Wert. Dies zu verwenden ist ziemlich vertraut:

IntLongHashMap intLongHashMap = new IntLongHashMap(); intLongHashMap.put(25, 1L); intLongHashMap.put(150, Long.MAX_VALUE); intLongHashMap.put(1, 0L); intLongHashMap.get(150);

HPPC bietet Karten für alle Kombinationen von Schlüsseln und Werten:

  • Grundschlüssel und Grundwert
  • Primitiver Schlüssel und Objekttypwert
  • Objekttypschlüssel und primitiver Wert
  • Sowohl Objekttypschlüssel als auch Wert

Objekttypkarten unterstützen Generika:

IntObjectOpenHashMap ObjectIntOpenHashMap 

Die erste Karte hat einen primitiven int- Schlüssel und einen BigDecimal- Wert. Die zweite Karte hat LocalDate für ihre Schlüssel und int für ihre Werte

3.2. Hash Maps vs Scatter Maps

Aufgrund der Art und Weise, wie Schlüssel-Hashing- und Verteilungsfunktionen traditionell implementiert werden, kann es beim Hashing der Schlüssel zu Kollisionen kommen. Abhängig von der Verteilung der Schlüssel kann dies zu Leistungsproblemen auf großen Karten führen. Standardmäßig implementiert HPPC eine Lösung, die dieses Problem vermeidet.

Es gibt jedoch immer noch einen Platz für Karten mit einer einfacheren Verteilungsfunktion. Dies ist nützlich, wenn die Karten als Nachschlagetabellen oder zum Zählen verwendet werden oder wenn sie nach dem Laden nicht viele Schreibvorgänge erfordern . HHPC bietet Scatter Maps , um die Leistung noch weiter zu steigern.

Alle Scatter-Map-Klassen behalten dieselbe Namenskonvention wie Maps bei, verwenden jedoch stattdessen das Wort Scatter :

  • IntScatterSet
  • IntIntScatterMap
  • IntObjectScatterMap

4. Fastutil

Fastutil ist ein schnelles und kompaktes Framework , das typspezifische Sammlungen einschließlich primitiver Typzuordnungen bereitstellt.

4.1. Schnelles Beispiel

Ähnlich wie bei Eclipse Collections und HPPC. Fastutil bietet auch Assoziationskarten vom Typ Primitiv zu Primitiv und Primitiv zu Objekt.

Let's create an int to boolean map:

Int2BooleanMap int2BooleanMap = new Int2BooleanOpenHashMap();

And now, let's add some entries:

int2BooleanMap.put(1, true); int2BooleanMap.put(7, false); int2BooleanMap.put(4, true);

Then, we can retrieve values from it:

boolean value = int2BooleanMap.get(1);

4.2. In-Place Iteration

Standard JVM collections that implement the Iterable interface usually create a fresh temporary iterator object at each iteration step. With huge collections, this can create a garbage collection issue.

Fastutil provides an alternative that greatly mitigates this:

Int2FloatMap map = new Int2FloatMap(); //Add keys here for(Int2FloatMap.Entry e : Fastutil.fastIterable(map)) { //e will be reused on each iteration, so it will be only one object } 

Fastutil also provides the fastForeach method. This will take a Consumer functional interface and perform a lambda-expression for each loop:

Int2FloatMap map = new Int2FloatMap(); //Add keys here Int2FloatMaps.fastForEach(map , e -> { // e is also reused across iterations }); 

This is very similar to the standard Java foreach construct:

Int2FloatMap map = new Int2FloatMap(); //Add keys here map.forEach((key,value) -> { // use each key/value entry }); 

5. Conclusion

In diesem Artikel haben wir gelernt, wie Sie mit Eclipse Collections, HPPC und Fastutil primitive Karten in Java erstellen .

Wie immer ist der Beispielcode für diesen Artikel auf GitHub verfügbar.