我希望能够在Java中将一个数组转换为Set。有一些明显的方法可以做到这一点(即使用循环),但我想要更加简洁的方式,就像:
java.util.Arrays.asList(Object[] a);
任何想法?我希望能够在Java中将一个数组转换为Set。有一些明显的方法可以做到这一点(即使用循环),但我想要更加简洁的方式,就像:
java.util.Arrays.asList(Object[] a);
任何想法?Set<T> mySet = new HashSet<>(Arrays.asList(someArray));
Set<T> mySet = Set.of(someArray);
var mySet = Set.of(someArray);
小心
Set.of 抛出 IllegalArgumentException - 如果 someArray 中存在重复元素。 更多详情请参见:https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/util/Set.html#of(E...)
如果你想要一个不可修改的集合,并且数组中可能有重复元素,请按照以下步骤进行:
var mySet = Set.copyOf(Arrays.asList(array));
Set<T> mySet = new HashSet<T>();
Collections.addAll(mySet, myArray);
这是JDK 6中的Collections.addAll(java.util.Collection, T...)。
另外,如果我们的数组装满了基本数据类型呢?
对于JDK < 8,我会编写明显的for
循环,在一次操作中进行包装并添加到集合中。
对于JDK >= 8,可供选择的一个不错选项是:
Arrays.stream(intArray).boxed().collect(Collectors.toSet());
java.util.Collections.addAll
来完成这个操作。另外,我不建议再使用 Commons Collections,因为它没有泛型,并且现在已经有了 Guava。 - ColinDaddAll
的时间复杂度是 O(n)。 - Steve Powell使用Guava,您可以做到:
T[] array = ...
Set<T> set = Sets.newHashSet(array);
new HashSet<T>(Arrays.asList(someArray))
。请参见 https://google.github.io/guava/releases/19.0/api/docs/com/google/common/collect/Sets.html#newHashSet(E...)。 - Alexander KlimetschekJava 8:
String[] strArray = {"eins", "zwei", "drei", "vier"};
Set<String> strSet = Arrays.stream(strArray).collect(Collectors.toSet());
System.out.println(strSet);
// [eins, vier, zwei, drei]
可变参数也可以使用!
Stream.of(T... values).collect(Collectors.toSet());
我们还可以使用Stream
。我们可以通过多种方式获取流:
Set<String> set = Stream.of("A", "B", "C", "D").collect(Collectors.toCollection(HashSet::new));
System.out.println(set);
String[] stringArray = {"A", "B", "C", "D"};
Set<String> strSet1 = Arrays.stream(stringArray).collect(Collectors.toSet());
System.out.println(strSet1);
// if you need HashSet then use below option.
Set<String> strSet2 = Arrays.stream(stringArray).collect(Collectors.toCollection(HashSet::new));
System.out.println(strSet2);
Collectors.toSet()
方法源代码显示,元素逐个添加到一个HashSet
中,但规范不保证它将是一个HashSet
。
因此最好使用后一种选项。输出结果为:“返回的Set的类型、可变性、可序列化性或线程安全性都没有任何保证。”
[A, B, C, D] [A, B, C, D] [A, B, C, D]
Set.of
静态工厂方法,为提供的元素或数组返回不可变的Set。@SafeVarargs
static <E> Set<E> of(E... elements)
详情请参阅Immutable Set静态工厂方法。
我们还可以通过两种方式获取不可变的集合:
Set.copyOf(Arrays.asList(array))
Arrays.stream(array).collect(Collectors.toUnmodifiableList());
方法Collectors.toUnmodifiableList()
在内部使用了Java 9中引入的Set.of
。更多信息请参见我的回答。
Stream.of()
- 我不知道这个。关于Collectors.toSet()
的一个小问题:你说规范不能保证逐个添加元素,但这就是“将...累积到新的Set
中”的意思。而且它更易读 - 在我看来更可取,如果你不需要具体类型、可变性、可序列化性和线程安全性的保证。 - Andrew SpencerHashSet
。它只保证它将是一个 Set
,这就是我的意思。希望我已经澄清了。 - akhil_mittal在执行Arrays.asList(array)
之后,你可以执行Set set = new HashSet(list);
这里是一段示例代码,你可以编写:
public <T> Set<T> GetSetFromArray(T[] array) {
return new HashSet<T>(Arrays.asList(array));
}
已经有许多优秀的答案,但大多数都不适用于基本类型数组(如int[]
、long[]
、char[]
、byte[]
等)。
在Java 8及以上版本中,您可以使用以下方式对该数组进行装箱:
Integer[] boxedArr = Arrays.stream(arr).boxed().toArray(Integer[]::new);
然后使用流将其转换为集合:
Stream.of(boxedArr).collect(Collectors.toSet());
Set<Integer> set1 = Sets.mutable.of(1, 2, 3, 4, 5);
Set<Integer> set2 = Sets.mutable.of(new Integer[]{1, 2, 3, 4, 5});
MutableSet<Integer> mutableSet = Sets.mutable.of(1, 2, 3, 4, 5);
ImmutableSet<Integer> immutableSet = Sets.immutable.of(1, 2, 3, 4, 5);
Set<Integer> unmodifiableSet = Sets.mutable.of(1, 2, 3, 4, 5).asUnmodifiable();
Set<Integer> synchronizedSet = Sets.mutable.of(1, 2, 3, 4, 5).asSynchronized();
ImmutableSet<Integer> immutableSet = Sets.mutable.of(1, 2, 3, 4, 5).toImmutable();
注意:我是 Eclipse Collections 的提交者
/**
* Handy conversion to set
*/
public class SetUtil {
/**
* Convert some items to a set
* @param items items
* @param <T> works on any type
* @return a hash set of the input items
*/
public static <T> Set<T> asSet(T ... items) {
return Stream.of(items).collect(Collectors.toSet());
}
}
Arrays.asList
的时间复杂度为 O(1)。 - SLaks