Java 9中的Convenience Factory Method返回的特定集合类型

时间:2017-08-21 07:40:31

标签: java collections factory literals java-9

在Java 9中,我们有方便工厂方法来创建和实例化不可变的List,Set和Map。

但是,目前还不清楚返回对象的具体类型。

例如:

List list = List.of("item1", "item2", "item3");

在这种情况下,实际返回了哪种类型的列表?它是ArrayList还是LinkedList或其他类型的List?

API文档刚提到这一行,没有明确提到它的LinkedList:

  

列表中元素的顺序与顺序相同   提供参数,或提供的数组中的元素。

5 个答案:

答案 0 :(得分:9)

  

但是,目前还不清楚返回对象的具体类型。

这是所有你需要知道的!重点是:这些方法确实在目的上返回了一些List<Whatever>。你得到的东西是保证来履行List接口所表示的公共合同。它是给出该方法的东西的列表,其顺序与写下来的顺序相同。

你绝对应该避免编写任何代码,这些代码需要知道 more 这些方法返回的列表!这是一个实现细节,它应该对调用这些方法的客户端代码很重要!

从这个意义上说:您的关注点应该更多地放在客户端 - 例如,避免使用您在示例中使用的原始类型(使用List而不使用特定的泛型类型)。

答案 1 :(得分:7)

List.of返回的类是一个包私有静态类,因此不属于公共API:

package java.util;
...

class ImmutableCollections {
    ...

    static final class List0<E> extends AbstractImmutableList<E> {
        ...
    }

    static final class List1<E> extends AbstractImmutableList<E> {
        ...
    }

    static final class List2<E> extends AbstractImmutableList<E> {
        ...
    }

    static final class ListN<E> extends AbstractImmutableList<E> {
        ...
    }
}

所以这不是ArrayList(也不是LinkedList)。您需要知道的唯一事情是不可变并且满足List接口合同。

答案 2 :(得分:4)

实际上,同样的想法是Collectors.toList例如 - 你得到一个List,文档特别说:There are no guarantees on the type, mutability, serializability, or thread-safety of the List returned目前返回了ArrayList,但显然这可以随时更改。

我想知道是否应该在这里做同样的事情 - 明确提到类型是List而已。这为将来的实施提供了很多理由,以决定最适合的类型 - 速度,空间等。

答案 3 :(得分:3)

List.of会返回List这样的特殊类型Collections.UnmodifiableList。它既不是ArrayList也不是LinkedList。当您尝试修改它时会抛出异常。

答案 4 :(得分:3)

虽然@ZhekaKozlov和@GhostCat似乎已经回答了问题,但是返回类型(ImmutableCollections.List)以及它是如何创建的包都是私有的,而不是公共API。还要说明这些工厂方法的实现保证了履行List接口所表示的公共合同。

进一步提供ImmutableCollections实施的要点,然后设置,映射和列表中的一步。我会为List添加一个示例表示,这与MapSet非常相似。

ImmutableCollections目前在接口List上使用以下方法实现这些工厂方法:

abstract static class AbstractImmutableList<E>

扩展了AbstractList类,并为覆盖其实现的所有可能操作抛出UnsupportedOperationException。意味着不再允许对集合进行操作,使它们等同于Java Immutable Collections

此外,这是通过类

扩展的
static final class ListN<E> extends AbstractImmutableList<E>

使用构造函数来评估输入的某些检查及其元素为 NonNull 以返回由E[] elements组成的对象(类型为元素的数组) E)并根据这些元素覆盖某些实现为.get(int idx).contains(Object o)

Map and Set的方式类似,只是在那里确保了元素顶部的验证或一对键和值的验证。这样你就无法创建它们(分别抛出IllegalArgumentException和NullPointer异常):

Set<String> set2 = Set.of("a", "b", "a");
Map<String,String> map = Map.of("key1","value1","key1","value1");

Set<String> set2 = Set.of("a", null);
Map<String,String> map = Map.of("key1",null);