Java8FlatMap-以嵌套形式添加项并使用FlatMap检索对象

Java8FlatMap-以嵌套形式添加项并使用FlatMap检索对象,java,java-8,java-stream,collectors,flatmap,Java,Java 8,Java Stream,Collectors,Flatmap,我有一个对象Foo,其中包含条的列表。这些类别描述如下: class Foo { String name; List<Bar> bars = new ArrayList<Bar>(); Foo(String name){ this.name = name; } } class Bar { String name; Bar(String name){ this.name = name;

我有一个对象
Foo
,其中包含
条的列表。这些类别描述如下:

class Foo {
    String name;
    List<Bar> bars = new ArrayList<Bar>();

    Foo(String name){
        this.name = name;
    }
}

class Bar {
    String name;

    Bar(String name){
        this.name = name;
    }
}
IntStream
        .range(1, 4)
        .forEach(i -> foos.add(new Foo("Foo" + i)));

foos.forEach(f ->
            IntStream.range(1,4)
                    .forEach(i -> f.bars.add(new Bar("Bar"+i+" -> "+f.name))));
foos.stream()
        .flatMap(f -> f.bars.stream())
        .forEach(i -> System.out.println("Bar Name : "+i.name));
然后在
流上使用
flatMap
,如下所示:

class Foo {
    String name;
    List<Bar> bars = new ArrayList<Bar>();

    Foo(String name){
        this.name = name;
    }
}

class Bar {
    String name;

    Bar(String name){
        this.name = name;
    }
}
IntStream
        .range(1, 4)
        .forEach(i -> foos.add(new Foo("Foo" + i)));

foos.forEach(f ->
            IntStream.range(1,4)
                    .forEach(i -> f.bars.add(new Bar("Bar"+i+" -> "+f.name))));
foos.stream()
        .flatMap(f -> f.bars.stream())
        .forEach(i -> System.out.println("Bar Name : "+i.name));

如何使用Java
Stream
和lambdas在一次执行中完成所有这些事情?有没有其他方法可以使用Java 8风格来完成此类操作?

您可以在
mapToObj
中生成
Foo
实例,而不是
forEach

IntStream.range(1, 4)
         .mapToObj (i -> {Foo foo = new Foo("Foo" + i);
                          foo.bars =
                              IntStream.range(1,4)
                                       .mapToObj(j -> new Bar("Bar"+j+" -> "+foo.name))
                                       .collect(Collectors.toList());
                          return foo;
                    })
         .flatMap (f -> f.bars.stream())
         .forEach(i -> System.out.println("Bar Name : "+i.name));
但是,这不会将创建的
Foo
实例存储在
列表中。如果要将它们存储在
列表中
,可以将操作拆分为2个
管道(第一个以
收集(collector.toList())
结尾),或者使用
peek(f->foos.add(f))
Foo
实例添加到
foos
列表中
(这将要求您在运行管道之前实例化
foos
列表)

编辑:

修复了一些拼写错误并测试了代码:

Bar Name : Bar1 -> Foo1
Bar Name : Bar2 -> Foo1
Bar Name : Bar3 -> Foo1
Bar Name : Bar1 -> Foo2
Bar Name : Bar2 -> Foo2
Bar Name : Bar3 -> Foo2
Bar Name : Bar1 -> Foo3
Bar Name : Bar2 -> Foo3
Bar Name : Bar3 -> Foo3

我还通过使用peek和mapToObject执行以下管道操作获得了解决方案

IntStream.range(1, 4)
            .mapToObj(i -> new Foo("Foo"+i))
            .peek(f -> IntStream.range(1, 4)
                    .mapToObj(i -> new Bar("Bar"+i+"->"+f.name))
                    .forEach(f.bars::add))
            .flatMap(f -> f.bars.stream())
            .forEach(b -> System.out.println("Bar : "+b.name));

如果您只需要打印
Bar
实例的名称,那么
Foo
Bar
实例的整个构造和集合都已过时。您可以直接生成和打印名称:

IntStream.range(1, 4)
         .mapToObj(i -> "Foo" + i)
         .flatMap(name -> IntStream.range(1, 4)
            .mapToObj(i -> "Bar" + i + "->" + name))
         .forEach(System.out::println);

使用您的答案,我得到了以下编译错误:方法mapToObj(IntFunction@KaranVerma现在一切都已修复。不建议为此使用
peek
。peek有什么问题?它被明确声明为主要用于调试的函数。请参见@Holger立即获得它