Ich möchte ein neues Element erstellen, das ähnlich wie Util.Map.Entry
Die Struktur key
, value
enthält.
Das Problem ist, dass ich keinen Map.Entry
Instanziieren kann, da es sich um eine Schnittstelle handelt.
Weiß jemand, wie man ein neues generisches Schlüssel-/Wertobjekt für Map.Entry erstellt?
Sie können einfach das Map.Entry<K, V>
Schnittstelle selbst:
import Java.util.Map;
final class MyEntry<K, V> implements Map.Entry<K, V> {
private final K key;
private V value;
public MyEntry(K key, V value) {
this.key = key;
this.value = value;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public V setValue(V value) {
V old = this.value;
this.value = value;
return old;
}
}
Und dann benutze es:
Map.Entry<String, Object> entry = new MyEntry<String, Object>("Hello", 123);
System.out.println(entry.getKey());
System.out.println(entry.getValue());
Es gibt public static class AbstractMap.SimpleEntry<K,V>
. Lassen Sie sich von dem Teil Abstract
des Namens nicht irreführen: Es ist in der Tat [~ # ~] keine [~ # ~] Klasse abstract
(aber seine oberste Ebene AbstractMap
ist).
Die Tatsache, dass es sich um eine static
verschachtelte Klasse handelt, bedeutet, dass Sie DON'T eine umschließende AbstractMap
- Instanz benötigen, um sie zu instanziieren.
Map.Entry<String,Integer> entry =
new AbstractMap.SimpleEntry<String, Integer>("exmpleString", 42);
Wie in einer anderen Antwort erwähnt, verfügt Guava auch über eine praktische Factory-Methode static
Maps.immutableEntry
, die Sie verwenden können.
Du sagtest:
Ich kann
Map.Entry
Nicht selbst verwenden, da es sich anscheinend um ein schreibgeschütztes Objekt handelt, das ich nicht instanziieren kann.instanceof
Das ist nicht ganz richtig. Der Grund, warum Sie es nicht direkt instanziieren können (d. H. Mit new
), ist, dass es ein interface Map.Entry
ist.
Wie in der Dokumentation vermerkt, ist AbstractMap.SimpleEntry
@since 1.6
. Wenn Sie also an 5.0 festhalten, steht es Ihnen nicht zur Verfügung.
Um nach einer anderen bekannten Klasse zu suchen, die implements Map.Entry
Ist, können Sie direkt zum Javadoc gehen. Von die Java 6 Version
Interface Map.Entry
Alle bekannten implementierenden Klassen :
Leider listet Version 1.5 keine bekannte Implementierungsklasse auf, die Sie verwenden können, sodass Sie möglicherweise nicht mehr mit der Implementierung Ihrer eigenen Klasse zufrieden sind.
Versuchen Sie Maps.immutableEntry aus Guave
Dies hat den Vorteil, dass es mit Java 5 (im Gegensatz zu AbstractMap.SimpleEntry
das erfordert Java 6.)
Beispiel für AbstractMap.SimpleEntry:
import Java.util.Map;
import Java.util.AbstractMap;
import Java.util.AbstractMap.SimpleEntry;
Instanziieren:
ArrayList<Map.Entry<Integer, Integer>> arr =
new ArrayList<Map.Entry<Integer, Integer>>();
Zeilen hinzufügen:
arr.add(new AbstractMap.SimpleEntry(2, 3));
arr.add(new AbstractMap.SimpleEntry(20, 30));
arr.add(new AbstractMap.SimpleEntry(2, 4));
Zeilen holen:
System.out.println(arr.get(0).getKey());
System.out.println(arr.get(0).getValue());
System.out.println(arr.get(1).getKey());
System.out.println(arr.get(1).getValue());
System.out.println(arr.get(2).getKey());
System.out.println(arr.get(2).getValue());
Sollte ausgeben:
2
3
20
30
2
4
Es ist gut zum Definieren von Kanten von Graphenstrukturen. Wie die zwischen den Neuronen in deinem Kopf.
Ab Java 9 gibt es eine neue Utility-Methode, mit der ein unveränderlicher Eintrag erstellt werden kann, der Map#entry(Object, Object)
lautet =.
Hier ist ein einfaches Beispiel:
Entry<String, String> entry = Map.entry("foo", "bar");
Da es unveränderlich ist, wirft der Aufruf von setValue
ein UnsupportedOperationException
. Die anderen Einschränkungen sind die Tatsache, dass es nicht serialisierbar ist und null
als Schlüssel oder Wert verboten ist. Wenn es für Sie nicht akzeptabel ist, müssen Sie AbstractMap.SimpleImmutableEntry
Verwenden = oder AbstractMap.SimpleEntry
stattdessen.
NB: Wenn Sie direkt ein Map
mit 0 bis 10 (Schlüssel, Wert) Paaren erstellen möchten, können Sie dies stattdessen tun Verwenden Sie die Methoden vom Typ Map.of(K key1, V value1, ...)
.
Warum Map.Entry
? Ich denke, so etwas wie ein Schlüssel-Wert-Paar ist für den Fall geeignet.
Verwenden Java.util.AbstractMap.SimpleImmutableEntry
oder Java.util.AbstractMap.SimpleEntry
Sie könnten tatsächlich gehen mit: Map.Entry<String, String> en= Maps.immutableEntry(key, value);
org.Apache.commons.lang3.Tuple.Pair
Implementiert Java.util.Map.Entry
Und kann auch eigenständig verwendet werden.
Auch wie schon andere erwähnt, macht Guavas com.google.common.collect.Maps.immutableEntry(K, V)
den Trick.
Ich bevorzuge Pair
wegen seiner fließenden Pair.of(L, R)
-Syntax.
Ich habe eine generische Pair-Klasse definiert, die ich ständig benutze. Es ist toll. Als Bonus muss ich durch Definieren einer statischen Factory-Methode (Pair.create) die Typargumente nur halb so oft schreiben.
public class Pair<A, B> {
private A component1;
private B component2;
public Pair() {
super();
}
public Pair(A component1, B component2) {
this.component1 = component1;
this.component2 = component2;
}
public A fst() {
return component1;
}
public void setComponent1(A component1) {
this.component1 = component1;
}
public B snd() {
return component2;
}
public void setComponent2(B component2) {
this.component2 = component2;
}
@Override
public String toString() {
return "<" + component1 + "," + component2 + ">";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((component1 == null) ? 0 : component1.hashCode());
result = prime * result
+ ((component2 == null) ? 0 : component2.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
final Pair<?, ?> other = (Pair<?, ?>) obj;
if (component1 == null) {
if (other.component1 != null)
return false;
} else if (!component1.equals(other.component1))
return false;
if (component2 == null) {
if (other.component2 != null)
return false;
} else if (!component2.equals(other.component2))
return false;
return true;
}
public static <A, B> Pair<A, B> create(A component1, B component2) {
return new Pair<A, B>(component1, component2);
}
}
Wenn Sie Clojure verwenden, haben Sie eine andere Option:
(defn map-entry
[k v]
(clojure.lang.MapEntry/create k v))