Java 8 Java8将一个列表流到多个列表

Java 8 Java8将一个列表流到多个列表,java-8,Java 8,我需要根据某些属性将一个列表拆分为多个列表 List<Custom1> nums = new ArrayList<>(); List<Custom2> cats = new ArrayList<>(); List<Custom3> forms = new ArrayList<>(); list.stream().forEach(custom -> {

我需要根据某些属性将一个列表拆分为多个列表

 List<Custom1> nums = new ArrayList<>();
        List<Custom2> cats = new ArrayList<>();
        List<Custom3> forms = new ArrayList<>();

        list.stream().forEach(custom -> {
            if (custom.getType().equalsIgnoreCase("N")) {
                Custom1 attr = new Custom1();
                attr.setAttrCd(custom.getCode());
                attr.setValue(Float.parseFloat(custom.getValue()));

                nums.add(attr);
            } else if (custom.getType().equalsIgnoreCase("C")) {
                Custom2 attr = new Custom2();
                attr.setAttrCd(custom.getCode());
                attr.setValue(Integer.parseInt(custom.getValue()));

                cats.add(attr);
            } else if (custom.getType().equalsIgnoreCase("F")) {
                Custom3 attr = new Custom3();
                attr.setAttrCd(custom.getCode());
                attr.setValue(custom.getValue());
                forms.add(attr);
            }
        });
List nums=new ArrayList();
列表猫=新的ArrayList();
列表表单=新的ArrayList();
list.stream().forEach(自定义->{
if(custom.getType().equalsIgnoreCase(“N”)){
Custom1 attr=新Custom1();
attr.setAttrCd(custom.getCode());
attr.setValue(Float.parseFloat(custom.getValue());
增加(属性);
}else if(custom.getType().equalsIgnoreCase(“C”)){
Custom2 attr=新Custom2();
attr.setAttrCd(custom.getCode());
attr.setValue(Integer.parseInt(custom.getValue());
cats.add(attr);
}else if(custom.getType().equalsIgnoreCase(“F”)){
Custom3 attr=新Custom3();
attr.setAttrCd(custom.getCode());
attr.setValue(custom.getValue());
表格。添加(attr);
}
});
使用流过滤器可以使相同的代码变得更好

list.stream().filter(…).collect(toList())

但在我的例子中,我需要迭代3次。
还有其他更好的方法吗?

您应该尝试使用
收集器.partitioning by()
并将所需列表作为值收集到映射中。您可以查看更多信息,例如,此处-

更新:正如Nikolai所指出的,
partitioning by()
只能用于根据谓词函数拆分为两个子集

@用户1578872,您应该考虑类的正确继承:如果流中的所有类都有字段
type
和其他公共字段,我想您可以提取一些主要的抽象类。因此,您需要重构类,并将类型信息从类字段转换为类类型

然而,让我们假设您有:

public abstract class Custom {

    private String type;
    // other common fields
    // constructors etc.
}
以及扩展它的三个子类:
Custom1
Custom2
Custom3
。您可以将类型信息带到类名,例如
Num
Cat
表单
。 因此,在接下来的代码中,您可以根据对象类轻松地在集合上划分整个流:

Map<Class, Set<Custom>> collect = list.stream()
        .collect(Collectors.groupingBy(Custom::getClass, toSet()));
Map collect=list.stream()
.collect(Collectors.groupingBy(Custom::getClass,toSet());
非常简单的解决方案

如果输入对象具有用于创建新的不同对象的其他字段,则会出现问题。我认为,如果您处理的对象集具有太多的特性,就不应该使用流API。在这种情况下,或者您最好使用
switch
构造在一个
for循环中处理所有对象。另外,您应该记住,在流中处理异常并不是那么容易,也不是那么可读的解决方案


如果您仍然想使用Streams,您基本上已经将所有代码放在lambda表达式中,这些表达式必须传递给
收集器。mapping

您应该尝试使用
收集器。partitioning by()
并将所需列表作为值收集到映射中。您可以查看更多信息,例如,此处-

更新:正如Nikolai所指出的,
partitioning by()
只能用于根据谓词函数拆分为两个子集

@用户1578872,您应该考虑类的正确继承:如果流中的所有类都有字段
type
和其他公共字段,我想您可以提取一些主要的抽象类。因此,您需要重构类,并将类型信息从类字段转换为类类型

然而,让我们假设您有:

public abstract class Custom {

    private String type;
    // other common fields
    // constructors etc.
}
以及扩展它的三个子类:
Custom1
Custom2
Custom3
。您可以将类型信息带到类名,例如
Num
Cat
表单
。 因此,在接下来的代码中,您可以根据对象类轻松地在集合上划分整个流:

Map<Class, Set<Custom>> collect = list.stream()
        .collect(Collectors.groupingBy(Custom::getClass, toSet()));
Map collect=list.stream()
.collect(Collectors.groupingBy(Custom::getClass,toSet());
非常简单的解决方案

如果输入对象具有用于创建新的不同对象的其他字段,则会出现问题。我认为,如果您处理的对象集具有太多的特性,就不应该使用流API。在这种情况下,或者您最好使用
switch
构造在一个
for循环中处理所有对象。另外,您应该记住,在流中处理异常并不是那么容易,也不是那么可读的解决方案


如果您仍然想使用Streams,那么您基本上已经将所有代码放在lambda表达式中,这些表达式必须传递给
收集器。映射

list.stream().filter(…).collect(toList())
三次没有问题。它的复杂性仍然很高,而且您的代码更干净。

列表.stream().filter(…).collect(toList())
3次都没有问题。它的复杂性仍然是O(n),而且您的代码更干净。

被否决
partitioningBy
只生成2个列表,而OP至少需要3个抱歉,我的意思是
收集器。groupingBy
如何在没有if条件的情况下转换为3个不同的对象?measurements.stream().collect(Collectors.groupingBy(Custom::getType,Collectors.mapping(null,null));为答案添加更新above@user1578872,你解决问题了吗?投了反对票
partitioningBy
只生成2个列表,而OP至少需要3个抱歉,我的意思是
收集器。groupingBy
如何在没有if条件的情况下转换为3个不同的对象?measurements.stream().collect(Collectors.groupingBy(Custom::getType,Collectors.mapping(null,null));为答案添加更新above@user1578872,你解决问题了吗?