Trying to compare two attributes from two lists. I usually compare it iterating two lists and comparing each element (which I think is not optimal). Like:
list1.forEach(x -> {
list2.forEach(y -> {
if (x.getId().compareTo(y.getId()) == 0)
x.setMyAttribute(y.getNameAttribute());
});
});
Is there a better way to compare a specific attribute from two lists? Still, I don't understand how to work with HashMap
, but I want to know if is better use HashMap
for this comparing and how to use it.
I guess I can create a HashMap
only with id
and name
(attributes I need).
CodePudding user response:
What you've shared is basically a brute-force solution, which checks every element in the list2
for each element in the list1
.
And you were thinking in the right direction. To avoid performing redundant iterations, you can index the contents of list2
by generating a HashMap
associating a particular element with its id
.
I'll assume that the natural order of id
is consistent with it equals/hashCode
implementation, i.e. (x.compareTo(y)==0) == (x.equals(y))
because it's a recommended practice (and if you're using as id
standard JDK classes like Long
, String
, UUID
it would be the case).
That's how it might be implemented:
List<Foo> list1 = // initializing list1
List<Foo> list2 = // initializing list1
Map<ID, Foo> list2FoosById = list2.stream()
.collect(Collectors.toMap(
Foo::getId,
Function.identity(),
(left, right) -> right // remove merge function if IDs are expected to be unique
));
for (Foo x : list1) {
Foo y = list2FoosById.get(x.getId()); // retrieving Foo from list2 with the corresponding ID
if (y != null) x.setMyAttribute(y.getNameAttribute()); // reassign the attribute if the Foo having identical ID exists
}