1

I feel like there most likely is a java library function to do this, and possibly another question on StackOverflow similar to this, but I couldn't find anything in my preliminary search.

I have two java.util.List objects, ListA and ListB. I want to use ListB, which is larger than ListA, to modify my elements in ListA. In order to do this, I need to match an ID from ListA to its corresponding element in ListB (my prior code ensures that every element in ListA will be in ListB) and then use a field in ListB to modify ListA.

Is a Hash function the best way to do this? or is there a better way?

EDIT: The two lists don't have the same type of objects

2
  • If the lists contain same type of object, you could implement hashCode and equals on that object using the id field, and use indexOf to find A objects in the list. Commented Jul 13, 2017 at 15:07
  • 4
    a map with ID <-> object is your way to go. Convert your ListB to a map. Then you can use the ID to get the corresponding object to modify ListA Commented Jul 13, 2017 at 15:08

4 Answers 4

2

You should probably create a Map from ListB, mapping the ID attribute to the element from ListB that correspond to that ID. Even if ListB being a list is a given, it is probably faster to convert it to a Map on the fly than to search the entire ListB for each element in ListA.

You can then just get the corresponding B for any A and modify that A accordingly. Here's a simplified example.

class A { int id; String foo; }
class B { int id; String bar; }

List<A> listA = ...
List<B> listB = ...
Map<Integer, B> mapB = listB.stream().collect(Collectors.toMap(b -> b.id, b -> b));
for (A a : listA) {
    B b = mapB.get(a.id);
    a.foo = b.bar;
}
Sign up to request clarification or add additional context in comments.

1 Comment

I did something similar to this but used a MultiMap instead and populated with a for loop, only because the people I'm collaborating with prefer MultiMaps. I think in general this is the best answer though.
0

Using HashSet might be your best bet. When you add a new element to a HashSet, a hashing algorithm gives a key to every unique element. If you're checking IDs, a Hash key might be your answer. Also, your prior code that guarantees might become obsolete, as HashSet will add every element from ListA to ListB if you want it to. I would like to give you more specific advice, but your question is very vague.

Comments

0

The answer is: depends.

The optimal data structure to use depends on your exact requirements. When your main (almost only) use case is to fetch an object from list B based on an entry in list A - then the natural choice would be a Map<ID, ListBEntry>. That could meant you actually don't have a list B in the end; just that map.

But in case their are other usage patterns, you might have to keep a map and both lists around.

Or, if your constraint is memory (not CPU cycles/performance), you might even just go with two lists and search lists for matching values each time.

Comments

0

I think tobias_k's answer is absolutely correct. Here I'd like to show a different way of coding his solution:

Map<ID, B> map = new HashMap<>();
listB.forEach(b -> map.put(b.getID(), b));

listA.replaceAll(a -> {
    B b = map.get(a.getID());
    // modify a with b here
    return a;
});

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.