6

我有这样的地图

Map map=new HashMap();//HashMap key random order.
map.put("a",10);
map.put("a",20);
map.put("a",30);
map.put("b",10);

System.out.println("There are "+map.size()+" elements in the map.");
System.out.println("Content of Map are...");
Set s=map.entrySet();
Iterator itr=s.iterator();
while(itr.hasNext())
{
    Map.Entry m=(Map.Entry)itr.next();
    System.out.println(m.getKey()+"\t"+m.getValue()+"\t"+ m.hashCode());
}

上述程序的输出是

There are 2 elements in the map.
Content of Map are...
b   10  104
a   30  127

现在我希望那个键 a 应该有多个值,比如

a 10
a 20
a 30

这样我就应该得到与 a 关联的所有值。请告知我怎样才能实现同样的目标。通过嵌套集合,我希望键 'a' 具有所有三个值。

4

6 回答 6

14

你检查过Guava Multimaps吗?

类似于 Map 的集合,但可以将多个值与单个键相关联。如果您使用相同的键但值不同的两次调用 put(K, V),则多重映射包含从键到两个值的映射。

如果您真的想使用标准集合(如下所示),则必须为每个键存储一个集合,例如

map = new HashMap<String, Collection<Integer>>();

请注意,第一次输入新键时,您必须在添加第一个值之前创建新集合(等)ListSet

于 2012-12-05T09:45:12.630 回答
4

要使用 Java 标准库实现您想要的,我会使用这样的映射:

Map<String, Collection<Integer>> multiValueMap = new HashMap<String, Collection<Integer>>();

然后你可以添加值:

multiValueMap.put("a", new ArrayList<Integer>());
multiValueMap.get("a").add(new Integer(10));
multiValueMap.get("a").add(new Integer(20));
multiValueMap.get("a").add(new Integer(30));

如果这让您感到不舒服,请考虑将此行为包装在专用类中,或使用第三方解决方案,正如其他人在此处建议的那样 ( Guava Multimap )。

于 2012-12-05T09:53:30.093 回答
2

在值部分放置一个ArrayList实例。

void addValue(Map map, Object key, Object value) {
    Object obj = map.get(key);
    List list;
    if (obj == null) {  
        list = new ArrayList<Object>();  
    } else {
        list = ((ArrayList) obj);
    }
    list.add(value);
    map.put(key, list);
}

有关更多信息,请检查

于 2012-12-05T09:46:28.123 回答
2

您不应该忽略泛型参数。你所拥有的是

Map<String, Integer> map = new HashMap<>();

如果你想自己编写解决方案,你需要

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

无论如何,首选方法是使用Guava Multimap

于 2012-12-05T09:47:29.013 回答
0

使用具有值类型的 Map 作为值列表。例如,在您的地图中,在添加条目时,您会将键作为“a”,并且您必须将其值添加为 Integer 列表,具有所有必需的值,如 1,2,3,4。

于 2012-12-05T09:46:34.633 回答
0

对于具有相同键条目的地图,使用没有意义get()。但只要您使用iterator()entrySet()这应该工作:

class HashMap<String, String> {

  Set<Entry<String, String>> entries;
  @Override
  public Set<Entry<String, String>> entrySet() {
    return entries;
  }

  @Override
  public int size() {
    return entries.size();
  }

  public String put(String key, String value) {
    if (entries == null) {
      entries = new AbstractSet<Entry<String, String>>() {

        ArrayList<Entry<String, String>> list = new ArrayList<>();
        @Override
        public Iterator<Entry<String, String>> iterator() {
          return list.iterator();
        }

        @Override
        public int size() {
          return list.size();
        }

        @Override
        public boolean add(Entry<String, String> stringStringEntry) {
          return list.add(stringStringEntry);
        }
      };
    }
    StatusHandler.MyEntry entry = new StatusHandler.MyEntry();
    entry.setKey(key);
    entry.setValue(value);
    entries.add(entry);
    return value;
  }
};

TL;DR 那么,它有什么用?这来自对 redmine-java-api 的破解,以接受基于表单参数的复杂查询:

https://stackoverflow.com/a/18358659/848072

https://github.com/albfan/RedmineJavaCLI/commit/2bc51901f2f8252525a2d2258593082979ba7122

于 2016-07-18T14:21:02.397 回答