java收集器。减少到列表
考虑这类:
@Data
@AllArgsConstructor
@NoArgsConstructor
class User {
String name;
String languages;
}
我有一个List<User>
,我想减少对语言的学习。输入:
List<User> list = new ArrayList<>();
list.add(new User("sam", "java"));
list.add(new User("sam", "js"));
list.add(new User("apollo", "html"));
预期产出:
[User(name=apollo, languages=html), User(name=sam, languages=java, js)]
我可以使用以下代码实现这一点:
List<User> l = list.stream()
.collect(Collectors.groupingBy(
u -> u.name,
Collectors.reducing((u1, u2) ->
new User(u1.name, u1.languages + ", " + u2.languages))))
.values()
.stream()
.filter(user -> user.get() != null)
.map(user -> user.get())
.collect(Collectors.toList());
System.out.println(l);
但我不想创建两个流,可以使用单个流实现吗
# 1 楼答案
当然,这是可能的,您有两个选项,并且在这两个选项中都必须使用
Collect.collectingAndThen
从创建的Map
中提取正确的值类型首先需要使用以下lambda表达式:
解决方案:
Collectors.toMap
使用Collectors.collectingAndThen
从Map<String, User>
中提取值:Collectors.groupingBy
通过Collectors.collectingAndThen
从Map<String, Optional<User>>
中提取由Collectors.reducing
引起的值:注意:我假设您使用java-8,那么可能会有另一个使用java-11或更高版本的解决方案
# 2 楼答案
你可以使用
Collectors.toMap()
: