littlespice3
littlespice3

Reputation: 141

Java List reference another List to modify itself

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

Upvotes: 1

Views: 116

Answers (4)

fps
fps

Reputation: 34450

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;
});

Upvotes: 0

tobias_k
tobias_k

Reputation: 82889

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;
}

Upvotes: 2

GhostCat
GhostCat

Reputation: 140427

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.

Upvotes: 0

Furkan Toprak
Furkan Toprak

Reputation: 121

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.

Upvotes: 0

Related Questions