Ser*_*erg 684 java collections constructor initialization hashset
我需要创建一个Set初始值.
Set<String> h = new HashSet<String>();
h.add("a");
h.add("b");
Run Code Online (Sandbox Code Playgroud)
有没有办法在一行代码中执行此操作?例如,它对最终的静态字段很有用.
Gen*_*diy 883
我使用的速记不是非常节省时间,但适用于单行:
Set<String> h = new HashSet<>(Arrays.asList("a", "b"));
Run Code Online (Sandbox Code Playgroud)
同样,这不是时间效率,因为您正在构建一个数组,转换为一个列表并使用该列表来创建一个集合.
初始化静态最终集时,我通常会这样写:
public static final String[] SET_VALUES = new String[] { "a", "b" };
public static final Set<String> MY_SET = new HashSet<>(Arrays.asList(SET_VALUES));
Run Code Online (Sandbox Code Playgroud)
稍微不那么丑陋和效率对静态初始化无关紧要.
Boz*_*zho 348
集合文字是为Java 7安排的,但没有进入.所以没有自动化.
你可以使用番石榴Sets:
Sets.newHashSet("a", "b", "c")
Run Code Online (Sandbox Code Playgroud)
或者您可以使用以下语法,这将创建一个匿名类,但它是hacky:
Set<String> h = new HashSet<String>() {{
add("a");
add("b");
}};
Run Code Online (Sandbox Code Playgroud)
Chr*_*oom 192
在Java 8中我会使用:
Set<String> set = Stream.of("a", "b").collect(Collectors.toSet());
Run Code Online (Sandbox Code Playgroud)
这为您提供了一个可变的Set预初始化"a"和"b".请注意,虽然在JDK 8中这确实返回a HashSet,但规范并不保证它,并且这可能在将来发生变化.如果您特别想要HashSet,请改为:
Set<String> set = Stream.of("a", "b")
.collect(Collectors.toCollection(HashSet::new));
Run Code Online (Sandbox Code Playgroud)
i_a*_*ero 149
Set<String> strSet1 = Stream.of("A", "B", "C", "D")
.collect(Collectors.toUnmodifiableSet());
Run Code Online (Sandbox Code Playgroud)
这里的收集器实际上将返回Java 9中引入的不可修改的集合,这从set -> (Set<T>)Set.of(set.toArray())源代码中的声明可以看出.
Set<String> strSet6 = Set.of("Apple", "Ball", "Cat", "Dog");
Run Code Online (Sandbox Code Playgroud)
我们有12个这种方便工厂方法的重载版本:
Collections.unmodifiableSet()
Collectors.toUnmodifiableSet()
static <E> Set<E> of()// ....等等
static <E> Set<E> of(E e1)
那么一个自然的问题就是为什么当我们有var-args时我们需要重载版本?答案是:每个var-arg方法在内部创建一个数组,并且具有重载版本将避免不必要的对象创建,并且还将使我们免于垃圾收集开销.
在Java 8中使用Stream.
Set<String> strSet1 = Stream.of("A", "B", "C", "D")
.collect(Collectors.toCollection(HashSet::new));
// stream from an array (String[] stringArray)
Set<String> strSet2 = Arrays.stream(stringArray)
.collect(Collectors.toCollection(HashSet::new));
// stream from a list (List<String> stringList)
Set<String> strSet3 = stringList.stream()
.collect(Collectors.toCollection(HashSet::new));
Run Code Online (Sandbox Code Playgroud)
使用Collections.unmodifiableSet - 我们可以使用static <E> Set<E> of(E e1, E e2)as:
Set<String> strSet4 = Collections.unmodifiableSet(strSet1);
Run Code Online (Sandbox Code Playgroud)
但它看起来有点尴尬,我们可以像这样写我们自己的收藏家:
class ImmutableCollector {
public static <T> Collector<T, Set<T>, Set<T>> toImmutableSet() {
return Collector.of(HashSet::new, Set::add, (l, r) -> {
l.addAll(r);
return l;
}, Collections::unmodifiablSet);
}
}
Run Code Online (Sandbox Code Playgroud)
然后将其用作:
Set<String> strSet4 = Stream.of("A", "B", "C", "D")
.collect(ImmutableCollector.toImmutableSet());
Run Code Online (Sandbox Code Playgroud)
使用Collectors.collectingAndThen - 另一种方法是使用static <E> Set<E> of(E... elems)允许我们执行其他完成转换的方法:
import static java.util.stream.Collectors.*;
Set<String> strSet5 = Stream.of("A", "B", "C", "D").collect(collectingAndThen(
toCollection(HashSet::new),Collections::unmodifiableSet));
Run Code Online (Sandbox Code Playgroud)
如果我们只关心Collections.unmodifiableSet()那么我们也可以Collectors.collectingAndThen()代替Set.
需要注意的一点是,该方法Collectors.toSet()根据doc返回指定集的不可修改视图.不可修改的视图集合是一个不可修改的集合,也是一个支持集合的视图.请注意,可能仍然可以对支持集合进行更改,如果它们发生,则通过不可修改的视图可以看到它们.但是该方法Collectors.toCollection(HashSet::new)在Java 10中返回真正的不可变集.
coo*_*ird 87
有几种方法:
双支撑初始化
这是一种创建匿名内部类的技术,该内部类具有实例初始化程序,String在创建实例时将其添加到自身:
Set<String> s = new HashSet<String>() {{
add("a");
add("b");
}}
Run Code Online (Sandbox Code Playgroud)
请记住,这实际上会在HashSet每次使用时创建一个新的子类,即使一个人不必显式编写新的子类.
一种实用方法
编写一个返回Set使用所需元素初始化的方法并不难写:
public static Set<String> newHashSet(String... strings) {
HashSet<String> set = new HashSet<String>();
for (String s : strings) {
set.add(s);
}
return set;
}
Run Code Online (Sandbox Code Playgroud)
上面的代码只允许使用a String,但是允许使用泛型的任何类型都不应该太难.
使用图书馆
许多库都有一种方便的方法来初始化集合对象.
例如,Google Collections有一个Sets.newHashSet(T...)方法,用于填充HashSet特定类型的元素.
Lu5*_*u55 40
如果你只有一个初始值,那就足够了:
Set<String> immutableSet = Collections.singleton("a");
Run Code Online (Sandbox Code Playgroud)
Mic*_*hev 29
最方便的方法之一是使用通用的Collections.addAll()方法,它采用集合和varargs:
Set<String> h = new HashSet<String>();
Collections.addAll(h, "a", "b");
Run Code Online (Sandbox Code Playgroud)
Jas*_*ols 27
你可以用Java 6做到这一点:
Set<String> h = new HashSet<String>(Arrays.asList("a", "b", "c"));
Run Code Online (Sandbox Code Playgroud)
但为什么?我没有发现它比显式添加元素更具可读性.
Mat*_*der 27
使用Java 9,您可以执行以下操作:
Set.of("a", "b");
Run Code Online (Sandbox Code Playgroud)
你会得到一个包含元素的不可变集合.有关详细信息,请参阅接口集的Oracle 文档.
Lan*_*ceP 24
我觉得最可读的是简单地使用谷歌番石榴:
Set<String> StringSet = Sets.newSet("a", "b", "c");
Run Code Online (Sandbox Code Playgroud)
Mar*_*iot 14
coobird的答案用于创建新HashSets 的效用函数的概括:
public static <T> Set<T> newHashSet(T... objs) {
Set<T> set = new HashSet<T>();
for (T o : objs) {
set.add(o);
}
return set;
}
Run Code Online (Sandbox Code Playgroud)
Her*_*eri 13
如果Set的包含类型是枚举,则有java构建的工厂方法(从1.5开始):
Set<MY_ENUM> MY_SET = EnumSet.of( MY_ENUM.value1, MY_ENUM.value2, ... );
Run Code Online (Sandbox Code Playgroud)
import com.google.common.collect.Sets;
Sets.newHashSet("a", "b");
Run Code Online (Sandbox Code Playgroud)
要么
import com.google.common.collect.ImmutableSet;
ImmutableSet.of("a", "b");
Run Code Online (Sandbox Code Playgroud)
使用Eclipse Collections,有几种不同的方法可以Set在一个语句中初始化包含字符"a"和"b"的字符串.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();
Run Code Online (Sandbox Code Playgroud)
Eclipse Collections与Java 5 - 8兼容.
注意:我是Eclipse Collections的提交者.
随着java9和便利工厂方法的发布,这可以以更简洁的方式实现:
Set set = Set.of("a", "b", "c");
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
749198 次 |
| 最近记录: |