使用java 8流的if-else条件

时间:2018-01-16 14:40:54

标签: java java-8 java-stream

场景:在某种情况下,我需要使用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条件。

3 个答案:

答案 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方法,其参数为根据条件,ABCXYZ

但是如果您需要根据某些条件对每个元素应用不同的逻辑,则可能需要按照此条件对您的流进行分区,然后对每个分区采取不同的行为:

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"));