我正在尝试创建Map<String, List<Moo>> fooMoos;
来自以下类结构:
class Foo {
String id;
Bar bar;
}
class Bar {
List<Moo> moos;
}
List<Foo> foos;
如果moos直接成为Foo的一个领域,我会做
Map<String, List<Moo>> fooMoos = foos.stream().collect(Collectors.toMap(Foo::getId, Foo::getMoos));
但是你如何用subFields做到这一点?有没有类似Foo :: getBar :: getMoos?
的东西我觉得我需要一个flatMap,但不知道该怎么做。
答案 0 :(得分:3)
函数引用很有用,但它们不支持链接。你需要使用像
这样的lambdafoo -> foo.bar.moos
或
foo -> foo.getBar().getMoos()
答案 1 :(得分:2)
使用短lambda简单得多。但是如果你真的想坚持方法引用,可以通过链接函数来完成。例如,使用Function.andThen
:
Map<String, List<Moo>> fooMoos = foos.stream().collect(Collectors.toMap(Foo::getId,
((Function<Foo,Bar>)Foo::getBar).andThen(Bar::getMoos)));
或者,使用Function.compose
:
Map<String, List<Moo>> fooMoos = foos.stream().collect(Collectors.toMap(Foo::getId,
((Function<Bar,List<Moo>>)Bar::getMoos).compose(Foo::getBar)));
与上述类似,在Guava中,有一个静态方法Functions.compose
,它允许您使用泛型类型推断来避免显式转换:
Map<String, List<Moo>> fooMoos = foos.stream().collect(Collectors.toMap(Foo::getId,
Functions.compose(Bar::getMoos, Foo::getBar)));