考虑一下这门课:
@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);但是我不想创建两个流,这可以用一个流来实现吗?
发布于 2020-05-21 09:54:22
但是我不想创建两个流,这可以用一个流来实现吗?
当然,您有两个选项,在这两个选项中都必须使用Collect.collectingAndThen从创建的Map中提取正确的值类型。
您需要首先使用以下lambda表达式:
BinaryOperator<User> binaryOperator = (u1, u2) ->
new User(u1.getName(), String.join(", ", u1.getLanguages(), u2.getLanguages()));解决办法:
Collectors.toMap与Collectors.collectingAndThen一起从Map<String, User>中提取值:
列表l= list.stream() // Stream .collect(Collectors.collectingAndThen( //地图用户::getName,// ..name作为关键用户->新用户(user.getName()),User.getLanguages(),// ..value作为用户binaryOperator),// ..combined映射->新ArrayList<>(map.values();//提取值Collectors.groupingBy与Collectors.collectingAndThen一起从由Collectors.reducing引起的Map<String, Optional<User>>中提取值:
列表ll = list.stream() // Stream .collect(Collectors.collectingAndThen( // Map用户)::getName,// .名为key Collectors.reducing(BinaryOperator),// .-> map.values().stream() //提取值.filter(可选:isPresent) // ..map(可选::get) // ..collect(Collectors.toList());// .创建一个列表注意:我假设您使用爪哇-8,使用爪哇-11或更高版本可能会有不同的解决方案。
发布于 2020-05-21 05:19:55
您可以使用Collectors.toMap()
List<User> l = new ArrayList<> (list.stream()
.collect(Collectors.toMap(u -> u.name,
u -> new User (u.name,u.languages),
(u1, u2) -> new User(u1.name, u1.languages + ", " + u2.languages)))
.values());https://stackoverflow.com/questions/61927722
复制相似问题