我需要创建一个具有初始值的集合。

Set<String> h = new HashSet<String>();
h.add("a");
h.add("b");

是否有一种方法可以在一行代码中做到这一点?例如,它对于最终的静态字段很有用。


当前回答

可以使用静态块进行初始化:

private static Set<Integer> codes1=
        new HashSet<Integer>(Arrays.asList(1, 2, 3, 4));

private static Set<Integer> codes2 =
        new HashSet<Integer>(Arrays.asList(5, 6, 7, 8));

private static Set<Integer> h = new HashSet<Integer>();

static{
    h.add(codes1);
    h.add(codes2);
}

其他回答

有一个我使用的简写,不是很省时,但适合单行:

Set<String> h = new HashSet<>(Arrays.asList("a", "b"));

同样,这并不省时,因为您正在构造一个数组,转换为一个列表,并使用该列表创建一个集合。

当初始化静态最终集时,我通常这样写:

public static final String[] SET_VALUES = new String[] { "a", "b" };
public static final Set<String> MY_SET = new HashSet<>(Arrays.asList(SET_VALUES));

对于静态初始化来说,稍微不那么丑陋和效率并不重要。

有几种方法:

双大括号初始化

这是一种创建匿名内部类的技术,它有一个实例初始化器,在创建实例时将string添加到自身:

Set<String> s = new HashSet<String>() {{
    add("a");
    add("b");
}}

请记住,这实际上会在每次使用HashSet时创建一个新的子类,尽管不必显式地编写一个新的子类。

一种实用方法

编写一个返回Set的方法并不是太难写:

public static Set<String> newHashSet(String... strings) {
    HashSet<String> set = new HashSet<String>();

    for (String s : strings) {
        set.add(s);
    }
    return set;
}

上面的代码只允许使用String类型,但是允许使用任何使用泛型的类型应该不会太难。

利用图书馆

许多库都有一个方便的方法来初始化集合对象。

例如,谷歌Collections有一个Sets.newHashSet(T…)方法,该方法将用特定类型的元素填充HashSet。

import com.google.common.collect.Sets;
Sets.newHashSet("a", "b");

or

import com.google.common.collect.ImmutableSet;
ImmutableSet.of("a", "b");

如果Set的包含类型是枚举类型,则存在java构建的工厂方法(从1.5开始):

Set<MY_ENUM> MY_SET = EnumSet.of( MY_ENUM.value1, MY_ENUM.value2, ... );

使用Java 9,你可以做到以下几点:

Set.of("a", "b");

你会得到一个包含元素的不可变集合。具体操作请参见接口Set的Oracle文档。