如何使用Lambda表达式创建多个列表?

3

我有一个带有年龄属性的用户。 在我的方法中,我有一个List。如何将它拆分成多个列表,以便另一个用户可以使用:

List<User> lt6Users = new ArrayList<User>();
List<User> gt6Users = new ArrayList<User>();
for(User user:users){
   if(user.getAge()<6){
      lt6Users.add(user);
   }
   if(user.getAge()>6){
      gt6Users.add(user);
   }
   // more condition
}

我刚刚了解了lambda表达式的两种用法:

lt6Users = users.stream().filter(user->user.getAge()<6).collect(Collectors.toList());
gt6Users = users.stream().filter(user->user.getAge()>6).collect(Collectors.toList());

上述代码的性能非常差,因为它会多次循环遍历列表。
users.stream().foreach(user->{
  if(user.getAge()<6){
     lt6Users.add(user);
  }
  if(user.getAge()>6{
     gt6Users.add(user);
  }
});

上面的代码看起来像是没有使用lambda表达式的初始代码。是否有另一种使用lambda表达式特性(如filter和Predicate)编写代码的方法?

2个回答

6
您可以使用 Collectors.partitioningBy(Predicate<? super T> predicate)
Map<Boolean, List<User>> partition = users.stream()
                                          .collect(Collectors.partitioningBy(user->user.getAge()<6));

partition.get(true)将给出年龄小于6岁的用户列表,而partition.get(false)将给出年龄大于或等于6岁的用户列表。


抱歉如果我的示例不够清晰。我在代码块中有注释,说明它还有更多的条件适用于另一个列表,例如gt6andlt30User。我们该如何解决这个问题? - gianglaodai
2
@gianglaodai partitioningBy 只适用于通过单个谓词将 List 分成两个分区。您可以使用 Collectors.groupingBy 将 List 分成具有完全相同年龄的用户组(即,您将获得一个 Map<Integer,List<User>>),但也许这不是您想要的。 - Eran
除了我的问题之外,如果我想在每个“if”块中执行其他操作而不是添加元素到列表中,有没有办法做到这一点? - gianglaodai
1
@gianglaodai,您能具体说明一下吗?还有其他可能是什么? - Eran
如果(user.getAge() < 6){print('你好,宝贝' + user.getName())} 如果(user.getAge()> 6){print('你好,男孩' + user.getName())} - gianglaodai

-1
我找到了一种使用Lambda表达式解决这个问题的方法: 编写一个带有Predicate的方法:
public void addUser(List<User> users,User user,Predicate<User> p){
  if(p.test(user)){
    users.add(user);
  }
}

所以循环可以写成这样:

users.foreach(user->{
  addUser(lt6Users,user,(User u)->u.getAge()<6);
  addUser(gt6Users,user,(User u)->u.getAge()>6);
  // more condition
});

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接