0

I'm using Java 8 and Groovy, unfortunately I can't use lambdas and I have two different lists of objects with one attribute in common, on the first List I get the most of data I need and on the second list I get the data in common, I wrote a for nested loop in order to update the first list with the attribute in common from the second list, I just want to know if there is a better way to improve this code:

    List<Object1> firstList = dao.something();
    List<Object2> secondList = dao.something2();
    List<Object1> thirdList = new ArrayList<Object1>();

    for (Object1 obj1 : firstList){
        for(Object2 obj2 : secondList){
            if(obj1.getSomething().equals(obj2.getSomething())){
                    obj1.setAttribute(ojb2.getAttribute);
                    thirdList.add(obj1);
            }
        }
    }

Any help will be useful, thank you.

7
  • Maybe you could have some benefit using Map instead of list so like Map<ObjectN, Id> where Id is the type of value returned by getId(). Commented Mar 17, 2021 at 18:54
  • If objects have unique id, then you can collect the second list in Map<IdType, Object2>. Then for each object from the first list, get id and get the desired object from the map if it is in the map. Commented Mar 17, 2021 at 18:58
  • @chptr-one thank you for mention the unique Ids, but objects does not have an unique Id, I updated my example Commented Mar 17, 2021 at 19:05
  • 2
    @HarifVelarde in your code each object in first list will take an attribute equal to the attribute of the last object in the second list, which found the same common attribute. And in the third list you will have several copies of the same object from the first list. Is it right? Commented Mar 17, 2021 at 19:20
  • 1
    For performance I'd suggest to convert list2 to hashmap if it contains more then 100 items. Also use @CompileStatic on your method. Commented Mar 18, 2021 at 1:21

2 Answers 2

1

You can use Iterable's forEach method to go through every element and search it in secondList and modify the content of the object

firstList.forEach(elem -> {
        V2 found = secondList.stream().filter(v1 -> v1.getId() == elem.getId()).findAny().orElse(null);               
        if(found != null) {
            elem.setAttribute(found);
        }
    });

Or you could use streams and map it into another list

 List<V1> thirdList = firstList.stream().map(elem -> { 
        V2 found = secondList.stream().filter(v1 -> v1.getId() == elem.getId()).findAny().orElse(null);               
        if(found != null) {
            elem.setAttribute(found);
        }
        return elem;
    }).collect(Collectors.toList());

If you want to compare two lists you'll always need to iterate twice. I hope this is helpful for you.

Sign up to request clarification or add additional context in comments.

2 Comments

your answer drive me to find a good solution on my scenario, thank you
My pleasure! at least it helped you
1

You can use Groovy's default collection methods:

List thirdList = firstList.findResults{ obj1 ->
  def obj2attr = secondList.find{ obj1.something == it.something }?.attribute 
  if( obj2attr ){
    obj1.attribute = obj2attr
    obj1
  }else
    null
}

findResults() is a handy mix of filter, map and collect

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.