2

I have two list of objects accounts and salaries and I need to iterate the list of objects. If the id matches I need to update the account object.

I have list1 and list2 these two objects are different object type. we need to update the object(param) in list1 with list2 object(param).

Example

if(accounts !=null && salaries!=null) { // checking for nulls
    for (Account obj1 : accounts) {// iterating objects
        for (Salary obj2 : salaries) {
            String id = ibj2.getId();
            if (id.equals(obj1.getId())) {// id checks  
                obj1.setxxxx(obj2.getxxxx());// set the value
            }
        }
    }
}  

I tried:

list1.stream().flatMap(x -> list2 .stream() .filter(y -> x.getId().equals(y.getId())));
6
  • // i have tried this list1.stream().flatMap(x -> list2 .stream() .filter(y -> x.getId().equals(y.getId()))); Commented May 22, 2019 at 6:49
  • In my opinion, it's no reason to rewrite this iterative code to java 8 streams, because it doesn't get you any performance benefits, but only complicate the readability. Commented May 22, 2019 at 6:58
  • @GolovPavel, that is unless the lists are big, in which case, parallel streaming will benefit here Commented May 22, 2019 at 7:00
  • @Sharon Ben Asher, ok, if the list is big, it's may be useful Commented May 22, 2019 at 7:09
  • @GolovPavel, have a look at my answer and tell me how's the readability Commented May 22, 2019 at 7:11

3 Answers 3

4

Your flatMap (suggested in the comment), will produce a Stream<Salary>, which won't allow you do modify the corresponding Account instances.

You can create a Stream of Accounts and their corresponding Salary and run forEach on that Stream:

accounts.stream()
        .flatMap(a->salaries.stream()
                            .filter(s -> s.getID().equals(a.getID())
                            .map(s -> new SimpleEntry<Account,Salary)(a,s)))
        .forEach(e -> e.getKey().setxxxx(e.getValue().getxxxx()));
Sign up to request clarification or add additional context in comments.

Comments

3

The final operation, obj1.setxxxx(obj2.getxxxx()); requires to have both obj1 and obj2. that dictates the item that is streamed from both lists

list1.stream()
    .forEach(obj1 -> 
        list2.stream()
            .filter(obj2 -> obj1.getId().equals(obj2.getId()))
            .findFirst()
            .ifPresent(obj2 -> obj1.setxxxx(obj2.getxxxx()))
    );

Comments

3

I would always suggest to create a Map since the lookup cost will decrease and it will become more readable.

Map<String, List<Salary>> salaryById = salaries.stream().collect(Collectors.groupingBy(Salary::getId));
accounts.forEach(a -> CollectionUtils.emptyIfNull(salaryById.get(a.getId())).forEach(s -> s.setxxxx(..)));

In case Account Salary <-> Account is One to One you change grouping to Collectors.toMap(..)

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.