是否可以将collect(Collectors.ToList()的返回类型转换为LinkedList?

问题描述 投票:0回答:4

我想编写一个函数来创建随机数流:

import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

public class fillRandom {
    public static List<Integer> IntFill(){
        return  new Random().ints(10,0,100).boxed().collect(Collectors.toList());

    }
}

然后我想将其返回到我的 LinkedList:

public class Main {

    public static void main(String[] args) throws Exception {
        List linkedList = new LinkedList<Integer>();
        Print printer = new printImpl();
        linkedList = (LinkedList) fillRandom.IntFill();
        printer.print(linkedList);

    }

}

但是我收到错误

Exception in thread "main" java.lang.ClassCastException: class java.util.ArrayList cannot be cast to class java.util.LinkedList

是否可以在没有

collect(Collectors.toCollection(LinkedList::new))
的情况下做一些事情来使其工作?如果我不想从 Random

返回 ArrayList
java collections java-stream
4个回答
4
投票

根据

toList
的文档,对于返回的列表类型没有保证,并且特别要求你使用
toCollection

不保证返回的 List 的类型、可变性、可序列化性或线程安全性;如果需要对返回的列表进行更多控制,请使用

toCollection(Supplier)

如果您不使用

toCollection
的原因只是为了避免在
intFill
中使用特定的实现,并且希望允许调用者指定他们想要的
List
,您始终可以为用户提供带有
Supplier 的选项
参数,就像
toCollection
一样。

public static <C extends Collection<Integer>> C intFill(Supplier<C> collectionSupplier){
    return new Random().ints(10,0,100).boxed()
        .collect(Collectors.toCollection(collectionSupplier));
}

用途:

List<Integer> linkedList = fillRandom.intFill(LinkedList::new);

或者,不进行强制转换,而是使用

LinkedList
构造函数从
LinkedList
收集器返回的任何
List
创建
toList

List<Integer> linkedList = new LinkedList<>(fillRandom.intFill());

请注意,这样做的一个缺点是它会再次循环整个列表,这可能是不可取的。


0
投票

您应该坚持使用接口

List
而不是使用实现类
LinkedList

话虽如此,如果你真的想收集你已经拥有的对象的类,你可以通过首先让收集器知道你想要基于什么对象来执行类似的操作(但我不推荐这样做):

import java.util.List;
import java.util.Random;
import java.util.stream.Collectors;

public class fillRandom {
    public static List<Integer> IntFill(List base){
        return (List<Integer>) new Random().ints(10,0,100).boxed().collect(Collectors.toCollection(() -> {
            try {
                return base.getClass().newInstance();
            } catch (Exception ex) {
                // Default
                return new ArrayList<>();
            }
        }));
    }
}

然后这样称呼它:

public class Main {
    public static void main(String[] args) throws Exception {
        List linkedList = new LinkedList<Integer>();
        Print printer = new printImpl();
        linkedList = fillRandom.IntFill(linkedList);
        printer.print(linkedList);

    }
}

另请注意,当您进行收集时,您正在创建一个全新的列表,而不是填充已经创建的列表。然后,当您将其分配给变量时,您将替换旧变量。


0
投票

如果目标是允许

IntFill
是任何类型的
List
,但需要将其作为
LinkedList
处理,则可以将返回列表中的数据复制到
LinkedList
中。
LinkedList
复制构造函数”正是这样做的,创建一个新的
LinkedList
,它是给定
Collection
的副本。

public static void main(String[] args) throws Exception {
    List<Integer> linkedList = new LinkedList<>(fillRandom.IntFill());

    Print printer = new printImpl();
    printer.print(linkedList);
}

-4
投票
    List linkedList = new LinkedList<Integer>();
    List<Integer> list = (LinkedList)fillRandom.IntFill();
    linkedList = new LinkedList<>(list);
    System.out.println(linkedList);

此代码应该适合您

© www.soinside.com 2019 - 2024. All rights reserved.