我有两个列表,我循环填充最终列表,因为内部循环满足条件.
private ListgetEnumFromType(List vars, List enums) { List 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; }
我重构了代码以使用最新的Java 8流API,我想出了这个:
vars.stream().forEach( var -> { String typeWithoutPrimitiveIdentifier = var.getType().substring(1,var.getType().length()); enums.stream() .filter(enumVal -> typeWithoutPrimitiveIdentifier(enumVal.getName())) .forEach(enumVal -> { if (!enumList.contains(enumVal)) { enumList.add(enumVal); } }); } );
我怎么能更进一步去除嵌套的foreach()方法呢?
通过使用内部stream().forEach(..)
调用(所以你改变外部实例)的问题是,如果有人并行转换流并且集合不是线程安全的,那么你可以很容易地运行并发问题.add
forEach
enumList
相反,你应该赞成适合可变减少的收集方法:
private SetgetEnumFromType(List vars, List 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()); }
您可能还希望String -> Enum
预先构建映射以避免多次过滤.
private SetgetEnumFromType(List vars, List enums) { Map enumsName = enums.stream().collect(toMap(Enum::getName, e -> e, (e1, e2) -> e1)); return vars.stream() .map(var -> var.getType().substring(1)) .map(enumsName::get) .filter(Objects::nonNull) .collect(toSet()); }
如果你真的想要退货List
,你可以看一下Collectors.collectingAndThen
.