java 从两个列表中查找值和设置值

avwztpqn  于 2023-01-15  发布在  Java
关注(0)|答案(3)|浏览(128)

我有一张

List<User> userList =  ...

List<Long> UserIdWithBilling = .....

如果在userList id字段中找到UserIdWithBilling列表中的值,我会搜索以将User字段设置为true

for(Long userId : UserIdWithBilling){
     Optional<User> optUserList =  userList.stream()
                                           .filter(ul->ul.getUserId().longValue()==userId)
                                           .findFirst();
        
     if(optUserList.isPresent()){
            optUserList.get().setBilling(true);
     }
        
 }

那是可行,但有没有更干净、更快的方法
也许有一种方法可以通过一条线完成

pvabu6sv

pvabu6sv1#

UserIdWithBilling转换为集合,然后在filter中使用contains

Set<Long> ids = new HashSet<>(UserIdWithBilling);
userList.stream()
   .filter(x -> ids.contains(x.getUserId()))
   .forEach(x -> x.setBilling(true));
q0qdq0h2

q0qdq0h22#

下面是使用新旧解决方案的可执行测试(作为一行程序)

import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.TestInstance;

import java.util.ArrayList;
import java.util.List;
import java.util.Optional;

import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

@TestInstance(TestInstance.Lifecycle.PER_CLASS)
public class UserList {
    List<User> userList =  new ArrayList<User>();
    List<Long> userIdsWithBilling = new ArrayList<>();

    @BeforeAll
    public void setup() {
        for (long id=1l; id<=10l; id++) userList.add(new User(id, false));
        for (long id=1l; id<=5l; id++) userIdsWithBilling.add(id);
    }

    @Test
    public void oldSolution() {
        for (Long userId : userIdsWithBilling) {
            Optional<User> optUserList = userList.stream()
                    .filter(ul -> ul.getId().longValue() == userId)
                    .findFirst();

            if (optUserList.isPresent()) {
                optUserList.get().setBilling(true);
            }
        }
        for (int i=0; i<5; i++) assertTrue(userList.get(i).getBilling());
        for (int i=5; i<10; i++) assertFalse(userList.get(i).getBilling());
    }

    @Test
    public void newSolution() {
        userList.stream().filter(user -> userIdsWithBilling.contains(user.getId()))
                .forEach(user -> user.setBilling(true));

        for (int i=0; i<5; i++) assertTrue(userList.get(i).getBilling());
        for (int i=5; i<10; i++) assertFalse(userList.get(i).getBilling());
    }

    private static class User {
        private Long id;
        private Boolean billing = false;

        public User(long id, boolean billing) {
            this.id = id;
            this.billing = billing;
        }
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public void setBilling(Boolean billing){
            this.billing = billing;
        }
        public Boolean getBilling(){
            return billing;
        }
    }
}

对于大型列表,您可以使用parallel streams,但请阅读相关文档。

tp5buhyn

tp5buhyn3#

在一行上,但请记住,它将原始userList上的计费更改为true。如果您想要像您的问题中那样的新列表,您必须重写。

UserIdWithBilling.forEach(
        billedUser -> userList.stream().filter(u -> u.getUserId() == billedUser).toList()
            .forEach(u -> u.setBilling(true)));

相关问题