将 List<Type> 转换为 List<OtherType> 的最快方法

Fastest way to convert a List<Type> to List<OtherType>

假设我们有以下代码

private List<String> convertScreenTypeToString(List<ScreenType> screenTypeList){
        List<String> result = new ArrayList<>();

        for(ScreenType screenType : screenTypeList){
            result.add(screenType.getLabel());
        }

        return result;
    }

但是,我们有不同的类型(ScreenType、HomeType、UserType),我不想重复相同的方法 3 次以上,我不能使用继承,因为它们是提供的模型。 (架构设计的东西)。

此外,

.... TypeToScreen(List<Object> whatever){}

这不是一个合适的解决方案。

此外:

private class Convert<T>{ .....TypeToScreen(List<T> whatecer){}}

在父级内部 class 没问题,但我正在寻找一些高级方法

Streams 可让您映射列表的元素。

List<String> labels =
    screenTypes.stream()
        .map(ScreenType::getLabel)
        .collect(Collectors.toList());

无法保证 List 是什么类型,因此您可能希望包含 new ArrayList<>() 或类似内容。

如果List上有这样的方法就好了。您可以为这种非常常见的情况编写一个方便的方法。

public static <T, R> List<R> map(
    List<T> source, Function<? super T,​ ? extends R> mapping
) {
    return
        screenTypes.stream()
            .map(mapping)
            .collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
}

此处 Stream.collect 的三参数形式消除了对中间 List 的需要。 @Ousmane D. 在评论中提供了替代的最后一行。

            .collect(Collectors.toCollection(ArrayList::new));

或者,您可以在没有流的情况下将其写出。如果这些事情中的任何一个对您来说很重要,那么它会更快、更容易阅读。

public static <T, R> List<R> map(
    List<T> source, Function<? super T,​ ? extends R> mapping
) {
    List<R> result = new ArrayList<>(source.size());
    for (T t : source) {
        result.add(mapping.apply(t));
    }
    return result;
}