如何使用值作为List或Array将HashMap中的键分组

时间:2017-09-14 12:35:50

标签: java hashmap key-value

我使用String作为键创建了Map,使用Integer作为值。所以,它就像citiesWithCodes

为了测试目的,我现在手动将值放在Hashmap中。他们是:

Map<String, Integer> citiesWithCodes = new HashMap<String, Integer>();
        citiesWithCodes.put("Berlin", 49);
        citiesWithCodes.put("Frankfurt", 49);
        citiesWithCodes.put("Hamburg", 49);
        citiesWithCodes.put("Cologne", 49);
        citiesWithCodes.put("Salzburg", 43);
        citiesWithCodes.put("Vienna", 43);
        citiesWithCodes.put("Zurich", 41);
        citiesWithCodes.put("Bern", 41);
        citiesWithCodes.put("Interlaken", 41);

我想根据他们的代码以List或Array格式获取城市。因此,例如对于值43,它应该返回类似{43=[Vienna, Salzburg]}

的内容

我尝试过以下方法。这是一种绝对肮脏的方法,并没有给出正确的结果。

   public static Map<Integer, List<String>> codeCities(Map<String, Integer> citiesWithCodes){
       Map<Integer, List<String>> segList = new HashMap<Integer, List<String>>();
       List<String> city;
       Iterator<Entry<String, Integer>> i = citiesWithCodes.entrySet().iterator();
       while (i.hasNext()) {
           city = new ArrayList<String>();
           Entry<String, Integer> next = i.next();
           i.remove();
           city.add(next.getKey());
           for (Entry<String, Integer> e : citiesWithCodes.entrySet()) {
               if(e.getValue().equals(next.getValue())){
                   city.add(e.getKey());
                   citiesWithCodes.remove(e);
               }
           }
           System.out.println(city);
           segList.put(next.getValue(), city);
       }
       return segList;
   }

我得到的输出是:{49=[Cologne], 41=[Interlaken], 43=[Salzburg]} 有人能告诉我,实现结果的正确方法吗?

PS:我知道可以使用MultiMap。但我们仅限于使用Java Collection Framework而不是Java 8。

3 个答案:

答案 0 :(得分:3)

如果您的范围仅限于 Java 7 ,请尝试更改以下代码:

 Map<Integer, List<String>> segList = new HashMap<Integer, List<String>>();
 Iterator<Entry<String, Integer>> i = citiesWithCodes.entrySet().iterator();
            while (i.hasNext()) {
                  Entry<String, Integer> next = i.next();
                  if (segList.get(next.getValue()) != null) {
                       List<String> city= segList.get(next.getValue());
                       city.add(next.getKey());
                       segList.put(next.getValue(), city);
                  }else{
                        List<String> city=new ArrayList<String>();
                        city.add(next.getKey());
                        segList.put(next.getValue(), city);

                  }
            }

<强>输出:

  

{49 = [法兰克福,柏林,汉堡,科隆],41 = [伯尔尼,苏黎世,   因特拉肯],43 = [维也纳,萨尔茨堡]}

答案 1 :(得分:2)

在java 8之前

package com.stackoverflow;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

public class HashMapToListMap {

public static void main(String[] args) {
    Map<String, Integer> citiesWithCodes = new HashMap<String, Integer>();
    citiesWithCodes.put("Berlin", 49);
    citiesWithCodes.put("Frankfurt", 49);
    citiesWithCodes.put("Hamburg", 49);
    citiesWithCodes.put("Cologne", 49);
    citiesWithCodes.put("Salzburg", 43);
    citiesWithCodes.put("Vienna", 43);
    citiesWithCodes.put("Zurich", 41);
    citiesWithCodes.put("Bern", 41);
    citiesWithCodes.put("Interlaken", 41);

    Map<Integer, List<String>> result = new HashMap<Integer, List<String>>();
    for(Entry<String,Integer> entry : citiesWithCodes.entrySet()){
            List<String> list = new ArrayList<String>();
            if(result.containsKey(entry.getValue()))
                list = result.get(entry.getValue());
            list.add(entry.getKey());
            result.put(entry.getValue(), list);
    }
    System.out.println(result);
}

}

在java 8之后

 package com.stackoverflow;

 import java.util.HashMap;
 import java.util.List;
 import java.util.Map;
 import java.util.stream.Collectors;

public class HashMapToListMap {

public static void main(String[] args) {
    Map<String, Integer> citiesWithCodes = new HashMap<String, Integer>();
    citiesWithCodes.put("Berlin", 49);
    citiesWithCodes.put("Frankfurt", 49);
    citiesWithCodes.put("Hamburg", 49);
    citiesWithCodes.put("Cologne", 49);
    citiesWithCodes.put("Salzburg", 43);
    citiesWithCodes.put("Vienna", 43);
    citiesWithCodes.put("Zurich", 41);
    citiesWithCodes.put("Bern", 41);
    citiesWithCodes.put("Interlaken", 41);


    Map<Integer, List<String>> result =  citiesWithCodes.entrySet().stream().collect(Collectors.groupingBy(
            Map.Entry::getValue,Collectors.mapping(Map.Entry::getKey, Collectors.toList())));
    System.out.println(result);
}

}

答案 2 :(得分:0)

您始终构建一个新的List<String>来保存具有给定键的城市列表。发生在行

city = new ArrayList<String>();

将其替换为

if(segList.containsKey(next.getValue())) {
    city = segList.get(next.getValue());
} else {
    city = new ArrayList<String>();
}

并且代码应该按预期工作。

编辑:@eran更快但我离开它,因为它解释了在不那么优雅和现代的方法中所犯的错误。