How to achieve this Map<String, List<>> structure

152.5k views Asked by At

I have data like below:

 Key       value
-----      ------
car         toyota
car         bmw
car         honda

fruit       apple
fruit       banana

computer    acer
computer    asus
computer    ibm 
...

(Each row of above data is an object with fields "key" and "value", all in one List List<DataObject>)

I would like to construct the data to a Map<String, List<String>> like following:

 "car"      : ["toyota", "bmw", "honda"]
 "fruit"    : ["apple","banana"]
 "computer" : ["acer","asus","ibm"]

How to achieve above Map structure from the data objects?

******Besides******

I am more interested in using pure JDK provided classes or interfaces to achieve the result instead of using external library. Any help?

6

There are 6 answers

2
JB Nizet On

Iterate over the objects. For each object, get its corresponding list from the map. If null, create a new list and put it in the map. Then add the value to the list.

Or Use Guava's ListMultimap, which will do this for you.

0
dacwe On

I would use the guavas Multimap implementation. But it is easy doable with the standard JDK aswell.

Example standard JDK:

public static void main(String[] args) {
    Scanner s = new Scanner(
            "car         toyota\n" +
            "car         bmw\n" +
            "car         honda\n" +
            "fruit       apple\n" +
            "fruit       banana\n" +
            "computer    acer\n" +
            "computer    asus\n" +
            "computer    ibm");

    Map<String, List<String>> map = new LinkedHashMap<String, List<String>>();

    while (s.hasNext()) {

        String key = s.next();
        if (!map.containsKey(key))
            map.put(key, new LinkedList<String>());

        map.get(key).add(s.next());
    }

    System.out.println(map);
}

Example guava:

public static void main(String[] args) {
    Scanner s = new Scanner(
            "car         toyota\n" +
            "car         bmw\n" +
            "car         honda\n" +
            "fruit       apple\n" +
            "fruit       banana\n" +
            "computer    acer\n" +
            "computer    asus\n" +
            "computer    ibm");

    Multimap<String, String> map = LinkedListMultimap.create();

    while (s.hasNext()) 
        map.put(s.next(), s.next());

    System.out.println(map);
}

Output (both implementations):

{car=[toyota, bmw, honda], fruit=[apple, banana], computer=[acer, asus, ibm]}
1
scarba05 On
Map<String, List<String>> data = new HashMap<String, List<String>>();
data.put("car", Arrays.asList("toyota", "bmw", "honda"));
data.put("fruit", Arrays.asList("apple","banana"));
data.put("computer", Arrays.asList("acer","asus","ibm"));
0
Buhake Sindi On

Something like this perhaps?

Map<String, List<String>> dataMap = new HashMap<String, List<String>>();

Pseudocode:

for (String key : keys) {
    if (!dataMap.containsKey(key)) {
        dataMap.put(key, new ArrayList<String>());
    }

    dataMap.get(key).add(getValue(key));
}

Alternatively, use Guava ListMultiMap.

0
Vipul On

The below snippet should help you.

HashMap<String, ArrayList<String>> map = new HashMap<String, ArrayList<String>>();

ArrayList<String> carList = new ArrayList<String>();
carList.add("toyota");
carList.add("bmw");
carList.add("honda");

map.put("car", carList);

ArrayList<String> fruitList = new ArrayList<String>();
fruitList .add("apple");
fruitList .add("banana");

map.put("fruit", fruitList );
2
rius On
    Map<String, List<String>> myMaps = new HashMap<String, List<String>>();
    for (DataObject item : myList) {
        if (!myMaps.containsKey(item.getKey())) {
            myMaps.put(item.getKey(), new ArrayList<String>());
        }
        myMaps.get(item.getKey()).add(item.getValue());
    }