在一个流中过滤和设置()

not*_*nce 5 java collections java-8 java-stream

所以我有一些我正在玩的示例代码,试图在下面找出这个逻辑.它只是一个大的主要方法和两个POJO,但它会运行.我正在调试以在终止点获取值.

public class Main {

    public static void main(String[] args) {

        obj1 obj1 = new obj1();
        obj1 obj12 = new obj1();

        obj2 obj2 = new obj2();
        obj2 obj22 = new obj2();

        obj1.id = 123L;
        obj1.carId = 1234L;
        obj12.id = 123L;
        obj12.carId = 1234L;

        obj2.carId = 1234L;
        obj22.carId = 12345L;

        ArrayList<obj1> obj1Arr = new ArrayList<>();
        ArrayList<obj2> obj2Arr = new ArrayList<>();

        obj1Arr.add(obj1);
        obj1Arr.add(obj12);

        obj2Arr.add(obj2);
        obj2Arr.add(obj22);

        List<obj2> newCarList= obj2Arr.stream()
                .filter(anObjOf2 -> obj1Arr
                        .stream()
                        .anyMatch(carReg -> carReg.getCarId().equals(anObjOf2.getCarId())))
                .collect(Collectors.toList());
    }
}
Run Code Online (Sandbox Code Playgroud)

POJO1:

public class obj1 {

    Long id = null;
    Long carId = null;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getCarId() {
        return carId;
    }

    public void setCarId(Long carId) {
        this.carId = carId;
    }
}
Run Code Online (Sandbox Code Playgroud)

POJO2:

public class obj2 {

    Long id = null;
    Long carId = null;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public Long getCarId() {
        return carId;
    }

    public void setCarId(Long carId) {
        this.carId = carId;
    }
}
Run Code Online (Sandbox Code Playgroud)

正如您所看到的,我正在流式传输并过滤掉任何obj不匹配的内容carId.我的下一个目标是set id匹配对象的(不是carId).

基本上,如果obj1.carId == obj2.carId那么set obj1.id = obj2.id.

我的问题是我不知道如何在同一个流中执行此操作.可能吗?我不禁想到此时需要一个迭代器?

tob*_*s_k 2

我建议首先为第一个列表中的每个元素创建一个映射Map(我对你的类进行了一些修改,以使其更具可读性,并删除了重复的 ID,我认为这是一个错误):carIdid

@Data @AllArgsConstructor
class Car {
    Long id = null;
    Long carId = null;
}
List<Car> obj1Arr = Arrays.asList(new Car(1L, 123L), new Car(2L, 1234L));
List<Car> obj2Arr = Arrays.asList(new Car(0L, 1234L), new Car(0L, 12345L));

Map<Long, Long> carIdToId = obj1Arr.stream()
        .collect(Collectors.toMap(Car::getCarId, Car::getId));
// [Car(id=2, carId=1234), Car(id=0, carId=12345)]
Run Code Online (Sandbox Code Playgroud)

然后,您可以使用它Map来过滤具有相同的汽车,carID而不必与其他汽车进行比较。然后,使用forEach只需在原始列表中设置 Id 即可。

obj2Arr.stream()
        .filter(anObjOf2 -> carIdToId.containsKey(anObjOf2.getCarId()))
        .forEach(anObjOf2 -> anObjOf2.setId(carIdToId.get(anObjOf2.getCarId())));
System.out.println(obj2Arr);
// [Car(id=2, carId=1234), Car(id=0, carId=12345)]
Run Code Online (Sandbox Code Playgroud)

如果您想要具有相等的项carId,您可以在 中设置 ID peek,然后collect。不过,这仍然会修改原始实例:

obj2Arr = obj2Arr.stream()
        .filter(anObjOf2 -> carIdToId.containsKey(anObjOf2.getCarId()))
        .peek(anObjOf2 -> anObjOf2.setId(carIdToId.get(anObjOf2.getCarId())))
        .collect(Collectors.toList());
System.out.println(obj2Arr);
// [Car(id=2, carId=1234)]
Run Code Online (Sandbox Code Playgroud)

或者创建一个全新实例的列表:

obj2Arr = obj2Arr.stream()
        .map(Car::getCarId)
        .filter(carIdToId::containsKey)
        .map(carId -> new Car(carIdToId.get(carId), carId))
        .collect(Collectors.toList());
System.out.println(obj2Arr);
// [Car(id=2, carId=1234)]
Run Code Online (Sandbox Code Playgroud)