Patrick S.
Patrick S.

Reputation: 19

Is there an easier way for making a List in a HashMap inside another HashMap?

I'm working on a program that authorizes a user of a server to access it with a generated key, and I'm currently working on the generation part. The owner of the server can specify how many keys, the server ID, and the duration of the keys. I need to store and check if the key matches the serverID so users can use the keys to gain access.

The only thing I could think of was a complicated HashMap combination with another HashMap inside, with an List inside of that HashMap. The first String is the server ID which is unique to each server, the List is for the batch of generated keys, and the final String value is for the duration of those keys.

static HashMap<List<String>, String> keyTimeBundle = new HashMap<>();
static List<String> generatedKeys = new ArrayList<>();
static HashMap<String, HashMap<List<String>, String>> clientGeneratedKeys = new HashMap<>();

The problem is that I don't have any idea where to start when checking if the key goes with the matching server ID because the key is in another HashMap inside a List. I'm sure there's another easier way to implement this but I haven't thought of it yet so feel free to not use my method to explain how to store and check the values.

Upvotes: 0

Views: 212

Answers (3)

John Kugelman
John Kugelman

Reputation: 361675

It's definitely getting unwieldy. It's time to pare back the overgrowth with some carefully thought out classes. Giving good names to the concepts in your programs makes it a lot easier to reason through the logic and data structures you need.

class Id {
    String value;
}

class Server {
    Id id;
    List<Key> keys;
}

class Key {
    Id id;
    Server server;
    Instant expirationDate;
}

Each key has a reference to the server it's for, and each server has a list of keys that give access to it. Rather than assigning expiration times to bundles of keys, give each key its own expiration time. Creating a batch of keys just means creating a bunch of keys and giving them all the same expiration time.

The Id class might just be a simple wrapper around String, but it makes the code a bit easier to read since you don't have to figure out what different Strings are (are they IDs? names?). The name Id makes it clear that they're ID strings.

Once you have your classes it makes it easier to think about what additional data structures you'll need. For instance, you'll want some sort of global map to look up servers by ID.

public static Map<Id, Server> serversById;

Upvotes: 3

vinay kant
vinay kant

Reputation: 66

Very simple different approach would be use HashMap<String,String> only. You can take key as <serverId><delimiter(such as '#')><generatedKey> and value as the duration of that key in that particular server.

While searching you just concatenate serverId and key and just check the duration.

Upvotes: 0

Elgayed
Elgayed

Reputation: 1219

I would suggest that you implement a POJO representation of a key

public class Key{
    private String key;
    //duration is key specific this gives you more flexibility in issuing temporary individual keys
    private long duration;
    ....

then you store each server keys list in a map

HashMap<String, List<Key>> clientGeneratedKeys = ...

As for checking, you check whether that server's keys list contains the submitted key (don't forget to implement the Key class equals based on comparing the 'key' attribute)

clientGeneratedKeys.get("Server Id").contains("submitted key");

you will need some null-safety checks in the previous line of code

Upvotes: 0

Related Questions