【问题标题】:How is selected the type of list returned by Collectors.toList()? [duplicate]Collectors.toList()返回的列表类型如何选择? [复制]
【发布时间】:2019-12-13 03:26:44
【问题描述】:

Collectors.toList() 的文档说不能保证返回的类型。

在一个简单的测试中:

Stream<String> s = Stream.of("Geeks", 
                                 "for", 
                                 "GeeksforGeeks", 
                                 "Geeks Classes"); 

List<String> myList = s.collect(Collectors.toList()); 

myList 的类型是 ArrayList。

如何选择这种类型?什么条件可以改变返回的类型?

【问题讨论】:

    标签: java collections


    【解决方案1】:

    这是关于未来更改的 API 规定。
    事实上,ArrayList 被返回:

    public static <T>
    Collector<T, ?, List<T>> toList() {
        return new CollectorImpl<>((Supplier<List<T>>) ArrayList::new, List::add,
                                   (left, right) -> { left.addAll(right); return left; },
                                   CH_ID);
    }
    

    但规范告诉我们,toList() 方法并非设计/用于返回特定的List 实现。
    今天,实现显示返回了ArrayList,但明天,新的 Java 版本可能会返回另一个实现(为什么不是不可变的 List)。
    因此,该方法的客户不应考虑(至少在理论上)将始终返回 ArrayList

    附带说明,Collectors.toCollection(Supplier) 允许客户提供用于收集的集合。
    虽然很少使用,但您可以使用它来保证使用 ArrayList

    List<String> list = l.stream().collect(Collectors.toCollection(ArrayList::new));
    

    【讨论】:

    • 实际上,the specification 明确告诉我们“返回的List 的类型、可变性、可序列化性或线程安全性无法保证。”规范明确指出不能假定特定的实现。
    • @VGR 你是对的。我重新制定了。
    【解决方案2】:

    使用Collectors#toCollection(Supplier);你可以预先确定你想要的类型。

    例如

    Stream.of("a","b","c").collect(Collectors.toCollection(ArrayList::new));
    

    将返回一个新的 ArrayList。

    或者对于链表

    Stream.of("a","b","c").collect(Collectors.toCollection(LinkedList::new));
    

    这两个示例都使用数据类型的零参数构造函数。

    并且Collectors#toList() 不保证任何特定类型。因此理论上返回的类型可能因java版本而异。

    【讨论】:

    • 如果您不使用“LinkedList::new”,语法会是什么样子,是类似于“LinkedList.new()”还是什么?
    • Java 8 添加到 lamdba 表达式和方法引用中。 LinkedList::new 是对 LinkedList 构造函数的方法引用。作为您的示例,您将尝试引用静态方法,这是允许的,但您不能使用关键字命名方法,“new”就是其中之一。否则,方法引用的语法与“[Class]::[methodName]”相同。或者,如果它是本地非统计参考 this::[methodName] 将起作用。
    猜你喜欢
    • 2018-01-24
    • 1970-01-01
    • 1970-01-01
    • 2017-04-16
    • 2011-02-11
    • 1970-01-01
    • 2018-02-21
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多