1

I have such function and I should find all keys in references, that have values = null and delete them. How to do it?

public static void garbageCollector(Map references){
            if (references.containsValue(null) ==true){
                ????
            }

Thanks in advance.

codeMan
  • 5,730
  • 3
  • 27
  • 51
Kitty
  • 11
  • 1
  • 4
  • 2
    If you want to do this, then don't put null values into the map in the first place. :) – allprog Mar 26 '14 at 13:53
  • If you simply call containsValue(null) on the map, you didn't gain anything. You still have no entry point for deleting anything. The algorithm should be "Iterate over all entries in the map. With each entry, check if value == null. If yes, delete the entry." Are you able to transfer that into a code snippet? – Seelenvirtuose Mar 26 '14 at 13:56
  • http://stackoverflow.com/questions/15872313/remove-a-key-in-hashmap-when-the-values-hashset-is-empty – giannis christofakis Mar 26 '14 at 13:58
  • I have the Map references, which can contain some values, that = null. This is why i do the test on contain the null values in my Map. If it is true I should find keys of this values and delete them. – Kitty Mar 26 '14 at 13:58

8 Answers8

3

You could use an iterator:

public static void garbageCollector(Map references){
    Iterator iterator = references.entrySet().iterator();
    while (iterator.hasNext()) {
        Map.Entry pair = (Map.Entry)iterator.next();
        if (pair.getValue() == null) {
            iterator.remove(); // avoids a ConcurrentModificationException
        }
    }
 }

And in Java 8 you could create a new Map with the null entries removed with:

references.entrySet().stream().filter(p -> p.getValue() != null).collect(toMap(Entry::getKey, Entry::getValue));
Raul Guiu
  • 2,374
  • 22
  • 37
3
references.values().removeAll(Collections.singleton(null));

This should simply do the job for you :)

Shishir Kumar
  • 7,981
  • 3
  • 29
  • 45
2

I have prepared the demo as per your requirement. You can check this

public static void main(String args[]) {
    Map map = new HashMap();
    map.put(1, null);
    map.put(2, "val1");
    System.out.println("map is "+map);
    Iterator it = map.entrySet().iterator();
    while (it.hasNext()) {
         Map.Entry entry = (Map.Entry) it.next();
            Integer key = (Integer)entry.getKey();
            String value = (String)entry.getValue();
            if (value == null) 
                it.remove();

    }
    System.out.println("map is "+map);
}
Bernhard Barker
  • 54,589
  • 14
  • 104
  • 138
JManish
  • 321
  • 4
  • 17
1

Take a look on the following code sample:

public <K, V> static void garbageCollector(Map<K, V> map) {
    Collection<K> remove = new LinkedList<K>();
    for (Entry<K, V> e : map.entrySet()) {
        if (e.getValue() == null) {
            remove.add(e.getKey());
        }
    }
    for (K r : remove)  {
      map.remove(r);
    }
}

This is just one of a few ways to perform this.

AlexR
  • 114,158
  • 16
  • 130
  • 208
0

Loop through the keys, get the value of each key.
If that value is null, remove the key.

public static void garbageCollector(Map references){
    ArrayList lst = new ArrayList();
    for (Object k : references.keySet()){
        if (references.get(k)==null){
            lst.add(k);
        }
    }
    for (Object k : lst){
        references.remove(k);
    }
}
peter.petrov
  • 38,363
  • 16
  • 94
  • 159
0
Map<String, Object> m = new HashMap<String, Object>();
LinkedList<String> toRemove = new LinkedList<String>();
for (Entry<String, Object> e : m.entrySet()) {
    if (e.getValue() == null) {
        toRemove.add(e.getKey());
    }
}
for (String key : toRemove) {
    m.remove(key);
}
shem
  • 4,686
  • 2
  • 32
  • 43
0

Use entrySet(). Specification says that

The set is backed by the map, so changes to the map are reflected in the set, and vice-versa.

So, you can edit set with entries instead of map and that is easier.

    HashMap<Object, Object> map = new HashMap();
    System.out.println("before");
    map.put(1, 2);
    map.put(2, null);
    map.put(3, null);

    for (Map.Entry<Object, Object> e : map.entrySet()) {
        System.out.println(e.getKey() + "=" + e.getValue());
    }

    for (Iterator<Map.Entry<Object, Object>> i = map.entrySet().iterator(); i.hasNext();) {
        if (i.next().getValue() == null) {
            i.remove();
        }
    }

    System.out.println("\nafter");
    for (Map.Entry<Object, Object> e : map.entrySet()) {
        System.out.println(e.getKey() + "=" + e.getValue());
    }

Output:

before
1=2
2=null
3=null

after
1=2
Sergey Fedorov
  • 2,169
  • 1
  • 15
  • 26
-2

you could write as:

Iterator<Map.Entry<String,String>> iter = map.entrySet().iterator();
    while (iter.hasNext()) {
        Map.Entry<String,String> entry = iter.next();
        if(null == (entry.getValue())){
            iter.remove();
        }
    }
Shekhar Khairnar
  • 2,643
  • 3
  • 26
  • 44
  • 2
    Don't do it inside the loop you are going to cause a `ConcurrentModificationException`. – shem Mar 26 '14 at 14:00