Обновление списка объектов из другого списка объектов с использованием потока java - PullRequest
0 голосов
/ 19 февраля 2020

У меня есть список Объекта A

A{
name
age
dob
}

и список Объекта B

B{
name
dob
}

.

Я всегда получаю Список A с A. Доб как ноль. и Список B с B.dob, имеющим значение. Мне нужно чтобы l oop через Список A и Список B найти общие объекты, используя поле имени в каждом объекте A и B, и обновить A.dob, используя B.dob

. Можно ли это сделать с помощью потоков

Ответы [ 2 ]

1 голос
/ 19 февраля 2020

Я бы предложил изменить список объектов A в forEach l oop:

// define: List<A> aList =

// define: List<B> bList =


aList.forEach(aListElement -> {
            // find the first B object with matching name:
            Optional<B> matchingBElem = bList.stream()
                    .filter(bElem -> Objects.equals(aListElement.getName(), bElem.getName()))
                    .findFirst();

            // and use it to set the dob value in this A list element:
            if (matchingBElem.isPresent()) {
                aListElement.setDob(matchingBElem.get().getDob());
            }

        }
);
0 голосов
/ 19 февраля 2020

Вы не должны использовать API-интерфейсы Stream для изменения состояния объекта.

Если вы все еще хотите изменить его, вы можете выполнить итерацию каждого элемента из списка A, отфильтровать, если dob равен нулю, найти dob по соответствующему имени в списке B.

List<A> aList = new ArrayList<>();
List<B> bList = new ArrayList<>();

aList.stream()
        .filter( a  -> a.dob == null)
        .forEach( a -> {
            Predicate<B> nameFilter = b -> b.name.equals(a.name);
            a.dob = findDob(nameFilter, bList);
        });

static String findDob(Predicate<B> nameFilter, List<B> bList) {
    B b = bList.stream()
            .filter(nameFilter)
            .findFirst()
            .orElse(new B());

    return b.dob;
}

Альтернативное эффективное решение: Учитывая, что у вас есть уникальное имя для каждого объекта B, вы можете подготовить поиск и найти возраст, используя эту карту, таким образом, вам не нужно повторять bList за каждую итерацию aList

List<A> aList = new ArrayList<>();
List<B> bList = new ArrayList<>();

Map<String, String> nameDobLookup = bList.stream()
                        .collect(Collectors.toMap(b -> b.name, b -> b.dob));

aList.stream()
        .filter(a -> a.dob == null)
        .forEach(a -> a.dob = nameDobLookup.get(a.name));
...