22

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?

Peter Perháč
  • 20,434
  • 21
  • 120
  • 152
Mellon
  • 37,586
  • 78
  • 186
  • 264
  • 1
    You've already explained what it should look like (`Map>`). What do you mean how to achieve it? Also, where and in what format is this data stored? – adarshr Jun 07 '12 at 08:09
  • @ adarshr , Since the data list has random length(there could be many this kind of data), I need a generic way to construct the Map structure..I am not sure how to do it – Mellon Jun 07 '12 at 08:10
  • Where/how is this data stored? CSV? Database? XML? JSON? – adarshr Jun 07 '12 at 08:11
  • @ adarshr, As I mentioned, I already got the data as a list List , each DataObject represent a row with "key" and "value" fields – Mellon Jun 07 '12 at 08:12
  • You can use ListMultimap from Google Guava collection. http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ListMultimap.html – Peter Štibraný Jun 07 '12 at 08:12
  • What external library should I download in order to use this ListMultimap ? – Mellon Jun 07 '12 at 08:15
  • a good question, and genuinely helpful. i just found what i wanted. first time i came across Multipmap-s and Guava's LinkedListMultimap. Please reopen this question – Peter Perháč Nov 11 '14 at 21:35

6 Answers6

35
    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());
    }
rius
  • 461
  • 3
  • 6
13

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]}
dacwe
  • 43,066
  • 12
  • 116
  • 140
6
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"));
scarba05
  • 2,943
  • 1
  • 27
  • 29
  • @ scarba05, I only make an example of the data, does not mean the data is like that, actually, the data is quite random, but in that format. If it is as simple as your answer, I won't ask here – Mellon Jun 07 '12 at 08:13
5

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 );
cela
  • 2,352
  • 3
  • 21
  • 43
Vipul
  • 27,808
  • 7
  • 60
  • 75
3

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.

JB Nizet
  • 678,734
  • 91
  • 1,224
  • 1,255
1

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.

Buhake Sindi
  • 87,898
  • 29
  • 167
  • 228