asun asun - 1 month ago 7
Java Question

What Data Structure to use (in JAVA) with 3 sets of keys in random order

I have 3 sets of keys: one is type, another is subtype and the last one is ID and value is a ProductObj. Originally, I thought of storing the ProductObj in HashMap of HashMap of HashMap (

HashMap<type, HashMap<subtype, HashMap<ID, prodObj>>>
) for faster search (want to design this as a Cache instead of keep retrieving from the DB). [Note: # of productObj is fixed] However, I learned that 50% of the time, I might only get ID and not type/subtype and another 50% would be type/subtype but no ID. What would be a good data structure to suit such purpose?

I thought of
HashMap<type, HashMap<subtype, HashMap<ID, uuid>>>
and another
HashMap<uuid, prodObj>
, but I hope to find a even better solution in terms of the data structure. Thanks in advance!

[Additional information]

This is what hope to store {type=1 subtype=1 id=1=prodObj1, type=1 subtype=1 id=2=prodObj2,...}

When id is given: e.g. id=1, then prodObj1 is returned

When type is given: e.g. type=1, the both prodObj1 and prodObj2 are returned

When type & subtype are given: e.g. type=1 subtype=1, the both prodObj1 and prodObj2 are returned

When type, subtype & id are given: e.g. type=1 subtype=1 id=1, then prodObj1 is returned

I hope to utilize a HashMap like data structure for faster search based on a key value as I will access the cache and change the prodObj state often.

Answer Source

Why using nested maps ?

If you don't manipulate a huge number of values in your map, you could use as key a custom class that defines a composite key (type, subtype and id).

In this way, you could pass to your map an instance of this composite key when you get from or put in.

public class ProductKey{

  private Long id;
  private string type;
  private string subType;

  private ProductKey(){

  public static ProductKey ofWithId(Long id){
    ProductKey productKey = new ProductKey(); = id;  
    return productKey;
  // other factory methods
  // equals and hashcode overriden of course

And you could instantiate and populate your map in this way :

Map<ProductKey, ProductObj> map = new HashMap<>();
map.put(ProductKey.ofWithId(1), myProductObj);
map.put(ProductKey.ofWithTypeAndSubType("type", "subtype"), anotherProductObj);

And retrieve element in this way :

 ProductObj retrievedObj = map.get(ProductKey.ofWithId(1));