web-dev-qa-db-ja.com

Java - 新しいエントリ(キー、値)の作り方

構造体keyvalueを含むUtil.Map.Entryと同様の新しいアイテムを作成したいと思います。

問題は、Map.Entryはインターフェースなのでインスタンス化できないことです。

Map.Entryの新しい汎用キー/値オブジェクトを作成する方法を知っている人はいますか?

246
Spiderman

Map.Entry<K, V>インターフェースを自分で実装することができます。

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

そしてそれを使う:

Map.Entry<String, Object> entry = new MyEntry<String, Object>("Hello", 123);
System.out.println(entry.getKey());
System.out.println(entry.getValue());
76
Jesper

public static class AbstractMap.SimpleEntry<K,V> があります。名前のAbstractの部分を誤解させないでください。実際には _は_ ではなくabstractクラスです(ただし、その最上位レベルの AbstractMap は).

それがstaticネストクラスであるという事実は、インスタンス化するために DON'T を囲むAbstractMapインスタンスが必要であることを意味します。

Map.Entry<String,Integer> entry =
    new AbstractMap.SimpleEntry<String, Integer>("exmpleString", 42);

別の回答で述べたように、Guavaには便利なstaticファクトリメソッド Maps.immutableEntry もあります。


あなたが言った:

Map.Entry自体を使用することはできません。なぜなら、それは新しいinstanceofをインスタンス化できないのは明らかに読み取り専用のオブジェクトだからです。

それは完全に正確というわけではありません。直接(つまりnewで)インスタンス化できないのは、それが interface Map.Entry だからです。


警告とヒント

ドキュメントに記載されているように、AbstractMap.SimpleEntry@since 1.6なので、5.0に固定されている場合は利用できません。

implements Map.Entryという別の既知のクラスを探すには、実際には直接javadocにアクセスできます。 Java 6バージョン から

インタフェースMap.Entry

すべての既知の実装クラス

残念なことに 1.5 version はあなたが使うことができる既知の実装クラスをリストしていないので、あなたはあなた自身の実装で行き詰まっているかもしれません。

689

Maps.immutableEntry から Guava を試してください

これには、Java 5と互換性があるという利点があります(Java 6が必要なAbstractMap.SimpleEntryとは異なります)。

43
finnw

AbstractMap.SimpleEntryの例:

import Java.util.Map; 
import Java.util.AbstractMap;
import Java.util.AbstractMap.SimpleEntry;

インスタンス化:

ArrayList<Map.Entry<Integer, Integer>> arr = 
    new ArrayList<Map.Entry<Integer, Integer>>();

行を追加します。

arr.add(new AbstractMap.SimpleEntry(2, 3));
arr.add(new AbstractMap.SimpleEntry(20, 30));
arr.add(new AbstractMap.SimpleEntry(2, 4));

行を取得します:

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

印刷する必要があります。

2
3
20
30
2
4

グラフ構造の辺を定義するのに適しています。あなたの頭の中のニューロン間のもののように。

33
Eric Leschinski

Java 9から始まって、Map#entry(Object, Object) である不変エントリを作成することを可能にする新しいユーティリティメソッドがあります。

これは簡単な例です:

Entry<String, String> entry = Map.entry("foo", "bar");

不変なので、setValueを呼び出すとUnsupportedOperationExceptionがスローされます。他の制限は、それが直列化できず、キーまたは値としてのnullが禁じられているという事実です。それがあなたにとって受け入れられないなら、あなたは AbstractMap.SimpleImmutableEntry または を使う必要があるでしょう/] AbstractMap.SimpleEntry .

22
Nicolas Filotto

なぜMap.Entryですか?私はキーと値のペアのようなものがそのケースに適していると思います。

Java.util.AbstractMap.SimpleImmutableEntryまたはJava.util.AbstractMap.SimpleEntryを使用

13
tanghao

あなたは実際に行くことができます:Map.Entry<String, String> en= Maps.immutableEntry(key, value);

org.Apache.commons.lang3.Tuple.PairJava.util.Map.Entryを実装しており、スタンドアロンでも使用できます。

また他の人が述べたようにGuavaのcom.google.common.collect.Maps.immutableEntry(K, V)がトリックをする。

流暢なPair.of(L, R)構文のために私はPairを好みます。

6
parxier

私はいつも使っているジェネリックなPairクラスを定義しました。それは素晴らしい。おまけとして、静的ファクトリメソッド(Pair.create)を定義することで、型引数を半分にするだけで済みます。

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

Clojureを使用している場合は、別の選択肢があります。

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