简体   繁体   English

连接两个哈希映射而不从两个映射中删除常见的entires

[英]Concatenating two hashmaps without removing common entires from both the maps

I have two hashmaps, in particular vocabs of two languages say english and german.I would like to concatenate both these map to return a single map.I tried : 我有两个哈希图,特别是两种语言的词汇表示英语和德语。我想连接这两个地图以返回单个地图。我试过:

 hashmap.putall()

But, removed some of the entries which are common in both maps and replace it by single entry only.But i want to keep both the vocabs intact just concatenate those. 但是,删除了两个地图中常见的一些条目,并仅通过单个条目替换它。但我想保持两个词汇完整只是连接它们。 Is there any method to do it? 有没有办法做到这一点? if not any other way to do. 如果不是其他任何方式。 I would prefer any methods in hashmap. 我更喜欢hashmap中的任何方法。

[EDIT] [编辑]

To make more clear, lets see two maps 为了更清楚,让我们看看两张地图

      at the 500    um die 500
      0   1   2     0   1   2

resutls into 重新进入

  at the  500 um die 500
  0   1    2   3  4   5               

You'll have to write your own custom "putAll()` method then. Something like this would work: 你必须编写自己的自定义“putAll()”方法。像这样的东西可以工作:

HashMap<String> both = new HashMap<String>(english);

for(String key : german.keySet()) {
    if(english.containsKey(key)) {
        both.put(key, english.get(key)+german.get(key));
    }
}

This first copies the English HashMap . 这首先复制英文HashMap Then puts in all the German words, concatenating if there is a duplicate key. 然后输入所有德语单词,如果有重复键则连接。 You might want some kind of separator character like a / in between so you can later extract the two. 您可能需要某种分隔符字符,如/中,这样您以后可以提取这两个字符。

There isn't anything like that in the Java main library itself, you will have to use something provided by third parties like Google Guava's Multimap , it does exactly what you want, or build something like this manually. 在Java主库本身没有类似的东西,你将不得不使用第三方提供的东西,如谷歌番石榴的Multimap ,它完全符合你的要求,或者手动构建这样的东西。

You can download the Guava library at the project's website . 您可以在项目的网站上下载Guava库。 Using a multimap is the same as using a map, as in: 使用多图与使用地图相同,如:

Multimap<String,String> both = new ArrayListMultimap <String,String>();
both.putAll( german );
both.putAll( english);

for ( Entry<String,String> entry : both.entrySet() ) {
  System.out.printf( "%s -> %s%n", entry.getKey(), entry.getValue() );
}

This code will print all key-value pairs including the ones that are present on both maps. 此代码将打印所有key-value对,包括两个映射中存在key-value对。 So, if you have me->me at both german and english they would be printed twice. 所以,如果你有me->megermanenglish他们会被打印两次。

Similar to @tskuzzy's answer 类似于@ tskuzzy的回答

Map<String, String> both = new HashMap<String, String>();

both.putAll(german);
both.putAll(english);
for (String e : english.keySet()) 
    if (german.containsKey(e))
        both.put(e, english.get(e) + german.get(e));

You cannot do that directly with any Map implementation, since in a map, each key is unique. 您不能直接使用任何Map实现,因为在地图中,每个键都是唯一的。

A possible workaround is to use Map<Key, List<Value>> , and then do the concatenation of your maps manually. 一种可能的解决方法是使用Map<Key, List<Value>> ,然后手动连接地图。 The advantage of using a List for the concatenated map, is that it will be easy to retrieve each of the individual values without any extra fiddling. 使用List作为连接映射的优点是,可以轻松地检索每个单独的值,而无需任何额外的功能。

Something like that would work: 这样的东西会起作用:

public Map<Key, List<Value>> concat(Map<Key, Value> first, Map<Key, Value> second){
    Map<Key, List<Value>> concat = new HashMap<Key, List<Value>>();
    putMulti(first, concat);
    putMulti(second, concat);
    return concat;
}

private void putMulti(Map<Key, Value> content, Map<Key, List<Value>> dest){
    for(Map.Entry<Key, Value> entry : content){
        List<Value> vals = dest.get(entry.getKey());
        if(vals == null){
            vals = new ArrayList<Value>();
            dest.put(entry.getKey(), vals);
        }
        vals.add(entry.getValue());
    }
}

Slight improvisation of @tskuzzy and @Peter's answer here. @tskuzzy和@Peter在这里的答案略有即兴。 Just define your own StrangeHashMap by extending HashMap . 只需通过扩展HashMap定义自己的StrangeHashMap

public class StrangeHashMap extends HashMap<String, String> {
    @Override
    public String put(String key, String value) {
        if(this.containsKey(key)) {
            return super.put(key, super.get(key) + value);
        } else {
            return super.put(key, value);
        }
    }
}

You can use it as so: 您可以这样使用它:

Map<String, String> map1 = new HashMap<String, String>();
map1.put("key1", "Value1");
map1.put("key2", "Value2");

Map<String, String> map2 = new HashMap<String, String>();
map2.put("key1", "Value2");
map2.put("key3", "Value3");

Map<String, String> all = new StrangeHashMap();

all.putAll(map1);
all.putAll(map2);

System.out.println(all);

The above prints the below for me: 以上为我打印如下:

{key3=Value3, key2=Value2, key1=Value1Value2}

Given the new elements in the question, it seems that what you actually need to use is lists. 鉴于问题中的新元素,您实际需要使用的是列表。 In this case, you can just do: 在这种情况下,你可以这样做:

List<String> english = ...;
List<String> german = ...;
List<String> concat = new ArrayList<String>(english.size() + german.size());
concat.addAll(english);
concat.addAll(german);

And there you are. 你有。 You can still use concat.get(n) to retreive the value nth value in the concatenated list. 您仍然可以使用concat.get(n)来检索连接列表中的第n个值。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM