Java 如何创建多重贴图<;K、 V>;从地图<;K、 收藏<;V>>;?

Java 如何创建多重贴图<;K、 V>;从地图<;K、 收藏<;V>>;?,java,guava,multimap,Java,Guava,Multimap,我没有发现这样的多重地图结构。。。当我想这样做的时候,我在地图上迭代,并填充多重地图。还有别的办法吗 final Map<String, Collection<String>> map = ImmutableMap.<String, Collection<String>>of( "1", Arrays.asList("a", "b", "c", "c")); System.out.println(Multimaps.forM

我没有发现这样的多重地图结构。。。当我想这样做的时候,我在地图上迭代,并填充多重地图。还有别的办法吗

final Map<String, Collection<String>> map = ImmutableMap.<String, Collection<String>>of(
            "1", Arrays.asList("a", "b", "c", "c"));
System.out.println(Multimaps.forMap(map));

final Multimap<String, String> expected = ArrayListMultimap.create();
for (Map.Entry<String, Collection<String>> entry : map.entrySet()) {
    expected.putAll(entry.getKey(), entry.getValue());
}
System.out.println(expected);
final Map=ImmutableMap.of(
“1”,数组.asList(“a”、“b”、“c”、“c”);
System.out.println(Multimaps.forMap(map));
应为final Multimap=ArrayListMultimap.create();
对于(Map.Entry:Map.entrySet()){
应为.putAll(entry.getKey(),entry.getValue());
}
System.out.println(预期);

第一个结果是
{1=[[a,b,c,c]]}
,但我希望
{1=[a,b,c,c]}

更新:对于你所要求的,我认为你需要回过头来。

假设你有

Map<String, Collection<String>> map = ...;
Multimap<String, String> multimap = ArrayListMultimap.create();
或者更优化,但更难阅读

for (Entry<String, Collection<String>> entry : map.entrySet()) {
  multimap.putAll(entry.getKey(), entry.getValue());
}
for(条目:map.entrySet()){
multimap.putAll(entry.getKey(),entry.getValue());
}

这是我为我的班级编写的一个有用的通用版本

/**
*使用输入贴图创建番石榴多重贴图。
*/
公共静态多重映射createMultiMap(映射输入){
Multimap Multimap=ArrayListMultimap.create();
for(Map.Entry:input.entrySet()){
multimap.putAll(entry.getKey(),entry.getValue());
}
返回多重映射;
}
和一个不变的版本:

/**
 * Creates an Immutable Guava multimap using the input map.
 */
public static <K, V> ImmutableMultimap<K, V> createImmutableMultiMap(Map<K, ? extends Iterable<V>> input) {
  ImmutableMultimap.Builder<K, V> builder = ImmutableMultimap.builder();
  for (Map.Entry<K, ? extends Iterable<V>> entry : input.entrySet()) {
    builder.putAll(entry.getKey(), entry.getValue());
  }
  return builder.build();
}
/**
*使用输入映射创建不可变的Guava多重映射。
*/
公共静态ImmutableMultimap createImmutableMultiMap(映射输入){
ImmutableMultimap.Builder=ImmutableMultimap.Builder();
for(Map.Entry:input.entrySet()){
builder.putAll(entry.getKey(),entry.getValue());
}
返回builder.build();
}

以下代码没有Google的Guava库。它用于双值键和排序顺序

Map<Double,List<Object>> multiMap = new TreeMap<Double,List<Object>>();

for( int i= 0;i<15;i++)
{
    List<Object> myClassList = multiMap.get((double)i);
    if(myClassList == null)
    {
        myClassList = new ArrayList<Object>();
        multiMap.put((double) i,myClassList);
    }
    myClassList.add("Value "+ i);
}

List<Object> myClassList = multiMap.get((double)0);
if(myClassList == null)
{
    myClassList = new ArrayList<Object>();
    multiMap.put( (double) 0,myClassList);
}
myClassList.add("Value Duplicate");
for (Map.Entry entry : multiMap.entrySet()) 
{
  System.out.println("Key = " + entry.getKey() + ", Value = " +entry.getValue());
}
Map multiMap=newtreemap();

对于(inti=0;i这个问题有点老了,但我想我应该给出一个更新的答案

ListMultimap<String, String> multimap = ArrayListMultimap.create();
Map<String, Collection<String>> map = ImmutableMap.of(
                           "1", Arrays.asList("a", "b", "c", "c"));
map.forEach(multimap::putAll);
System.out.println(multimap);
ListMultimap multimap=ArrayListMultimap.create();
Map Map=ImmutableMap.of(
“1”,数组.asList(“a”、“b”、“c”、“c”);
forEach(multimap::putAll);
System.out.println(多重映射);
这将根据需要为您提供
{1=[a,b,c,c]}

LinkedListMultimap mm=map.entrySet()
LinkedListMultimap<String, String> mm = map.entrySet()
    .stream()
    .collect(
        () -> LinkedListMultimap.create(map.size()),
        (m, e) -> m.putAll(e.getKey(), e.getValue()),
        (m1, m2) -> m1.putAll(m2));
.stream() .收集( ()->LinkedListMultimap.create(map.size()), (m,e)->m.putAll(e.getKey(),e.getValue()), (m1,m2)->m1.putAll(m2));
还有另一种方法可以使用:

如果您使用的是扩展
列表
集合
,文档建议使用特殊方法和

Multimaps.newListMultimap(myMap,ArrayList::new);
newSetMultimap(myMap,HashSet::new);

您可以使用
com.google.common.collect.Multimaps.flatingtomultimap
作为流收集器。

给定地图:

Map Map=Map.of(
第1条(“a”、“b”、“c”)的清单,
第2条(d、e、f)项清单;
您可以执行以下操作:

Multimap Multimap=map.entrySet().stream()
.collect(flattingtomultimap(Map.Entry::getKey,it->it.getValue().stream(),HashMultimap::create));

谢谢,但当我问这个问题时,我已经尝试了这个类的一些函数…以及其他方法…但对我来说唯一有效的方法是在地图上迭代…@Sylvian:既然你标记了这个答案已被接受,这是否意味着你的问题现在实际解决了?看起来好像没有,因为你没有以任何方式提及。只是想知道,如果其他人发布更详细/合适的答案,那将是浪费时间。
Multimaps.newMultimap(map,new Supplier(){public List get(){return new ArrayList();}}});
它在Multimaps.newMultimap()之后就不起作用了首先需要一个空映射argument@MarkPeters是的,这套方法上的Javadoc可能需要一些帮助。这个要求应该在param文档上,而不仅仅是在exception文档中。这正是我所做的!请注意,正如Kevin在这里指出的那样,Multimap是一个Map,如果在原始Map中,有一个空的iterable作为v值,则不会将条目“”添加到Multimap中。Multimap创建是为我使用的:Multimap Multimap=ArrayListMultimap.create();它适用于所有Multimap know实现的类。我离开java world有一段时间了,但始终保持与新语法的联系是很好的。它消除了一些噪音,我喜欢它。感谢您的更新。也许@kevin bourrillion可以用这个语法更新他的答案。这些语法有些不灵活,因为它们迫使您使用一个特殊的多重映射实现。@Michael-Hmm我无法想象有多少事情比在互联网上发布的免费开源代码片段更缺乏灵活性:)@DanielAlexiuc-Hehe。这不是我说的那种僵硬。如果您在整个代码中使用了第一个函数,然后在其中一半的情况下需要更改返回的
Multimap
的类型,那么您将面临一场维护噩梦。我认为,通过一个参数传递一个
Multimap
是一个更好的设计。
ListMultimap<String, String> multimap = ArrayListMultimap.create();
Map<String, Collection<String>> map = ImmutableMap.of(
                           "1", Arrays.asList("a", "b", "c", "c"));
map.forEach(multimap::putAll);
System.out.println(multimap);
LinkedListMultimap<String, String> mm = map.entrySet()
    .stream()
    .collect(
        () -> LinkedListMultimap.create(map.size()),
        (m, e) -> m.putAll(e.getKey(), e.getValue()),
        (m1, m2) -> m1.putAll(m2));