Collections.singleton()返回Set而不是Collection的好处是什么?

fge*_*fge 16 java collections

Collections.singleton()方法Set使用该单个参数而不是a 返回a Collection.

为什么会这样?从我所看到的,除了Set作为一个子类型Collection,我看不出任何优势......这只是因为无论如何Set延伸Collection所以没有理由不这样做?

是的,也有Collections.singletonList(),但是这是另一回事,因为你可以从访问随机元素List.get()...

Bas*_*que 9

不可变

这个好处可以在JavaDoc文档中的第一个形容词中找到:不可变的.

有时您正在使用需要Set(或List等)的代码.在您自己的环境中,您可能只需要一个项目.要实现自己的目标,即在需要在集合中显示该项目时仅强制执行单项规则,请使用Set禁止添加多个项目的实现.

"不可变" Collections::singleton意味着,一旦创建,结果Set对象就保证只有一个项目.不是零,也不是一个.不能再添加了.无法删除这一项.

例如,假设您的代码正在使用Employee代表贵公司CEO(首席执行官)的对象.你的代码只是明确地与CEO打交道,所以你知道一次只能有一个这样的Employee对象,总是一个CEO.但是,您希望利用一些为指定的Employee对象集合创建报告的现有代码.通过使用,Collection.singleton您可以保证您自己的代码不会错误地拥有除一名员工之外的其他代码,同时仍然可以通过Set.

Set< Employee > ceo = Collections.singleton( new Employee( "Tim Cook" ) ) ;  // Always exactly one item in this context, only one CEO is possible.

ceo.add( … ) ;     // Fails, as the collection is immutable.
ceo.clear() ;      // Fails, as the collection is immutable.
ceo.remove( … ) ;  // Fails, as the collection is immutable.

someReport.processEmployees( ceo ) ;
Run Code Online (Sandbox Code Playgroud)

Java 9:Set.of&List.of

Java 9及更高版本提供了新的接口方法,Set.ofList.of提供了相同的效果,即单个元素的不可变集合.

Set< Pet > pet = Set.of( someDog ) ;
Run Code Online (Sandbox Code Playgroud)

但是兄弟of方法被重载以接受不可变集合中的任何数量的元素,而不仅仅是一个元素.

Set< Pet > pets = Set.of( someDog , someOtherDog , someCat ) ;
Run Code Online (Sandbox Code Playgroud)


Lou*_*man 8

我不确定本身有"好处"或"优势"吗?它只是返回单例的方法,Set当你想要一个单例时恰好是默认实现Collection,因为单例Collection恰好也是一个数学集.

  • 我并没有像集合的数学定义那样深刻,但是,这也是事实.实际上,好处似乎是因为在这种特殊情况下,`Collection`和`Set`基本相同,为什么不返回`Set`?毕竟,如果有所不同,我们可能会有`.singletonCollection()`和`.singletonSet()`... (5认同)

ord*_*lex 5

I wondered the same thing and came across your question in my research. Here is my conclusion:

Returning a Set keeps the Collections API clean.

Here are the methods for getting a singleton Collection:

  • public static <T> Set<T> singleton(T o)
  • public static <T> List<T> singletonList(T o)
  • public static <K,V> Map<K,V> singletonMap(K key, V value)

What if the API designers decided on having a singletonSet method and singleton method? It would look like this:

  • public static <T> Collection<T> singleton(T o)
  • public static <T> Set<T> singletonSet(T o)
  • public static <T> List<T> singletonList(T o)
  • public static <K,V> Map<K,V> singletonMap(K key, V value)

Is the singleton method really necessary? Let's think about why we would need some of these methods.

Think about when you would call singletonList? You probably have an API that requires List instead of Collection or Set. I will use this poor example:

public void needsList(List<?> list);
Run Code Online (Sandbox Code Playgroud)

You can only pass a List. needsList hopefully needs the data indexed and is not arbitrarily requesting a List instead of a Collection.

However, you could also pass a List to a method that required any Collection:

public void needsAnyCollection(Collection<?> collection);
Run Code Online (Sandbox Code Playgroud)

But if that is the case, then why use a List? A List has a more complicated API and involves storing indexes. Do you really need the indexes? Would a Set not suffice? I argue that you should use a Set, because needsAnyCollection does not care about the order.

This is where singletonSet really shines. You know that if the collection is of size 1 (singleton), then the data must be unique. Collections of size 1 are coincidentally a Set.

不需要返回一个单例类型的方法Collection,因为它偶然是一个Set