如何通过插入顺序添加和删除HashMap值?

时间:2017-01-08 15:35:25

标签: java hashmap limit wowza linkedhashmap

我想知道如何映射基于其唯一ID和id会话连接的用户,以便当该ID超过3个会话时,首先连接的用户将从hashmap中删除,依此类推

示例:

UserID:3 Session:1980002
UserID:3 Session:2841111
UserID:3 Session:84848

UserID已包含3个活动会话,删除最旧的会话并调用KillSession,让位给新的。

UserID:3 Session:2841111
UserID:3 Session:84848
UserID:3 Session:4848880

代码:

public void onHTTPCupertinoStreamingSessionCreate(HTTPStreamerSessionCupertino httpSession) {
    String User_Session = httpSession.getSessionId();
    String Client_ID = httpSession.getProperties().getPropertyStr("sql_client_id");
    /* Verifies that there are already 3 active sessions and removes the oldest, 
    since the limit of simultaneous sessions is 3 for each user,
    and add to hashmap, Client_ID and User_Session */
}

public void onHTTPCupertinoStreamingSessionDestroy(IHTTPStreamerSession httpSession) {
    String User_Session = httpSession.getSessionId();
    //remove from hashmap, Client_ID based on session User_Session
}

public void KillSession(int SessionId){ 
    IApplicationInstance Instance = applicationInstance;
    IHTTPStreamerSession sessions = Instance.getHTTPStreamerSessions().get(SessionId);
    sessions.rejectSession();
    //remove from hashmap, Client_ID based on session User_Session
}

Client_ID是数据库中用户的id,User_Session是为每个连接生成的wowza中的唯一会话,此会话没有相同的值,即,如果同一Client_ID连接多次,对于每个会话,价值都会有所不同。

也就是说,基本上我的难点是挂载hashmap,我怎么能这样做?

2 个答案:

答案 0 :(得分:2)

如果要按插入顺序添加和删除,请使用LinkedHashMap。 (可能有帮助的简单版本)

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

public class LinkedHashMapExample {
    static class User {
        LinkedHashMap<String, Integer> sessionIds = new LinkedHashMap<>();
        int userId;

        public User(int userId) {
            this.userId = userId;
        }

        public void addSession(String someField, int sessionId) {
            this.sessionIds = new LinkedHashMap<String, Integer>(sessionIds) {
                protected boolean removeEldestEntry(Map.Entry<String, Integer> eldest) {
                    return size() > 3;
                }
            };
            sessionIds.put(someField, sessionId);
        }

        @Override
        public String toString() {
            return "User{" +
                    "sessionIds=" + sessionIds +
                    ", userId=" + userId +
                    '}';
        }
    }

    public static void main(String[] args) {
        User user1 = new User(1);
        user1.addSession("1980002", 1980002);
        user1.addSession("84848", 84848);
        user1.addSession("2841111", 2841111);
        System.out.println(user1);
        user1.addSession("999999", 999999);
        System.out.println(user1);
        user1.addSession("777777", 777777);
        System.out.println(user1);
    }
}

答案 1 :(得分:1)

如果我已正确理解您希望每个用户/客户端ID最多存储三个会话ID,我真的不认为LinkedHashMap会对您有所帮助。 LinkedHashMap维持广告订单顺序是正确的,而不是HashMap

我对你有不同的建议。为了保持分离,我建议这个小辅助类来保存地图:

public class MapOfSessions {

    private Map<String, Queue<Integer>> sessionMap = new HashMap<>();

    public int countSessions(String clientId) {
        Queue<Integer> q = sessionMap.get(clientId);
        if (q == null) {
            return 0;
        } else {
            return q.size();
        }
    }

    public int removeOldestSession(String clientId) {
        return sessionMap.get(clientId).remove();
    }

    public void add(String clientId, int sessionId) {
        Queue<Integer> q = sessionMap.get(clientId);
        if (q == null) {
            q = new ArrayDeque<>();
            sessionMap.put(clientId, q);
        }
        q.add(sessionId);
    }

    public void remove(String clientId, int sessionId) {
        sessionMap.get(clientId).remove(sessionId);
        // if queue is now empty, may remove key from map
    }
}

现在,地图是保持客户ID和会话ID之间的对应关系的地方,而Queue保持了插入顺序。

通过这种方式,您可以通过以下方式解决您的任务。我已从killSession()中删除了地图,并已将该响应权交给来电者onHTTPCupertinoStreamingSessionCreate()

private int maxSessionsPerUser = 3;
private MapOfSessions sessionsPerUser = new MapOfSessions();

public void onHTTPCupertinoStreamingSessionCreate(HTTPStreamerSessionCupertino httpSession) {
    // use camel case for variable names: begin with lowercase, no underscores
    String userSession = httpSession.getSessionId();
    String clientId = httpSession.getProperties().getPropertyStr("sql_client_id");
    /* Verifies that there are already 3 active sessions and removes the oldest, 
    since the limit of simultaneous sessions is 3 for each user,
    and add to hashmap, clientId and userSession */
    if (sessionsPerUser.countSessions(clientId) == maxSessionsPerUser) {
        int oldestSession = sessionsPerUser.removeOldestSession(clientId);
        killSession(oldestSession);
    }
    sessionsPerUser.add(clientId, Integer.parseInt(userSession));
}

public void onHTTPCupertinoStreamingSessionDestroy(IHTTPStreamerSession httpSession) {
    String userSession = httpSession.getSessionId();
    // it’s easier to remove from map when we know both clientId and userSession
    String clientId = httpSession.getProperties().getPropertyStr("sql_client_id");
    //remove from hashmap, clientId based on session userSession
    sessionsPerUser.remove(clientId, Integer.parseInt(userSession));
}

// method name in camel case (like variable names)
public void killSession(int SessionId){ 
    IApplicationInstance Instance = applicationInstance;
    IHTTPStreamerSession sessions = Instance.getHTTPStreamerSessions().get(SessionId);
    sessions.rejectSession();
    //don’t remove from hashmap here, assume caller has done that
}

我将客户端ID存储为字符串,会话ID存储为整数。您可能希望对两者使用相同的类型。由于您已使用KillSession()参数声明int,因此我认为我会使用int进行会话。