【发布时间】:2020-06-05 03:12:51
【问题描述】:
我有一个 Foo 列表,在每个 Foo 上我应用一个处理器方法来获取 ValidItem。
如果处理有错误,则返回ErrorItem。
现在如何通过 Java 8 流处理这个以获取 2 个不同列表形式的结果
List<Foo> FooList = someList....;
class ValidItem extend Item{......}
class ErrorItem extend Item{......}
Item processItem(Foo foo){
return either an object of ValidItem or ErrorItem;
}
我相信我能做到
Map<Class,List<Item>> itemsMap =
FooList
.stream()
.map(processItem)
.collect(Collectors.groupingBy(Object::getClass));
但由于List<Parent> 不是List<Child>,所以我无法将地图结果转换为List<ValidItem>
实际上ErrorItem 和ValidItem 是两个完全不同的类,根本不相关,只是为了这个蒸汽处理和 processItem 方法,我通过扩展标记 Item 类将它们保持在相同的层次结构中。
在代码中的许多其他地方,我不能/不应该将 ValidItem 称为 Item ,因为它给出了它也可以是 ErroItem 的想法。
是否有正确的方法来处理流,最后我得到 2 个列表。和 ErrorItem 和 ValidItem 没有扩展同一个 Item 类?
############## 更新#############
正如我所说的 ValidItem 和 ErrorItem 不应该相同,所以我更改了 process 方法的签名并将其传递给一个列表。
我知道这不是 Stream 的使用方式。如果您有更好的方法,请告诉我
List<Foo> FooList = someList....;
class ValidItem {......}
class InvalidFoo{......}
ValidItem processFoo(Foo foo, List<InvalidFoo> foolist){
Do some processing on foo.
either return new ValidItem ();
OR
fooList.add(new InvalidFoo()) , and then return null;
}
List<InvalidFoo> invalidFooList = new ArrayList();
List<ValidItem> validItem =
fooList
.stream()
.map(e->processItem(e,invalidFooList))
.filter(Objects::notNull)
.collect(Collectors.toList());
现在我有无效和有效的列表,但这看起来不像一个干净的流代码。
【问题讨论】:
-
您的实体设计不应基于流处理,而应按设计在元素上使用流。也就是说,使用两个类中的 type 属性来区分它们,您可以按该属性进行分组,然后再转换为特定实例。
-
同意你的设计意见。但这些不是商业实体。只是为了提问,我发布了这个....基本上,我正在处理文件。这些是每行的处理结果项......基于结果
List<ValidItems>我将创建实体以持久化并将List<ErrorItems>发送回UI......我也觉得我不应该保留它们在同一个对象层次结构中,因此提出了问题。您提供的建议没有解决我提出的问题,我对它们进行分组没有问题。我的问题是如何收集流返回的 2 个不同类的列表 -
您正在读取一个文件,并从文件的每一行创建
ErrorItem或ValidItem,并且您想创建两个单独的列表,即List<ErrorItem>和LIst<ValidItem>.那是对的吗?该文件是文本文件吗? -
@Arba 它的 CSV,但是是的,它也可以被认为是文本......事情是,
ErrorItem与ValidItem一点也不相似......在ErrorItem我是只需输入errorMessage、errorReason、fieldname(如果是字段错误)并填写originalline,以便用户参考,而ValidItem不完全是但非常接近我的业务实体。 -
您能否edit 提出您的问题并从您的 CSV 中发布一些示例行,包括有效行和错误行,并指出您需要从此类示例数据中得到什么结果?
标签: java java-8 java-stream collectors