Flatten List<A> 其中每个 A 包含一个 List<B> 用于每个不同的 B
Flatten List<A> where each A contains a List<B> for every distinct B
我的目标是扩展 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"
}
]
}
]
如何使用 streams 执行此操作?
如果您在 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 singleton-list 和一个新对象 A
必须为最初包含在特定对象 A
中的每个不同对象 B
创建将保存此列表的新对象 A
。
为此,您可以使用 flatMap()
操作,该操作接受一个元素和 returns 扁平元素流。在嵌套流中应用的操作 distinct()
将确保只有唯一对象 B
将从每个列表中被窥视(我假设 hashCode/equals
合同在 class 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());
我的目标是扩展 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"
}
]
}
]
如何使用 streams 执行此操作?
如果您在 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 singleton-list 和一个新对象 A
必须为最初包含在特定对象 A
中的每个不同对象 B
创建将保存此列表的新对象 A
。
为此,您可以使用 flatMap()
操作,该操作接受一个元素和 returns 扁平元素流。在嵌套流中应用的操作 distinct()
将确保只有唯一对象 B
将从每个列表中被窥视(我假设 hashCode/equals
合同在 class 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());