简体   繁体   中英

How to modify HashMaps according to values

Let's say I have a HashMap<String, Integer> containing usernames and their position as an int in a queue or line. How would I go about removing a user from the queue and subsequently update all the values for the users behind?

I've found a method of doing this that I believe should work. @Rias, thanks for the direction to concurrent hashMaps which provided a way to complete the same task I was facing.

public void removeFromQueue(String user) {
    if (queueMap.containsKey(user)) {
        int userPlace = queueMap.get(user);
        for (String currentser : queueMap.keySet()) {
            if (queueMap.get(currentUser) > userPlace) {
                queueMap.put(user, queueMap.get(currentUser) - 1);
            }
        }
    }
}

The self-answer can be improved. Most obviously you are doing two map look ups for each entry when none are required (as we are iterating). Also there is now the handy Map.replaceAll method. So perhaps:

public void removeFromQueue(String user) {
    Integer userPlace = queueMap.get(user);
    if (userPlace != null) {
        queueMap.replaceAll((k, v) -> v>userPlace ? v-1 : v);
    }
}

You can do it as follows:

import java.util.LinkedHashMap;
import java.util.Map;

public class Main {
    static Map<String, Integer> queueMap = new LinkedHashMap<String, Integer>();

    public static void main(String[] args) {
        queueMap.put("Arvind", 5);
        queueMap.put("Avinash", 6);
        queueMap.put("Kumar", 7);
        queueMap.put("Lightcaster", 8);
        queueMap.put("Stackoverflow", 9);
        System.out.println("Before: " + queueMap);
        removeFromQueue("Kumar");
        System.out.println("After: " + queueMap);
    }

    static void removeFromQueue(String user) {
        final Integer userPlace = queueMap.get(user);
        if (userPlace != null) {
            queueMap.replaceAll((k, v) -> v > userPlace ? v - 1 : v);
            queueMap.remove(user);
        }
    }
}

Output:

Before: {Arvind=5, Avinash=6, Kumar=7, Lightcaster=8, Stackoverflow=9}
After: {Arvind=5, Avinash=6, Lightcaster=7, Stackoverflow=8}

I hope I didn't miss anything, why you can't use a simple ArrayList<String> for all the user names?

The list will keep the users in order by their index, which is the equivalent of the value in your map. Moreover, if you remove a user which his index is i , then all the users with index > i will be reorganized as you want (after the removal the new index of the user with index i + 1 will be i )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM