如何实现这个Map<String, List<>>结构

22

我有以下数据:

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

fruit       apple
fruit       banana

computer    acer
computer    asus
computer    ibm 
...

上述数据的每一行都是一个带有“key”和“value”字段的对象,全部存储在一个List<DataObject>中。

我想将这个数据构建成一个如下所示的Map<String,List<String>>

 "car"      : ["toyota", "bmw", "honda"]
 "fruit"    : ["apple","banana"]
 "computer" : ["acer","asus","ibm"]
如何从数据对象实现上述Map结构?
除此之外,我更想使用纯JDK提供的类或接口来实现结果,而不是使用外部库。有什么帮助吗?

1
你已经解释了它应该看起来像什么(Map<String, List<String>>),你是指如何实现它?还有,这些数据存储在哪里以及以何种格式存储? - adarshr
@adarshr,由于数据列表的长度是随机的(可能有许多这种数据),我需要一种通用的方法来构建Map结构..我不确定如何做。 - Mellon
这些数据存储在哪里/如何存储?CSV文件?数据库?XML?JSON? - adarshr
@adarshr,正如我所提到的,我已经将数据作为列表List<DataObject>获取,每个DataObject代表一个带有“key”和“value”字段的行。 - Mellon
你可以使用Google Guava集合中的ListMultimap。http://docs.guava-libraries.googlecode.com/git/javadoc/com/google/common/collect/ListMultimap.html - Peter Štibraný
显示剩余2条评论
6个回答

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());
    }

这对我来说真是太神奇了。非常感谢你! - Vineela Thonupunuri
我收到以下错误:“DataObject无法解析为类型”。 - Questioner

13

我会使用番石榴 Multimap 实现。不过使用标准 JDK 也很容易实现。

标准 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);
}

茉莉例子:

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);
}

输出(两种实现方式均适用):
{car=[toyota, bmw, honda], fruit=[apple, banana], computer=[acer, asus, ibm]}

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,我只是举了一个数据的例子,并不意味着数据就是那样的,实际上,数据相当随机,但格式是那样的。如果问题像你的回答那么简单,我就不会在这里问了。 - Mellon

5
下面的代码片段应该会对你有所帮助。
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 );

3

遍历对象。对于每个对象,从映射中获取其相应的列表。如果为null,则创建一个新列表并将其放入映射中。然后将值添加到列表中。

或者使用Guava的ListMultimap,它会为您完成此操作。


我需要下载哪个外部库才能使用ListMultimap? - Mellon
当然是Guava。这就是为什么我说Guava的ListMultimap。 - JB Nizet

1

可能是这样的吗?

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

伪代码:

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

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

或者,使用Guava ListMultiMap


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接