Reputation: 35
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
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
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
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 itsiterator()
. Each matching element is removed usingIterator.remove()
. If the collection's iterator does not support removal then anUnsupportedOperationException
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
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