使用具有自定义条件的java8流创建另一个对象列表

时间:2018-03-20 13:46:18

标签: lambda java-8 java-stream

我有一个要求,我需要根据2个条件从另一个列表创建对象列表。 对象应处于会话状态或应处于活动状态。 [这个问题与Create list of object from another using java8 streams

含糊不清
class Person
{
    private String firstName;
    private String lastName;
    private String personId;
    //Getters and Setters
}

class UserInfo
{
    private String uFirstName;
    private String uLastName;
    private String userId;
    //Constructor, Getters and Setters
}

主要课程:

Boolean isActiveUser = ..... [getting from upstream systems]
HttpSession session = request.session();
List<String> sessionUserIds = session.getAttribute("users");

List<Person> personList = criteria.list(); //Get list from db.

//CURRENT COCDE
List<UserInfo> userList = new ArrayList<>();
for(Person person: personList) {
   UserInfo userInfo = new UserInfo(person);
   if(sessionUserIds.contains(person.getPersonId())){
       userInfo.setLoginTime("");  //Get LoginTime from upstream
       userInfo.setIdleTime("");   // Get IdleTime from Upstream
       userList.add(userInfo);
   } else {
       if(isActiveUser) {
            userList.add(userInfo);
       }
   }
}

 // Trying to GET IT converted to JAVA-8

 List<UserInfo> userList = personList.stream()
                   .filter(p ->  ??)
                   .map( ??
                   .collect(Collectors.toList());

任何帮助将不胜感激。

3 个答案:

答案 0 :(得分:2)

是否要为会话用户ID列表中的所有用户调整数据,而不调整其他用户的数据?也许以下内容对您而言(假设,正如您在其他地方所说的那样,getPersonId()返回的内容与getUserId()相同):

List<UserInfo> userList;
userList = personList.stream()
                       .filter(p -> isActiveUser || sessionUserIds.contains(p.getPersonId()))
                       .map(UserInfo::new)
                       .collect(Collectors.toList());
userList.stream()
        .filter(u -> sessionUserIds.contains(u.getUserId())
        .forEach(u -> {
          u.setLoginTime(""); // Get LoginTime from upstream
          u.setIdleTime(""); // Get IdleTime from Upstream
        });

请务必阅读foreach javadoc

或者只使用一个流:

List<UserInfo> userList;
userList = personList.stream()
                     .filter(p -> isActiveUser || sessionUserIds.contains(p.getPersonId()))
                     .map(p -> {
                        UserInfo u = new UserInfo(p);
                        if (sessionUserIds.contains(u.getUserId())) {
                          u.setLoginTime(""); // Get LoginTime from upstream
                          u.setIdleTime(""); // Get IdleTime from Upstream
                        }
                        return u;
                      })
                     .collect(Collectors.toList());

我建议您在映射之前进行过滤。对我来说,它更具可读性。对每个人来说绝对不是这样。通过该代码进行心理调试时,至少我可以过滤掉一些元素,并专注于进一步处理中重要的事情。

答案 1 :(得分:1)

您可以创建流,然后检查用户是否处于活动状态或是否在会话中,然后如果用户在会话中使用setter并最终收集。

List<UserInfo> userList = personList.stream()
        .map(UserInfo::new)
        .filter(userInfo -> isUserActive || sessionUserIds.contains(userInfo.getUserId()))
        .map(userInfo -> {
            if(sessionUserIds.contains(userInfo.getUserId())) {
                userInfo.setLoginTime("");
                userInfo.setIdleTime("");
            }
            return userInfo;
        })
        .collect(Collectors.toList());

或者,如果您不介意在过滤器中使用setter。

List<UserInfo> userList = personList.stream()
        .map(UserInfo::new)
        .filter(userInfo -> {
            if (sessionUserIds.contains(userInfo.getUserId())) {
                userInfo.setLoginTime("");
                userInfo.setIdleTime("");
                return true;
            }
            return isUserActive;
        })
        .collect(Collectors.toList());

答案 2 :(得分:0)

不是一个好主意,只是一试。

如果personId成为userId,那么您可以尝试如下:

List<UserInfo> userList = new ArrayList<>();

personList.stream()
          .map(p -> new UserInfo(person)) // person becomes user here
          .forEach(u -> {

                if(sessionUserIds.contains(u.getUserId())){
                   userInfo.setLoginTime("");
                   userInfo.setIdleTime("");
                   userList.add(userInfo);
                } else if(isActiveUser) {
                    userList.add(userInfo);
                }
          }
      });