我的目标是扩展List<A>
,其中每个A
都有一个属性List<B>
到一个List<A>
,每个A
将包含一个带有单个不同对象B
的列表。
考虑到A
和B
具有这样的结构:
class A{
String idA;
List<B> listOfB;
}
class B{
Long idB;
String name;
}
我想扩展List<A>
,使其包含每个不同的包含对象B
的对象A
(其中两个对象B
由属性name
区分(。例如
[
{
"idA": 1,
"listOfB": [
{
"idB": 3,
"name": "Foo"
}
]
},
{
"idA": 2,
"listOfB": [
{
"idB": 3,
"name": "Foo"
},
{
"idB": 4,
"name": "Bar"
}
]
}
]
应转换为
{
"idA": 1,
"listOfB": [
{
"idB": 3,
"name": "Foo"
}
]
},
{
"idA": 2,
"listOfB": [
{
"idB": 3,
"name": "Foo"
}
]
},
{
"idA": 2,
"listOfB": [
{
"idB": 4,
"name": "Bar"
}
]
}
]
如何使用流执行此操作?
如果在B中实现equals,这可能是解决方案之一。
Set<B> bs = as.stream()
.map(A::getListOfB)
.flatMap(List::stream)
.collect(Collectors.toSet());
return bs.stream()
.map(s -> as.stream()
.filter(a -> a.getListOfB().contains(s))
.map(a -> new A(a.idA, List.of(s)))
.collect(Collectors.toList())
)
.flatMap(List::stream)
.collect(Collectors.toList());
请注意,我已经在A&B.
如果我正确理解了您的解释和您提供的示例,您需要构建一个由对象A
组成的结果列表,其中每个元素都将包含一个对具有一个类型为B
的元素的列表的引用。
必须为最初包含在特定对象A
中的每个不同对象B
创建单例列表和将保持该列表的新对象A
。
为此,可以使用flatMap()
操作,该操作获取一个元素并返回一个扁平元素流。在嵌套流中应用的操作distinct()
将确保从每个列表中只窥视唯一对象B
(我假设hashCode/equals
契约在类B
中正确实现(。
List<A> listB = getSourceList();
listB.stream()
.flatMap(a -> a.getListOfB().stream()
.distinct()
.map(b -> new A(a.getIdA(), List.of(b))))
.collect(Collectors.toList());