Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java 8 Map of Collections remove element from collection and remove entry if empty

I have a map for which the values are a collection. Given a key, I want to remove an element of the collection and return it, but I also want to remove the entry if the collection is empty. Is there a way to do this in a short way using one of the numerous new Map methods of Java 8?

One easy example (I use a Stack but it could be a List, a Set, etc.). For the sake of the example, let's say that it is already checked that the map contains the key.

public static String removeOne(Map<Integer, Stack<String>> map, int key) {
    Stack<String> stack = map.get(key);
    String result = stack.pop();
    if(stack.isEmpty()){
        map.remove(key);
    }
    return result;
}

I tried doing something like

map.compute(1, (k, v) -> {v.pop(); return v.size() == 0 ? null : v;});

But even though it does indeed remove the entry if empty, I don't know how to get the value returned by pop().

like image 727
Ricola Avatar asked Dec 18 '18 11:12

Ricola


3 Answers

Well, it's even uglier than what you have already in place, but there is a way, I guess:

public static String removeOne(Map<Integer, Stack<String>> map, int key) {
    String[] removed = new String[1];
    map.compute(key, (k, v) -> {
        removed[0] = v.pop();
        return v.size() == 0 ? null : v;
    });
    return removed[0];
}

Problem is that merge/compute and the like return the value, and in your case that is a Stack/Set/List, not and individual element from that collection.

like image 73
Eugene Avatar answered Nov 13 '22 14:11

Eugene


Or you could possibly rewrite it using size as:

public static String removeOne(Map<Integer, Stack<String>> map, int key) {
    return map.get(key).size() == 1 ? map.remove(key).pop() : map.get(key).pop();
}
like image 4
Naman Avatar answered Nov 13 '22 12:11

Naman


Is there a way to do this in a short way using one of the numerous new Map methods of Java 8?

There's no new method as of JDK8 that would improve your code whether that's in terms of readability or efficient.

if you're doing this as an exercise for your self then I can understand to some extent why you'd want to shorten the code (if possible) but when it comes to production code golfing should be avoided and instead go with the approach that is most readable and maintainable; doesn't matter if it's longer.

Your approach is good as is.

like image 2
Ousmane D. Avatar answered Nov 13 '22 14:11

Ousmane D.