0

My application requires a multivaluemap with a key having 2 types of values say List and String. Map can return all the values or a single value based on type parameter as in get(key, type).

Couldn't find such feature in either spring's or apache multivaluemap. Is there any other library providing this data structure or I would have to implement my own?

Yateen Gupta
  • 68
  • 1
  • 1
  • 10
  • What about creating your own object so you can create your map this way Map ? – rilent May 07 '19 at 09:00
  • But I need to store multiple value types for a key – Yateen Gupta May 07 '19 at 09:03
  • 1
    Provide us an example please, I don't see why this wouldn't work for your situation. You can have the list of values in the YourOwnObject class. – rilent May 07 '19 at 09:04
  • Specifically, my value types are Map as well as list. So insert statements would be like: put(key, new HashMap); put(key, new ArrayList) – Yateen Gupta May 07 '19 at 09:09
  • Then create an object which has a Hashmap and an ArrayList (I have updated my answer), with no more informations I still don't understand what is the issue – rilent May 07 '19 at 09:14
  • The required functionality is that I need to fetch values based on key and value type. In your case, the variable names would be required to fetch either map or list. But I need to fetch on the basis of type, not by value names – Yateen Gupta May 07 '19 at 09:22

3 Answers3

0

Create your own object

public class YourOwnObject {

    private HashMap<String,String> valuesMap
    private ArrayList<String> valuesList;

}

and when you instantiate your Map :

Map<String,YourOwnObject>

You are pretty free to do anything if you go this way

rilent
  • 659
  • 1
  • 6
  • 22
0

It is bit easy to add multimap in Java 8 with lamda expression with different values as expected. Here is the sample code. You can give a try.

public class TestMultiMap<K, V> {

    private final Map<K, Set<V>> multiValueMap = new HashMap<>();

    public void put(K key, V value) {
        this.multiValueMap.computeIfAbsent(key, k -> new HashSet<>()).add(value);
    }   
    public Set<V> get(K key) {
        return this.multiValueMap.getOrDefault(key, Collections.emptySet());
    }
}

The computeIfAbsent() method takes A key and a lambda. If that key does not exist, computeIfAbsent() runs and create new HashMap.

The getOrDefault() method returns the value or returns the empty set if key found to be null.

To use this

TestMultiMap<String,Object> testMultiMap = new TestMultiMap<>();
testMultiMap.put("Key 1", new Object());
testMultiMap.put("Key 2", "String 1");
testMultiMap.put("Key 3", 1);
Rowi
  • 545
  • 3
  • 9
  • But here value type is V for entire Set collection. I need to map different value types to a key – Yateen Gupta May 07 '19 at 09:31
  • @YateenGupta, I updated my answer hare and. V can be anything Object, String or Your own object – Rowi May 07 '19 at 09:53
  • Then how would you fetch based on value type. Iterating and checking type of each value? Don't think that would be an optimized solution. – Yateen Gupta May 07 '19 at 10:00
0

How about:

Map<String, Map<Class<?>, Object>> valuesByTypeByKey;

When fetching, supply the key and type:

public <T> T fetch(String key, Class<T> type) {
    return (T)valuesByTypeByKey.getOrDefault(key, Collections.emptyMap()).get(type);
}

Inserting works like this:

public <T> void insert(String key, Class<T> type, T value) {
    valuesByTypeByKey.computeIfAbsent(key, k -> new HashMap<>()).put(type, value);
}
john16384
  • 7,800
  • 2
  • 30
  • 44
  • Having class name as a key came to my mind, but wasn't sure about the scenario that has same class names across different packages and jars – Yateen Gupta May 07 '19 at 09:34
  • Class makes a perfectly fine key. Classes have a proper equals/hashCode, are immutable, and afaik they're even singletons. – john16384 May 07 '19 at 09:35
  • If you think `Class` is too broad, you can use an `enum`, like `public enum Type {TEXT, NUMBER, BOOLEAN}`. – john16384 May 07 '19 at 09:42
  • I think enum would be a good idea, this thread highlights the problem https://stackoverflow.com/questions/2625546/is-using-the-class-instance-as-a-map-key-a-best-practice – Yateen Gupta May 07 '19 at 09:43
  • That's not really an issue in normal Java applications. Apps deployed in containers just need to be careful not to put them into static fields. If you don't use shared containers or redeploy webapps without restarting the entire instance (and who does that still these days), there is no issue. – john16384 May 07 '19 at 09:50