我需要创建一个具有初始值的集合。
Set<String> h = new HashSet<String>();
h.add("a");
h.add("b");
是否有一种方法可以在一行代码中做到这一点?例如,它对于最终的静态字段很有用。
我需要创建一个具有初始值的集合。
Set<String> h = new HashSet<String>();
h.add("a");
h.add("b");
是否有一种方法可以在一行代码中做到这一点?例如,它对于最终的静态字段很有用。
当前回答
只是一个小提示,不管你最终使用了这里提到的哪种好方法,如果这是一个通常不被修改的默认设置(就像你正在创建的库中的默认设置),遵循以下模式是一个好主意:
// Initialize default values with the method you prefer, even in a static block
// It's a good idea to make sure these defaults aren't modifiable
private final static Set<String> DEFAULT_VALUES = Collections.unmodifiableSet(...);
private Set<String> values = DEFAULT_VALUES;
好处取决于您为该类创建的实例数量以及更改默认值的可能性。
如果您决定遵循这种模式,那么您还必须选择最易读的集初始化方法。由于不同方法之间的效率差异可能不会太大,因为您将只初始化一次集合。
其他回答
有一个我使用的简写,不是很省时,但适合单行:
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));
对于静态初始化来说,稍微不那么丑陋和效率并不重要。
(丑陋)双大括号初始化没有副作用:
Set<String> a = new HashSet<>(new HashSet<String>() {{
add("1");
add("2");
}})
但在某些情况下,如果我们提到这是一个使最终集合不可变的好味道,它可能真的很有用:
final Set<String> a = Collections.unmodifiableSet(new HashSet<String>(){{
add("1");
add("2");
}})
结合Michael Berdyshev的回答和泛型,并使用initialCapacity构造函数,与数组进行比较。asList变体:
import java.util.Collections;
import java.util.HashSet;
import java.util.Set;
@SafeVarargs
public static <T> Set<T> buildSetModif(final T... values) {
final Set<T> modifiableSet = new HashSet<T>(values.length);
Collections.addAll(modifiableSet, values);
return modifiableSet;
}
@SafeVarargs
public static <T> Set<T> buildSetModifTypeSafe(final T... values) {
return new HashSet<T>(Arrays.asList(values));
}
@SafeVarargs
public static <T> Set<T> buildeSetUnmodif(final T... values) {
return Collections.unmodifiableSet(buildSetModifTypeSafe(values));
// Or use Set.of("a", "b", "c") if you use Java 9
}
如果你为init传递一些值,这是很好的 使用其他方法 如果您不小心将类型与buildSetModif混合,则生成的T将 是什么?扩展对象,这可能不是你想要的,这不能发生在buildSetModifTypeSafe变体,这意味着buildSetModifTypeSafe(1,2, "a");不会编译
你可以在Java 6中做到:
Set<String> h = new HashSet<String>(Arrays.asList("a", "b", "c"));
但是为什么呢?我不认为它比显式地添加元素更具有可读性。
这是一个优雅的解决方案:
public static final <T> Set<T> makeSet(@SuppressWarnings("unchecked") T... o) {
return new HashSet<T>() {
private static final long serialVersionUID = -3634958843858172518L;
{
for (T x : o)
add(x);
}
};
}