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

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

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


当前回答

你可以在Java 6中做到:

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

但是为什么呢?我不认为它比显式地添加元素更具有可读性。

其他回答

结合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 7中使用,但最终没有加入。所以还没有自动的东西。

你可以使用番石榴的套装:

Sets.newHashSet("a", "b", "c")

或者你可以使用下面的语法,这将创建一个匿名类,但它是hack:

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

创建新哈希集时,coobird的answer效用函数的概括:

public static <T> Set<T> newHashSet(T... objs) {
    Set<T> set = new HashSet<T>();
    for (T o : objs) {
        set.add(o);
    }
    return set;
}

只是一个小提示,不管你最终使用了这里提到的哪种好方法,如果这是一个通常不被修改的默认设置(就像你正在创建的库中的默认设置),遵循以下模式是一个好主意:

// 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;

好处取决于您为该类创建的实例数量以及更改默认值的可能性。

如果您决定遵循这种模式,那么您还必须选择最易读的集初始化方法。由于不同方法之间的效率差异可能不会太大,因为您将只初始化一次集合。

在Eclipse Collections中,有几种不同的方法来初始化一个包含字符'a'和'b'的Set语句。Eclipse Collections同时为对象类型和基本类型提供了容器,因此我演示了如何使用Set<String>或CharSet,以及可变、不可变、同步和不可修改的这两个版本。

Set<String> set =
    Sets.mutable.with("a", "b");
HashSet<String> hashSet =
    Sets.mutable.with("a", "b").asLazy().into(new HashSet<String>());
Set<String> synchronizedSet =
    Sets.mutable.with("a", "b").asSynchronized();
Set<String> unmodifiableSet =
    Sets.mutable.with("a", "b").asUnmodifiable();

MutableSet<String> mutableSet =
    Sets.mutable.with("a", "b");
MutableSet<String> synchronizedMutableSet =
    Sets.mutable.with("a", "b").asSynchronized();
MutableSet<String> unmodifiableMutableSet =
    Sets.mutable.with("a", "b").asUnmodifiable();

ImmutableSet<String> immutableSet =
    Sets.immutable.with("a", "b");
ImmutableSet<String> immutableSet2 =
    Sets.mutable.with("a", "b").toImmutable();

CharSet charSet =
    CharSets.mutable.with('a', 'b');
CharSet synchronizedCharSet =
    CharSets.mutable.with('a', 'b').asSynchronized();
CharSet unmodifiableCharSet =
    CharSets.mutable.with('a', 'b').asUnmodifiable();
MutableCharSet mutableCharSet =
    CharSets.mutable.with('a', 'b');
ImmutableCharSet immutableCharSet =
    CharSets.immutable.with('a', 'b');
ImmutableCharSet immutableCharSet2 =
    CharSets.mutable.with('a', 'b').toImmutable();

注意:我是Eclipse Collections的提交者。