Java map with multiple values: container class or multiple maps?

Viewed 319

I'm trying to create a mapping in which a UUID key points to both an object (e.g. some User class instance) and auxiliary information about that object (e.g. an int and a String). There are two obvious implementations of this:

import java.util.Map;
import java.util.HashMap;
import java.util.UUID;
...
    Map<UUID, User> main = new HashMap<UUID, User>();
    Map<UUID, Integer> aux1 = new HashMap<UUID, Integer>();
    Map<UUID, String> aux2 = new HashMap<UUID, String>();

or

import java.util.Map;
import java.util.HashMap;
import java.util.UUID;
...
    private static class UserInfo { // Nested class
        public final User user;
        public final int aux1;
        public final String aux2;

        public UserInfo(User user, int aux1, String aux2) {
            this.user = user;
            this.aux1 = aux1;
            this.aux2 = aux2;
        }
    }
...
    Map<UUID, UserInfo> main = new HashMap<UUID, UserInfo>();

Which is generally considered more performant, in terms of efficiency and memory usage? Or is there a more worthwhile third option?

2 Answers

For both memory and efficiency, I believe the second option is the better solution. The first solution is creating more Maps which use memory, and storing the same UUID which use memory.

It is also better for maintainability and readability, which unless performance to the millisecond is critical, is the more important of these. If you bundle the correlated information together, it is easier to determine where you got the information and what it is describing.

Also think about future development for the project, for example adding another descriptor for the user like aux3. For the first example you would need to add another hashmap, remember to add to the new hashmap, and remember to pull data from it as you are pulling from the others. This would create a lot of boilerplate for initial set up and access.

uuid = //some uuid
Map<UUID, Double> aux3 = new HashMap<UUID, Double>();

// some code
aux3.put(uuid, 1.0);

// some code ...
aux3.get();

But with composition method, you'd only need to remember to add the class property (with successors and mutators), and you are free to use these anywhere. Anytime you access from the user map, you only need I call to get(uuid) and you have access to all the associated data.

This is Subjective topic - evaluate below factors

  1. Information Security (just because you mentioned user) - can you keep all the information together
  2. depends on what you doing with these Maps and if there are likely to be issues because of later processing

otherwise, generally 2nd option (UserInfo class) is a good to idea.

Related