1

I have two lists of Objects. Need to traves through both them, match them by id then update list1 values of that object from list 2 if the id matches.

I know how to do it with old java but wondering if it can be done in JAVA8 (stream)

class Person {
    String id ;
    String name;
    String age;
}
p1:{1,test1,3}
p2:{2,test2,6}
p3:{3,test3,8}
p4:{1,test1,33}
p5:{2,test22,16}
p6:{3,test3,18}
p10:{10,test10,8}

List<Person> list1 = {p1,p2, p3, p10};
List<Person> list2 = {p4,p5, p6}; 

wanting the end result like this

list1 = {p1,p2, p3, p10}
p1:{1,test1,33}
p2:{2,test22,16}
p3:{3,test3,18}
p10:{10,test10,8}

basically, I want if the id matches I want the values to be overridden from list2 to list 1 (don't want list 3)

so far I was able to match them by id but then I am lost how to update the fields...

List<CartItemAttribute> test = existingCartItem.get().getAttributes().stream()
                        .filter(x -> (cartItem.getAttributes().stream()
                        .filter(y->y.getCartItemAttributeId()== x.getCartItemAttributeId())
                        .count()<1
)).collect(Collectors.toList());

here is what i have that works as expected

private void upsertAttributes(CartItem cartItem, Optional<CartItem> existingCartItem) {
        boolean addAtribute = true;
        List<CartItemAttribute> existingAttribute = existingCartItem.get().getAttributes();
        for (CartItemAttribute requestingList: cartItem.getAttributes()) {
            addAtribute = true;
            for (CartItemAttribute existingList: existingAttribute) {
                if(StringUtils.isNotBlank(requestingList.getCartItemAttributeId()) 
                              && requestingList.getCartItemAttributeId()
                                .equals(existingList.getCartItemAttributeId())) {

                    existingList.setKey(requestingList.getKey());
                    existingList.setValue(requestingList.getValue());
                    addAtribute = false;
                }
            }
            if(addAtribute) {
                existingAttribute.add(requestingList);
            }   
        }
}

4 Answers 4

4

Try this out

List<Person> list1 = getPersonList1();
List<Person> list2 = getPersonList2();

list1.replaceAll(l1 -> list2.stream()
          .filter(l2 -> l2.getId().equals(l1.getId()))
          .findAny()
          .orElse(l1));

list1.addAll(list2.stream()
          .filter(l2 -> !list1.contains(l2))
          .collect(toList()));

getPersonList1

private static List<Person> getPersonList1() {
    return Lists.newArrayList(
        new Person("1", "test1", "3"),
        new Person("2", "test2", "6"),
        new Person("3", "test3", "8"),
        new Person("10", "test10", "8")
    );
}

getPersonList2

private static List<Person> getPersonList2() {
    return Lists.newArrayList(
        new Person("1", "test1", "33"),
        new Person("2", "test22", "16"),
        new Person("3", "test3", "18"),
        new Person("4", "test4", "15")
    );
}

Output

List1

[
Person(id=1, name=test1, age=3), 
Person(id=2, name=test2, age=6), 
Person(id=3, name=test3, age=8), 
Person(id=10, name=test10, age=8)
]

List2

[
Person(id=1, name=test1, age=33), 
Person(id=2, name=test22, age=16), 
Person(id=3, name=test3, age=18), 
Person(id=4, name=test4, age=15)
]

Final List1

[
Person(id=1, name=test1, age=33), 
Person(id=2, name=test22, age=16), 
Person(id=3, name=test3, age=18), 
Person(id=10, name=test10, age=8), 
Person(id=4, name=test4, age=15)
]
Sign up to request clarification or add additional context in comments.

1 Comment

I had to change a little as the model was checking everything instead of ids and I didn't want to update that. but this worked. thank you so much for teaching me how to do this.
0

You can reassign the list by doing:

list1 = existingCartItem.get().getAttributes().stream()
                        .filter(x -> (cartItem.getAttributes().stream()
                        .filter(y->y.getCartItemAttributeId()== x.getCartItemAttributeId())
                        .count()<1
)).collect(Collectors.toList());

1 Comment

no this doesn't replace the list like that.i still have what I started with in list 1
0

You could implement the in-place update of the first list using replaceAll as:

list1.replaceAll(l1Person -> list2.stream()
        .filter(l2Person -> l2Person.getId().equals(l1Person.getId()))
        .findAny()
        .orElse(l1Person));

1 Comment

Thanks for the response. this solved my 1 issue where I am replacing the data from list2 with list 1 when the id is matching. but it doesn't add the data from list2 to list1 when the id is not matching with any of the ids (and it checked all data from list 2)
0
existingCartAttributes.replaceAll(l1 -> requestingCartAttributes.stream()
              .filter(l2 -> l2.getCartItemAttributeId().equals(l1.getCartItemAttributeId()))
              .findAny()
              .orElse(l1));

    System.out.println("*********************************");
    for (CartItemAttribute var: existingCartAttributes) {
        System.out.println("[" +var.getCartItemAttributeId() + "] [" + var.getKey() + "] [" +var.getValue()+"]");
    }
    System.out.println("*********************************");
    existingCartAttributes.addAll(requestingCartAttributes.stream()
              .filter(l2 -> StringUtils.isBlank(l2.getCartItemAttributeId()))
              .collect(Collectors.toList()));
    for (CartItemAttribute var: existingCartAttributes) {
        System.out.println("[" +var.getCartItemAttributeId() + "] [" + var.getKey() + "] [" +var.getValue()+"]");
    }

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.