Así que he algunos ejemplos de código que estoy jugando con a tratar de averiguar esta lógica a continuación. Es sólo una gran método principal y dos POJOs, sino que va a ejecutar. Estoy de depuración para obtener valores en el punto de terminación.
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());
}
}
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;
}
}
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;
}
}
Como se puede ver, estoy de streaming y el filtrado de cualquier obj
s que no coinciden con el carId
. Mi próximo objetivo es entonces set
id
(no Carid) en el objeto coincidente.
Básicamente, si obj1.carId == obj2.carId
ENTONCES set obj1.id = obj2.id
.
Mi problema es que no sé cómo hacer esto en la misma corriente. ¿Es posible? No puedo evitar pensar que hay una necesidad de un iterador en este punto?
Yo te sugeriría que primero la creación de un Map
mapeo carId
que id
para cada elemento de la primera lista (He modificado su clase un poco para que sea más legible y eliminado identificadores duplicados, que supongo eran un error):
@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)]
A continuación, puede utilizar esta Map
filtrar para los coches con la misma carID
sin tener que comparar uno con otro coche. Entonces, el uso forEach
acaba de establecer la identificación en la lista original.
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)]
Si desea que sólo los elementos con la misma carId
, se puede establecer el ID en peek
y después collect
. Esto todavía modificará los casos originales, sin embargo:
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)]
O crear una lista de completamente nuevos casos:
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)]