Marwan Jaber
Marwan Jaber

Reputation: 641

How to compare Map with List

Sorry for the title, I couldn't find a better one and I know it sounds confusing. The issue is as follow:

I have a HashMap with that Looks like the following:

Map<String, ClassA> myMap;

Also, I have a List that Looks like the following:

List<ClassB> myList;

The ClassB looks like the following:

   public class ClassB{

    //many things

    private String someString;
    //getter
    //setter
    }
}

The someString is the key string myMap

I want to remove from the map, all the objects that I can't find in the list myList with the least number of iterations, because this cleaning will happen once every few seconds all the time for life.

Any algorithm? Pattern or even example?

Thank you

Upvotes: 3

Views: 237

Answers (3)

Stuart Marks
Stuart Marks

Reputation: 132350

Looks like you want retainAll. The trick is that you call this on the map's keySet(), which has the side effect of removing unwanted entries from the map.

Next, you want to retain the elements not in the List<ClassB>, but in a list of strings derived from each instance of ClassB. You can use a stream to do that.

    myMap.keySet()
         .retainAll(myList.stream()
                          .map(ClassB::getSomeString)
                          .collect(toList()));

Upvotes: 2

Imesha Sudasingha
Imesha Sudasingha

Reputation: 3570

With java 8 stream API,

Set<String> keySet = new HashSet<>(myMap.keySet());
myList.forEach(entry -> keySet.remove(entry.getSomeString()));
keySet.forEach(key -> myMap.remove(key));

That's it. What I just did was just removed the keys which are in the list from the keySet. Then, I remove all the keys which are left. This will run in O(n).

This will be consuming lesser memory than the current solution since you are creating an additional Set instead of a Map.

Upvotes: 2

Nir Alfasi
Nir Alfasi

Reputation: 53525

You have to iterate List<ClassB> myList at least once in order to do so, but you can do it with one iteration exactly, which makes it ideal algorithmic-wise.

Create a new Map and for each element in the list check if it's in myMap and if it's there - add it to the new Map you created. After you finish iterating the list simply assign: myMap = newMap; and you're done.

Note: this is ideal for minimal number of steps, but it is using more memory than an "in-place" algorithm.

Upvotes: 5

Related Questions