Java-新しいエントリ(キー、値)を作成する方法


291

私は同様に新しいアイテムを作成したいのですがUtil.Map.Entryそれは構造が含まれていますがkeyvalue

問題は、それがMap.Entryインターフェースであるため、インスタンス化できないことです。

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

回答:


79

あなたは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());

117
もちろん-すぐに使える解決策はないのかと思いました。私は自分のコードをできるだけ標準にしようとしています...
スパイダーマン

1
Mapの一部の実装に最終的なキー(HashMap、ConcurrentHashMapなど)があるが、TreeMap、WeakHashMapなどの他の実装ではない理由を説明していただけませんか?
AKS

7
指定されたコードは、Map.Entryインターフェースで必要なequalsとhashCodeもオーバーライドしないため、完全に正しくありません
John Tang Boyland

Java 7 Update 80の時点で、私は上記を実装し、機能しました(pastebin)。他のメソッドはオーバーライドされませんでした。
シルバー

807

ありpublic static class AbstractMap.SimpleEntry<K,V>ます。Abstract名前の一部に誤解を与えないでください。実際にはクラスではありませんabstract(ただし、トップレベルAbstractMapはクラスです)。

それがstaticネストされたクラスであるという事実は、それをインスタンス化するための囲みインスタンスを必要としないことを意味する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.SimpleEntryis @since 1.6なので、5.0にこだわっている場合は使用できません。

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

インターフェースMap.Entry

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

残念ながら、1.5バージョンには、使用できる既知の実装クラスがリストされていないため、独自のクラスの実装に悩まされている可能性があります。


上記の行はコンパイルエラーを返します(私はJava 5、BTWを使用しています)-エラーメッセージは次のとおりです:「タイプAbstractMap.SimpleEntryは表示されません」
Spiderman

6
これAbstractMap.SimpleEntryは、ドキュメントで確認できるように、Java 6までは公開されていなかったためです。
Jesper

さて、短い議論を要約すると、Java 5にはすぐに使える解決策はありません。独自の実装を使用する必要があります。
スパイダーマン

4
指摘するための+1 AbstractMap.SimpleEntry。あなたは毎日何か新しいことを学ぶと思います!
Priidu Neemre 2013年

「囲んでいるAbstractMapインスタンス」で囲んでどういう意味ですか。囲い込みは技術用語などをJavaで推論していますか?案内してください。
Cグラフィックス

70

始まったJava 9、ある不変のエントリを作成することを可能にする新しいユーティリティの方法がありますMap#entry(Object, Object)

以下に簡単な例を示します。

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

不変なので、呼び出しsetValueはをスローしUnsupportedOperationExceptionます。その他の制限は、シリアライズnull可能ではなく、キーまたは値が禁止されているため、受け入れられない場合は、AbstractMap.SimpleImmutableEntryまたはを使用する必要があるという事実ですAbstractMap.SimpleEntry

注意:Map 0から最大10(キー、値)のペアで直接aを作成する必要がある場合は、代わりにtypeのメソッドを使用できますMap.of(K key1, V value1, ...)


53

GuavaのMaps.immutableEntryをお試しください

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


34

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

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


18

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


便利です。github.com/google/guava Guavaは、GoogleのコアJavaライブラリのセットで、新しいコレクションタイプ(マルチマップやマルチセットなど)、不変コレクション、グラフライブラリ、および同時実行、I / O、ハッシュ、キャッシング用のユーティリティが含まれています。プリミティブ、文字列など!Google内のほとんどのJavaプロジェクトで広く使用されており、他の多くの企業でも広く使用されています。
Languoguang

13

なんでMap.Entry?Key-Valueペアのようなものがこのケースに適していると思います。

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


6

org.apache.commons.lang3.tuple.Pairを実装しjava.util.Map.Entry、スタンドアロンで使用することもできます。

また、他の人が述べたように、グアバのcom.google.common.collect.Maps.immutableEntry(K, V)ものはトリックを行います。

Pair流暢なPair.of(L, R)構文が好きです。


2
ImmutablePair代わりに提案してもいいですか?
beluchin

私は本当にorg.apache.commons.lang3.tuple.Pairクラスが好きです、それは素晴らしいです!
Laurens Op 't Zandt 2017

それについて私が気に入らない唯一のことは、それが左、右、キー、値にシリアル化されることです。ここで、左=キーと右=値です。シリアル化された文字列の2つの余分な役に立たない(多分)値。
Vikrant Goel 2017年

4

私はいつも使用する一般的な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);
    }

}

1
他のコメントをすべて読む前に、これを投稿しました。標準ライブラリに含まれているものが必要なようです...
Nels Beckman

2
Google Guavaは、Pair実装が悪いことである理由を明確にしています。出典
IngoBürk2014

3

Clojureを使用している場合は、別のオプションがあります。

(defn map-entry
  [k v]
  (clojure.lang.MapEntry/create k v))
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.