webentwicklung-frage-antwort-db.com.de

Java - Wie erstelle ich einen neuen Eintrag (Schlüssel, Wert)

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?

257
Spiderman

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());
77
Jesper

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 staticMaps.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.


Einschränkung und Tipp

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.

724

Versuchen Sie Maps.immutableEntry aus Guave

Dies hat den Vorteil, dass es mit Java 5 (im Gegensatz zu AbstractMap.SimpleEntry das erfordert Java 6.)

48
finnw

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.

34
Eric Leschinski

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, ...) .

29
Nicolas Filotto

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

13
tanghao

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.

6
parxier

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);
    }

}
4
Nels Beckman

Wenn Sie Clojure verwenden, haben Sie eine andere Option:

(defn map-entry
  [k v]
  (clojure.lang.MapEntry/create k v))
3