将java 7嵌套for循环转换为使用java 8 streams API

将java 7嵌套for循环转换为使用java 8 streams API,java,collections,iterator,java-8,java-stream,Java,Collections,Iterator,Java 8,Java Stream,我这里有一个示例,它基本上返回基于简单逻辑的列表 给定具有列表字段的输入列表和分组对象列表,如果grouping.name与输入列表中的任何字符串匹配,则该方法应返回包含grouping.list的所有成员的列表,或者将输入字符串添加到返回列表中 在我编写了这段代码之后,我认为可以在Java7中简化它,并使用Java8流式API作为更好的示例 public class CollectorExample { public static void main(String[] args){

我这里有一个示例,它基本上返回基于简单逻辑的列表

给定具有列表字段的输入列表和分组对象列表,如果
grouping.name
与输入列表中的任何字符串匹配,则该方法应返回包含
grouping.list
的所有成员的列表,或者将输入字符串添加到返回列表中

在我编写了这段代码之后,我认为可以在Java7中简化它,并使用Java8流式API作为更好的示例

public class CollectorExample {

    public static void main(String[] args){

        List<String> input = new ArrayList<>();
        input.add("foo");
        input.add("bar");
        input.add("foobar");
        input.add("java");

        List<String> list1 = new ArrayList<>();
        list1.add("hello");
        list1.add("world");

        List<String> list2 = new ArrayList<>();
        list2.add("spring");
        list2.add("multi-threaded");


        Grouping g1 = new Grouping("foobar",list1);
        Grouping g2 = new Grouping("java",list2);

        List<Grouping> groupingList = new ArrayList<>();
        groupingList.add(g1);
        groupingList.add(g2);


        System.out.println(mapAndMerge(input,groupingList));


    }


    public static List<String> mapAndMerge(List<String> input, List<Grouping> groupingList){

        Set<String> returnDocs = new HashSet<>();
        Iterator<String> it = input.iterator();
        while(it.hasNext()){
            String doc = it.next();
            boolean found = false;
            for (Grouping lg : groupingList){
                if (lg.getName().equals(doc)){
                    returnDocs.addAll(lg.getList());
                    found=true;
                   }
                }
            if (!found){
                returnDocs.add(doc);
            }
        }
    return new ArrayList<>(returnDocs);
    }

}

class Grouping {

    List<String> list;
    String name;

    public Grouping(String name, List<String> list){
        this.list=list;
        this.name=name;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public List<String> getList() {
        return list;
    }

    public void setList(List<String> list) {
        this.list = list;
    }


}

您可以使用Java8按照以下方式重新编写
mapAndMerge
方法。但它并不像你喜欢的那样简洁

    public static List<String> mapAndMerge(List<String> input,
        List<Grouping> groupingList) {

      Set<String> returnDocs = input
        .stream()
        .map(t -> groupingList
            .stream()
            .filter(g -> g.getName().equals(t))
            .map(v -> v.getList())
            .findAny()
            .orElse(Arrays.asList(t)))
        .flatMap(t -> t.stream())
        .collect(Collectors.toSet());

      return new ArrayList<>(returnDocs);
    }
公共静态列表映射和合并(列表输入,
列表分组列表){
设置returnDocs=input
.stream()
.map(t->groupingList
.stream()
.filter(g->g.getName().equals(t))
.map(v->v.getList())
.findAny()
.orElse(Arrays.asList(t)))
.flatMap(t->t.stream())
.collect(收集器.toSet());
返回新的ArrayList(返回文档);
}

我认为如果您使用
Map
而不是
Grouping
类,将会更加简单和清晰

这就是main()方法中的内容:

Map groupingMap=newhashmap();
groupingMap.put(“foobar”,列表1);
groupingMap.put(“java”,列表2);
List mergedDocs=new ArrayList();
input.stream()
.map(doc->groupingMap.getOrDefault(doc,Collections.singletonList(doc)))
.forEach(mergedDocs::addAll);
System.out.println(mergedDocs);
不使用
分组
类,而是使用一个简单的
映射
可以使这一过程简单得多。此映射将充当分组,保存给定名称的列表。由于查看映射的时间是常数时间(而您的解决方案是线性时间,因为它遍历分组以找到匹配的时间),因此这也使得性能更好

如果必须使用
列表
,您仍然可以对其进行预处理,将其转换为中间
映射

mapAndMerge
方法简单地变成:

public static List<String> mapAndMerge(List<String> input, List<Grouping> groupingList) {
    Map<String, List<String>> map = groupingList.stream().collect(Collectors.toMap(Grouping::getName, Grouping::getList));
    return input.stream()
                .flatMap(s -> map.getOrDefault(s, Arrays.asList(s)).stream())
                .collect(Collectors.toList());
}

请用你自己的话解释代码的意图。实际上它听起来更好。我使用了我不想在Java7中使用的布尔值。在Java7中,您是否可以在不使用布尔值的情况下重构相同的对象。
    Map<String, List<String>> groupingMap = new HashMap<>();
    groupingMap.put("foobar", list1);
    groupingMap.put("java", list2);

    List<String> mergedDocs = new ArrayList<>();
    input.stream()
         .map(doc -> groupingMap.getOrDefault(doc, Collections.singletonList(doc)))
         .forEach(mergedDocs::addAll);

    System.out.println(mergedDocs);
public static List<String> mapAndMerge(List<String> input, List<Grouping> groupingList) {
    Map<String, List<String>> map = groupingList.stream().collect(Collectors.toMap(Grouping::getName, Grouping::getList));
    return input.stream()
                .flatMap(s -> map.getOrDefault(s, Arrays.asList(s)).stream())
                .collect(Collectors.toList());
}
[foo, bar, hello, world, spring, multi-threaded]