Java 泛型和流

标签 java generics lambda java-stream

我正在构建一种避免代码重复的框架,在某个时候我需要将对象 Foo 列表转换为对象 Bar 列表。

我有扩展的数据库实体

public class BaseEntity {...}

以及扩展的展示对象

public class BaseDTO<T extends BaseEntity> {...}

所以

public class Foo extends BaseEntity {...}

public class Bar extends BaseDTO<A extends BaseEntity> {
    public Bar(Foo entity, Locale l) {
        ...
    }
}

现在使用流很容易将 Foo 列表转换为 Bar 列表

public abstract ClassThatUsesFooAndBar() {

    public List<Bar> convertFooToBar(List<Foo> list) {
        return list.stream().map(f -> new Bar(f, locale)).collect(...);
    }
}

但是,问题来了,这些 Foo 和 Bar 实际上是泛型(A 和 B),所以使用 Foo 和 Bar 的类实际上是 ClassThatUsesAandB<A extends BaseEntity, B extends BaseDTO> ,因此该函数也必须是抽象的,并作为具有正确 A 和 B 实现的样板代码实现,因为显然您无法实例化泛型类型。

有没有办法使用generics/streams/lambdas来创建一个可以写一次的函数,这样实现类就不需要重新实现它了?函数签名为

public List<B> convertAToB(List<A> list);

我希望我已经足够清楚我需要什么,如果您需要进一步的解释,请询问

谢谢!

最佳答案

我认为最简单的方法是使用 lambda 进行转换。

public static <A,B> List<B> convertList(List<A> list, Function<A,B> itemConverter) {
    return list.stream().map(f -> itemConverter.apply(f)).collect(...);
}

然后你可以像这样使用它:

List<Bar> l = convertList(fooList,foo -> new Bar(foo.getBaz()));

或者如果你愿意,你可以将它提取到它自己的命名类中:

public class Foo2BarConverter implements Function<Foo,Bar> {
    @Override
    public Bar apply(Foo f) {
       return new Bar(f.getBaz());
    }
}

顺便说一句,考虑到我们可以用流式处理做什么,创建一个新列表只是为了拥有 Bar 对象的物化列表似乎有点浪费。我可能会在转换后立即将我想对列表执行的任何操作链接起来。

关于Java 泛型和流,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/34228921/

相关文章:

C# 泛型实例化

.net - Linq从整数列表中选择多个ID(主键)

javascript - 使用 JavaScript 使用 lambda 和正则表达式查找数组中最常见的数字

java - 如何返回第一个和最后一个数字交换的数组?

java - 基于 3 个不同的整数创建一个唯一的整数

java - Websphere 8.5 和 SpringServletContainerInitializer

用于解码 JAXB 对象的 Java 泛型

generics - 苹果 swift : Generic type constraint for String type only not works

java - 嵌入到java中的网络浏览器

c++ - 通用 lambda : syntactic sugar or not?