将嵌套的foreach重构为Java8流

将嵌套的foreach重构为Java8流,java,java-8,java-stream,Java,Java 8,Java Stream,假设内部循环满足一个条件,我有两个循环列表来填充最终列表 private List<Enum> getEnumFromType(List<Bean.Var> vars, List<Enum> enums) { List<Enum> enumList = new ArrayList<>(); for (Bean.Var var : vars) { String typeWithoutTypeIdentif

假设内部循环满足一个条件,我有两个循环列表来填充最终列表

private List<Enum> getEnumFromType(List<Bean.Var> vars, List<Enum> enums) {
    List<Enum> enumList = new ArrayList<>();

    for (Bean.Var var : vars) {
        String typeWithoutTypeIdentifierPrefix = var.getType().substring(1,var.getType().length());
        for (Enum enumVal : enums) {
            if (typeWithoutTypeIdentifierPrefix.equals(enumVal.getName())) {
                if (!enumList.contains(enumVal)) {
                    enumList.add(enumVal);
                }
            }
        }
    }

    return enumList;
}

如何进一步删除嵌套的foreach()方法

使用
stream().forEach(…)
并在
forEach
中调用
add
(因此您可以修改外部
enumList
实例)的问题是,如果有人并行地转换流,并且集合不是线程安全的,那么您很容易遇到并发问题

相反,您应该支持适合可变缩减的收集方法:

private Set<Enum> getEnumFromType(List<Bean.Var> vars, List<Enum> enums) {
    return vars.stream()
               .map(var -> var.getType().substring(1))
               .map(v -> enums.stream().filter(e -> v.equals(e.getName())).findAny())
               .filter(Optional::isPresent)
               .map(Optional::get)
               .collect(toSet());
}

如果您真的想返回一个
列表
,您可以查看
收集器。Collecting然后

我会将其分为两个操作:

  • 获取不带基元标识符的类型列表
  • 查找名称为其中一个的所有
    Enum
    s,将它们收集到
    集中
    ,以确保没有重复项
  • 以下是我的想法,但未经测试:

    private List<Enum> getEnumFromType(List<Bean.Var> vars, List<Enum> enums) {
        List<String> typesWithoutPrefix = vars.stream()
            .map(e -> e.getType().substring(1))
            .collect(Collectors.toList());
    
        Set<Enum> set = enums.stream()
            .filter(e -> typesWithoutPrefix.contains(e.getName()))
            .collect(Collectors.toSet());
        return new ArrayList<>(set);
    }
    
    私有列表getEnumFromType(列表变量、列表枚举){
    列表类型WithOutPrefix=vars.stream()
    .map(e->e.getType().substring(1))
    .collect(Collectors.toList());
    Set=enums.stream()
    .filter(e->typesWithoutPrefix.contains(e.getName()))
    .collect(收集器.toSet());
    返回新的ArrayList(集合);
    }
    
    试试这个

    private List<Enum> getEnumFromType(List<Bean.Var> vars, List<Enum> enums) {
        return new ArrayList<>(
            vars.stream()
                .map(var -> var.getType().substring(1))
                .flatMap(s -> enums.stream()
                    .filter(e -> s.equals(e.getName())))
                .collect(Collectors.toSet())
        );
    }
    
    私有列表getEnumFromType(列表变量、列表枚举){
    返回新的ArrayList(
    vars.stream()
    .map(var->var.getType().substring(1))
    .flatMap->enums.stream()
    .filter(e->s.equals(e.getName()))
    .collect(收集器.toSet())
    );
    }
    
    返回值的顺序将与您的不同。

    .filter(enumVal->typeWithoutPrimitiveIdentifier.equals(enumVal.getName())
    ?如果您确实想返回列表,可以查看Collectors.collecting,然后使用
    .distinct().collector(Collectors.toList())
    private List<Enum> getEnumFromType(List<Bean.Var> vars, List<Enum> enums) {
        List<String> typesWithoutPrefix = vars.stream()
            .map(e -> e.getType().substring(1))
            .collect(Collectors.toList());
    
        Set<Enum> set = enums.stream()
            .filter(e -> typesWithoutPrefix.contains(e.getName()))
            .collect(Collectors.toSet());
        return new ArrayList<>(set);
    }
    
    private List<Enum> getEnumFromType(List<Bean.Var> vars, List<Enum> enums) {
        return new ArrayList<>(
            vars.stream()
                .map(var -> var.getType().substring(1))
                .flatMap(s -> enums.stream()
                    .filter(e -> s.equals(e.getName())))
                .collect(Collectors.toSet())
        );
    }