10
/**
 * Returns the empty map (immutable).  This map is serializable.
 *
 * <p>This example illustrates the type-safe way to obtain an empty set:
 * <pre>
 *     Map&lt;String, Date&gt; s = Collections.emptyMap();
 * </pre>
 * Implementation note:  Implementations of this method need not
 * create a separate <tt>Map</tt> object for each call.   Using this
 * method is likely to have comparable cost to using the like-named
 * field.  (Unlike this method, the field does not provide type safety.)
 *
 * @see #EMPTY_MAP
 * @since 1.5
 */
@SuppressWarnings("unchecked")
public static final <K,V> Map<K,V> emptyMap() {
    return (Map<K,V>) EMPTY_MAP;
}

上記の関数は、不変の空のマップを返します。

public static final Map EMPTY_MAP = new EmptyMap<>();

EmptyMap クラスは次のとおりです

/**
 * @serial include
 */
private static class EmptyMap<K,V>
    extends AbstractMap<K,V>
    implements Serializable
{
    private static final long serialVersionUID = 6428348081105594320L;

    public int size()                          {return 0;}
    public boolean isEmpty()                   {return true;}
    public boolean containsKey(Object key)     {return false;}
    public boolean containsValue(Object value) {return false;}
    public V get(Object key)                   {return null;}
    public Set<K> keySet()                     {return emptySet();}
    public Collection<V> values()              {return emptySet();}
    public Set<Map.Entry<K,V>> entrySet()      {return emptySet();}

    public boolean equals(Object o) {
        return (o instanceof Map) && ((Map<?,?>)o).isEmpty();
    }

    public int hashCode()                      {return 0;}

    // Preserves singleton property
    private Object readResolve() {
        return EMPTY_MAP;
    }
}

そのようなクラスとユーティリティメソッドの使用は何ですか? 私は試した

Map myMap = Collections.emptyMap();
myMap.put("Name","John");

コレクションが不変であるためException in thread "main" java.lang.UnsupportedOperationException 、変更がサポートされていないためです。では、そのようなデータ構造の用途は何ですか?

4

5 に答える 5

15

What is the use of such Class and utility method?

If you're returning a Map result, it's often useful for it to be immutable... for example, you can create an immutable map which wraps your own "real" data rather than having to either create a full copy, or trust the caller not to mutate it.

Also, if you're returning a Map result which is empty, it's convenient not to have to create a new object each time - every empty map is equivalent to every other empty map, so it's fine to use a single instance.

于 2013-08-02T08:47:45.927 に答える
7

これは、null オブジェクトの設計パターンhttp://en.wikipedia.org/wiki/Null_Object_patternを実装するのに役立ちます。これは、null の代わりに空のマップを返します。

于 2013-08-02T08:56:14.933 に答える
4

Collections.EMPTY_MAPあなたの場合、不変の最良の説明は次のとおりだと思います。

  1. このフィールドは public として宣言されています (アクセスを容易にするため)。最終版にしない場合は、いつでも来て、次のような小さなコードを作成できることを意味します。

    //somewhere in your program (or someone else's)
    Collections.EMPTY_MAP = new EmptyMap<"String","String">("unwantedKey","unwantedValue");
    
    //what do you actually want to do
    Map myMap = Collections.emptyMap();
    //you would expect an empty map, but you will get something else
    

    プログラムの動作が間違っていることがおそらくわかるので、これはあなたにとって非常に悪いことです。

  2. 有効な Java 第 2 版の項目 43 (null ではなく、空の配列またはコレクションを返す)を読んだ場合は、空のコレクションを返すことをお勧めします。そのため、開発時に null 配列操作コードを含める必要はありません。これをNull-Object-Patternと呼ぶこともできます。

    では、不変の EMPTY_COLLECTION (またはあなたの場合は MAP) とは何の関係があるのでしょうか? クラスで多くのメソッドを使用し、コレクションから要素のグループを作成するメソッドを呼び出し、グループのコレクションを返すことを想像してください。

    ここまでは順調ですね。EMPTY_MAPfromを使用することにしたとしましょうCollections(ある場合は、なぜでしょうか?)。いくつかの場所で空のマップを返しますが、そのうちのいくつかではそれを変更したいと考えています。この参照を使用するすべてのコードに対して、参照 EMPTY_MAP を変更します (これにより、番号 1 に戻ります。EMPTY_MAP の変更を覚えていますか?)。

  3. この理由は、メモリの削減などのためです。それが不変ではなく、空のマップが必要になるたびに新しいインスタンスを作成すると、(重大と言えるかもしれませんが) メモリ (リークではなく) パフォーマンス (用語はよくわかりませんが、あなたはアイデアを得る)。singletonについて聞いたことがあるかもしれませんが、これは同じことです。

ほらね。これは、不変の EMPTY_MAP が必要な主な 3 つの理由 (現時点で考えられる) です。

問題の解決策として、EMPTY_MAP を使用しないでください。自分で作成する必要があります。それほど難しいことではなく、これらの厄介な (恐ろしい) 不変のものを取り除くことができます。

幸運を!

于 2013-08-02T09:38:41.813 に答える
1

このスタックオーバーフローの質問が役立つかもしれません:不変の空のセットの使用( Collections.emptyMap() vs new HashMap() )

于 2013-08-02T08:52:41.777 に答える
1

毎回新しいオブジェクトをインスタンス化する必要なく、空のコレクションを返すために (emptyList および emptySet と共に) 使用されます。

于 2013-08-02T09:06:47.103 に答える