如果元素重复,为什么 Set.of() 会抛出 IllegalArgumentException?

2022-01-17 00:00:00 set collections java java-9

在 Java 9 中,在 Set 接口上引入了新的静态工厂方法,称为 of(),它接受多个元素,甚至是一个元素数组.

In Java 9 new static factory methods were introduced on the Set interface, called of(), which accept multiple elements, or even an array of elements.

我想将一个列表变成一个集合以删除集合中的任何重复条目,这可以使用以下方法完成(在 Java 9 之前):

I wanted to turn a list into a set to remove any duplicate entries in the set, which can be done (prior to Java 9) using:

Set<String> set = new HashSet<>();
set.addAll(list);

但我认为使用这种新的 Java 9 静态工厂方法会很酷:

But I thought it would be cool to use this new Java 9 static factory method doing:

Set.of(list.toArray())

其中 list 是一个字符串列表,之前已定义.

where the list is a List of Strings, previously defined.

但是,当元素重复时,java 抛出了 IllegalArgumentException,在方法的 Javadoc 中也有说明.这是为什么呢?

But alas, java threw an IllegalArgumentException when the elements were duplicates, also stated in the Javadoc of the method. Why is this?

编辑:这个问题与另一个关于概念上等价主题 Map.of() 方法的问题不同,但明显不同.并非所有静态工厂 of() 方法的行为都相同.换句话说,当我询问有关 Set.of() 方法的问题时,我不会点击处理 Map.of() 方法的问题.

Edit: this question is not a duplicate of another question about a conceptually equivalent topic, the Map.of() method, but distinctly different. Not all static factory of() methods behave the same. In other words, when I am asking something about the Set.of() method I would not click on a question dealing with the Map.of() method.

推荐答案

Set.of() 工厂方法为 given<生成不可变的 Set/strong> 元素数量.

The Set.of() factory methods produce immutable Sets for a given number of elements.

在支持固定数量参数的变体中(static <E>Set<E>of()static <E>Set<E>of(E e1)static <E>Set<E> of(E e1,E e2) 等...) 不重复的要求比较容易理解——当您调用 Set.of(a,b,c) 方法时,您表示您希望创建一个 exactly 3 的不可变 Set元素,因此如果参数包含重复项,则拒绝您的输入而不是生成较小的 Set 是有意义的.

In the variants that support a fixed number of arguments (static <E> Set<E> of​(), static <E> Set<E> of​(E e1), static <E> Set<E> of​(E e1,E e2), etc...) the requirement of not having duplicates are easier to understand - when you call the method Set.of(a,b,c), you are stating you wish to create an immutable Set of exactly 3 elements, so if the arguments contain duplicates, it makes sense to reject your input instead of producing a smaller Set.

Set;of(E... elements) 变体是不同的(如果允许创建任意数量元素的 Set),它遵循与其他变体相同的逻辑.如果您将 n 元素传递给该方法,则表示您希望创建一个 exactly n 的不可变 Set元素,所以不允许重复.

While the Set<E> of​(E... elements) variant is different (if allows creating a Set of an arbitrary number of elements), it follows the same logic of the other variants. If you pass n elements to that method, you are stating you wish to create an immutable Set of exactly n elements, so duplicates are not allowed.

您仍然可以使用以下方法从 List(可能存在重复)中创建 Set:

You can still create a Set from a List (having potential duplicates) in a one-liner using:

Set<String> set = new HashSet<>(list);

在 Java 9 之前就已经可用了.

which was already available before Java 9.

相关文章