如何在Java中初始化一个静态Map ?

方法一:静态初始化器 方法二:实例初始化器(匿名子类) 或 还有别的方法吗?

它们各自的优点和缺点是什么?

下面是一个例子来说明这两种方法:

import java.util.HashMap;
import java.util.Map;

public class Test {
    private static final Map<Integer, String> myMap = new HashMap<>();
    static {
        myMap.put(1, "one");
        myMap.put(2, "two");
    }

    private static final Map<Integer, String> myMap2 = new HashMap<>(){
        {
            put(1, "one");
            put(2, "two");
        }
    };
}

当前回答

也许它是有趣的检查谷歌集合,例如,他们在他们的网页上的视频。它们提供了各种初始化映射和集合的方法,也提供了不可变的集合。

更新:这个库现在被命名为Guava。

其他回答

第二个方法的一个优点是,你可以用Collections.unmodifiableMap()来包装它,以确保以后不会更新集合:

private static final Map<Integer, String> CONSTANT_MAP = 
    Collections.unmodifiableMap(new HashMap<Integer, String>() {{ 
        put(1, "one");
        put(2, "two");
    }});

 // later on...

 CONSTANT_MAP.put(3, "three"); // going to throw an exception!

也许它是有趣的检查谷歌集合,例如,他们在他们的网页上的视频。它们提供了各种初始化映射和集合的方法,也提供了不可变的集合。

更新:这个库现在被命名为Guava。

地图。Java 9+中的

private static final Map<Integer, String> MY_MAP = Map.of(1, "one", 2, "two");

详见JEP 269。JDK 9在2017年9月全面上市。

现在Java 8已经发布了,这个问题值得重新审视。我尝试了一下——看起来也许你可以利用lambda表达式语法来获得一个非常漂亮和简洁(但类型安全)的映射文字语法,看起来像这样:

Map<String,Object> myMap = hashMap(
    bob -> 5,
    TheGimp -> 8,
    incredibleKoolAid -> "James Taylor",
    heyArnold -> new Date()
);

Map<String,Integer> typesafeMap = treeMap(
    a -> 5,
    bee -> 8,
    sea -> 13
    deep -> 21
);

未经测试的示例代码在https://gist.github.com/galdosd/10823529 会对其他人对此的看法感到好奇(这有点邪恶…)

注意:这个答案实际上属于问题如何直接初始化一个HashMap(在字面上)?但由于在写这篇文章时,它被标记为这篇文章的副本……


在Java 9的Map.of()之前(它也被限制为10个映射),你可以扩展你选择的Map实现,例如:

public class InitHashMap<K, V> extends HashMap<K, V>

重新实现HashMap的构造函数:

public InitHashMap() {
    super();
}

public InitHashMap( int initialCapacity, float loadFactor ) {
    super( initialCapacity, loadFactor );
}

public InitHashMap( int initialCapacity ) {
    super( initialCapacity );
}

public InitHashMap( Map<? extends K, ? extends V> map ) {
    super( map );
}

并添加一个额外的构造函数,它受到Aerthel的答案的启发,但通过使用Object…和<K, V>类型:

public InitHashMap( final Object... keyValuePairs ) {

    if ( keyValuePairs.length % 2 != 0 )
        throw new IllegalArgumentException( "Uneven number of arguments." );

    K key = null;
    int i = -1;

    for ( final Object keyOrValue : keyValuePairs )
        switch ( ++i % 2 ) {
            case 0:  // key
                if ( keyOrValue == null )
                    throw new IllegalArgumentException( "Key[" + (i >>> 1) + "] is <null>." );
                key = (K) keyOrValue;
                continue;
            case 1:  // value
                put( key, (V) keyOrValue );
        }
}

Run

public static void main( final String[] args ) {

    final Map<Integer, String> map = new InitHashMap<>( 1, "First", 2, "Second", 3, "Third" );
    System.out.println( map );
}

输出

{1=First, 2=Second, 3=Third}

你也可以扩展Map接口:

public interface InitMap<K, V> extends Map<K, V> {

    static <K, V> Map<K, V> of( final Object... keyValuePairs ) {

        if ( keyValuePairs.length % 2 != 0 )
            throw new IllegalArgumentException( "Uneven number of arguments." );

        final Map<K, V> map = new HashMap<>( keyValuePairs.length >>> 1, .75f );
        K key = null;
        int i = -1;

        for ( final Object keyOrValue : keyValuePairs )
            switch ( ++i % 2 ) {
                case 0: // key
                    if ( keyOrValue == null )
                        throw new IllegalArgumentException( "Key[" + (i >>> 1) + "] is <null>." );
                    key = (K) keyOrValue;
                    continue;
                case 1: // value
                    map.put( key, (V) keyOrValue );
            }
        return map;
    }
}

Run

public static void main( final String[] args ) {

    System.out.println( InitMap.of( 1, "First", 2, "Second", 3, "Third" ) );
}

输出

{1=First, 2=Second, 3=Third}