Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I make a Map with two indexes?

Tags:

java

hashmap

I have one Map in java like this:

Map<String index1, Map<String index 2, Object obj>> map = new HashMap<>();

I want to get my Object in the map by using index1 and index2 as lookups.

like image 487
Yên Đậu Avatar asked Aug 22 '15 02:08

Yên Đậu


2 Answers

The easiest way to do this would be to use Guava's Table, if you're willing to use a third party library.

It works like this:

Table<String, String, Object> table = HashBasedTable.create();
table.put(index1, index2, obj);
Object retrievedObject = table.get(index1, index2);

You can add it to your project by following these instructions: How to add Guava to Eclipse project


If you don't want to use Guava, you have a big problem. If you try to insert an element with new first key, you have to make sure the innermap already exists. This means, every time you do put, you have to retrieve the innerMap, see if it exists, and then create it if it does not. You will have to do this every time you call Map.put. Also, you risk throwing a NullPointerException if the inner map doesn't exist when you call get on the inner map.

If you do this, should wrap your Map<String, Map<String, Object> in an outer class to manage these problems, or use Java 8's computeIfAbsent. But the easiest way is to just use Table as above.

If you make your own class to use instead of Table, it would be something like:

public class DoubleMap<R, C, V> {
  private final Map<R, Map<C, V>> backingMap;

  public DoubleMap() {
    this.backingMap = new HashMap<>();
  }

  public V get(R row, C column) {
    Map<C, V> innerMap = backingMap.get(row);
    if(map == null) return null;
    else return innerMap.get(column);
  }

  public void put(R row, C column, V value) {
    Map<C, V> innerMap = backingMap.get(row);
    if(innerMap == null) {
      innerMap = new HashMap<C, V>();
      backingMap.put(row, innerMap);
    }
    innerMap.put(column, value);
  }
}

You would use this class by doing:

DoubleMap<String, String, Object> map = new DoubleMap();

Note that this answer has a lot less features than the Guava version.

like image 184
durron597 Avatar answered Oct 14 '22 18:10

durron597


Getting a Value from a Map

If I understand your question, then with an index a and b that might look like (guarding against null with a ternary or Conditional Operator ? :),

Object obj = (map.get("a") == null) ? null : map.get("a").get("b");

Using a Generic Type

And you might be more specific, like

Map<String, Map<String, Something>> map = new HashMap<>();
Something s = (map.get("a") == null) ? null : map.get("a").get("b");

Adding values to the Map

Assuming you want to add your Something value to the map that could be done with something like,

Map<String, Map<String, Something>> map = new HashMap<>();
if (map.get("a") == null) {
    map.put("a", new HashMap<>());
}
map.get("a").put("b", value);
like image 27
Elliott Frisch Avatar answered Oct 14 '22 18:10

Elliott Frisch