Rey Cai
Rey Cai

Reputation: 35

How to delete entry in Java TreeMap?

I am making a method, which takes a provided TreeMap, removes entries where the key is a multiple of keyFilter and the value contains the valueFilter character, and then returns the resulting TreeMap.

This is what I have so far:

public static TreeMap<Integer, String> filterTreeMap(
        TreeMap<Integer, String> map, int keyFilter, char valueFilter) {
    for (Map.Entry<Integer, String> entry : map.entrySet()) {
        int mapKey = entry.getKey();
        String mapValue = entry.getValue();
        if (mapKey%keyFilter == 0 && mapValue.indexOf(valueFilter) != -1) {
            map.remove(mapKey);
        }
    }
    return map;
}

However, under the if condition where I want to delete the entries, I don't know how to delete entries in tree map. As far as I know, there is no existing method that I can use?

Upvotes: 0

Views: 1053

Answers (4)

dehasi
dehasi

Reputation: 2773

Keys on the map are unique. So, find that keys, and then remove them form the map.

public static TreeMap<Integer, String> filterTreeMap(TreeMap<Integer, String> map,
                int keyFilter, char valueFilter) {
                
                Set<Integer> keysToRemove = map.entrySet().stream()
                    .filter(kv -> kv.getKey() % keyFilter == 0 && kv.getValue().indexOf(valueFilter) != -1) // can be Predicate parameter
                    .map(Map.Entry::getKey)
                    .collect(Collectors.toSet());
        
                keysToRemove.forEach(map::remove);
                
                return map; // keep in mind, map is modified here. You might want to return a new map instead
            }

Upvotes: 1

Maneesha Indrachapa
Maneesha Indrachapa

Reputation: 905

Iterate over a copy and you can add/remove just fine:

for (Map.Entry<Integer, String> entry : new LinkedHashMap<Integer,String> (map).entrySet()) {
    int mapKey = entry.getKey();
    String mapValue = entry.getValue();
    if (mapKey%keyFilter == 0 && mapValue.indexOf(valueFilter) != -1) {
        map.remove(mapKey);
    }
}

It's not even any more lines of code, because the copy is made in-line via the copy constructor. LinkedHashMap was chosen to preserve iteration order (if that matters).

Upvotes: 0

Nowhere Man
Nowhere Man

Reputation: 19555

It is possible to apply method removeIf to the entry set.

default boolean removeIf(Predicate<? super E> filter)
Removes all of the elements of this collection that satisfy the given predicate. Errors or runtime exceptions thrown during iteration or by the predicate are relayed to the caller.

Implementation Requirements:
The default implementation traverses all elements of the collection using its iterator(). Each matching element is removed using Iterator.remove(). If the collection's iterator does not support removal then an UnsupportedOperationException will be thrown on the first matching element.

Then the method filterTreeMap may have void return type because the input map is modified and this change will be "visible" outside this method.

public static void filterTreeMap(
        TreeMap<Integer, String> map, int keyFilter, char valueFilter) {
    map.entrySet().removeIf(e -> 
        e.getKey() % keyFilter == 0
        && e.getValue().indexOf(valueFilter) != -1
    );
}

Upvotes: 2

Elliott Frisch
Elliott Frisch

Reputation: 201447

Use an Iterator. As the Iterator.remove() Javadoc notes

The behavior of an iterator is unspecified if the underlying collection is modified while the iteration is in progress in any way other than by calling this method.

Something like

public static TreeMap<Integer, String> filterTreeMap(TreeMap<Integer, String> map,
        int keyFilter, char valueFilter) {
    Iterator<Map.Entry<Integer, String>> iter = map.entrySet().iterator();
    while (iter.hasNext()) {
        Map.Entry<Integer, String> entry = iter.next();
        int mapKey = entry.getKey();
        String mapValue = entry.getValue();
        if (mapKey % keyFilter == 0 && mapValue.indexOf(valueFilter) != -1) {
            iter.remove();
        }
    }
    return map;
}

Upvotes: 3

Related Questions