我有一个n
个项目列表,每个项目都有一个产品代码和m
个人(可能在多个项目中)。
这样的事情:
items: [
{ code: 'Tuna', people: [ 'Adam', 'Eric' ] },
{ code: 'Corn', people: [ 'Eric' ] },
...
]
我想将此映射到不同人员和他们拥有的产品的列表,或类似的东西:
people: {
Adam: ['Tuna'],
Eric: ['Tuna', 'Corn']
}
在过去的两个小时里,我一直在努力为自己的直接映射算法提供一个优雅的解决方案。
我在Java 8中这样做,所以流API全部用于争夺。订单并不重要。
这是我目前的最佳努力:
Map<Person, List<String>> partyProductMap = getItems().stream()
.flatMap(item -> item.getPeople().stream())
.distinct()
.collect(Collectors.toMap(
Function.identity(),
person -> getItems().stream()
.filter(item -> item.getPeople().contains(person))
.map(item -> item.getProductCode())
.distinct()
.collect(Collectors.toList())
));
很想听听我如何改进这个想法!
答案 0 :(得分:2)
我的观点是,最优雅的解决方案是简单的解决方案:
final Map<Person, Set<String>> partyProductMap = new HashMap<>();
for (final Item item : getItems())
for (final Person person : item.getPeople()) {
Set<String> codes = partyProductMap.get(person);
if (codes == null) partyProductMap.put(person, codes = new HashSet<>());
codes.add(item.code);
}
注意:这里使用的是Set而不是List
当然,像Item / Person这样的类有hashCode的正确实现,equals并且可能是compareTo
答案 1 :(得分:2)
怎么样:
Map<Person, List<String>> partyProductMap = getItems().stream().
flatMap(item -> item.getPeople().stream().map(
people -> Arrays.asList(
people, item.getProductCode()))).
collect(Collectors.groupingBy(x -> x.get(0),
Collectors.mapping(
x-> x.get(1), Collectors.toList())));