场景:在某种情况下,我需要使用Java 8流API根据某些字段条件为List
个对象设置一些值。
以下是对象User
的示例。
public class User{
private int id;
private String name;
private String text;
private boolean isActive;
}
这是我制定的代码
List<User> users = userDao.getAllByCompanyId(companyId);
users.stream()
.filter(Objects::nonNull)
.filter(User::isActive)
.peek(user -> user.setText('ABC'))
.filter(user -> !user.isActive())
.peek(user -> user.setText('XYZ')
我知道我根据条件将值设置为object的方式是错误的。
这只是使用流的试用版,最后我需要将值设置为users
对象。
有没有办法处理if-else条件。
答案 0 :(得分:8)
也许你过于复杂了。
List<User> users = new ArrayList<>();
users.stream()
.filter(Objects::nonNull)
.forEach(u -> u.setRole(u.isActive()?"ABC":"XYZ"));
答案 1 :(得分:5)
我在猜测所期望的行为,如果我错了,请纠正我。
您可以在lambda表达式中使用块:
List<User> users = userDao.getAllByCompanyId(companyId);
users.stream().filter(Objects::nonNull).forEach(user -> {
if (user.isPresent()) {
user.setRole("ABC");
} else {
user.setRole("XYZ");
}
});
答案 2 :(得分:3)
使用带有否定条件的其他filter
操作无法执行您想要的操作,因为这将使您最终得到一个空流(即,如果从数字列表中删除元素&lt; 5然后你删除元素&gt; = 5,你最终会得到一个空列表。
实现你想要的最简单直接的方法就是在其他答案中使用forEach
,特别是对于一个简单的例子(包括调用相同的setter方法,其参数为根据条件,ABC
或XYZ
。
但是如果您需要根据某些条件对每个元素应用不同的逻辑,则可能需要按照此条件对您的流进行分区,然后对每个分区采取不同的行为:
Map<Boolean, List<User>> partitioned = users.stream()
.filter(Objects::nonNull)
.collect(Collectors.partitioningBy(User::isActive));
然后,只需对每个分区执行操作:
// Apply logic to active users partition
partitioned.get(true).forEach(u -> u.setText("ABC"));
// Apply logic to inactive users partition
partitioned.get(false).forEach(u -> u.setText("XYZ"));