java - Java 中的多对一映射

标签 java dictionary hashmap mapping key-value

我正在尝试在java中构建多对一键值对。到目前为止我所管理的就是这个

  public class KeyStore {
    int i=1;
    Map<Integer,String> map1=new HashMap<Integer,String>();
    Map<String,List<Integer>> map2=new HashMap<String,List<Integer>>();

    public synchronized int put(String blobString) {
    if(map1.containsValue(blobString)){
    int r=blobString.hashCode()+i*blobString.hashCode();
    i++;
    map1.put(r, blobString);
    List<Integer> j=map2.get(blobString);
    List<Integer> k=j;
    map2.remove(blobString);
    k.add(r);
    map2.put(blobString, k);
    return r;

}
else{
    map1.put(blobString.hashCode(),blobString);
    List<Integer> x=new ArrayList<Integer>();
    x.add(blobString.hashCode());
    map2.put(blobString,x);
    return blobString.hashCode();
}
}

     public synchronized String get(int objectId) {
         return map1.get(objectId);
  }

如果我放置,它的作用是

  ks.put("abc") 

  ks.put("abc")

这里 ks 是包含上述方法的类的实例。

结果是

{1916062554=abc, 958031277=abc}

但我想要的是

191602554,958031277=abc

如果我在这些键中的任何一个上使用get(),它应该输出值abc。另外,delete() 应该删除最近的 key ,并且不会损害其他 key 。

我想到使用

Map<ArrayList<Integer>,String> keystore=new HashMap<ArrayListInteger>,String>();

但我不知道如何实现 put 方法,即如何在列表映射中插入键。需要这方面的帮助。

编辑 1

我能够使 get 和 put 方法起作用。与删除方法作斗争。写了一些类似这样的内容

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

public synchronized void delete(int objectId) {
  map1.remove(objectId);
  Iterator<Entry<String, List<Integer>>> it = map2.entrySet().iterator();
 loop1: while (it.hasNext()) {
        @SuppressWarnings("rawtypes")
        Map.Entry pairs = (Map.Entry)it.next();
        @SuppressWarnings("unchecked")
        List<Integer> z=(List<Integer>) pairs.getValue();
         if(z.contains(objectId)){
             //System.out.println(z.size());
             String key=(String) pairs.getKey();
             System.out.println(z+" "+key);
            if(z.size()==1){
                map2.remove(key);
                break loop1;
            }
            else{
                z.remove(objectId);
                map2.remove(key);
                map2.put(key, z);
                break loop1;
            }
        }
  }
  }

基本上map1包含映射

123=>abc,456=>abc

并且map2包含

abc=>[123,456]

我收到 arrayindexoutofbound 异常。我在删除方法中尝试的是迭代每个 blob 字符串,然后检查与 blob 字符串关联的值列表是否存在所需的 objectID。如果是,那么我从列表中删除该对象 ID 并附加新的映射。有什么帮助吗?

编辑2

上面给出了更新且有效的 get 和 put 方法。

最佳答案

Map JavaDoc说:

A map cannot contain duplicate keys; each key can map to at most one value.

但是您可以通过将值设置为字符串列表来解决此问题:

   import  java.util.ArrayList;
   import  java.util.HashMap;
   import  java.util.Iterator;
   import  java.util.List;
   import  java.util.Map;
   import  java.util.Set;

/**
   <P>{@code java MultiValueHashMap}</P>
 **/
public class MultiValueHashMap  {
   public static final void main(String[] ignored)  {
      Map<Integer,List<String>> mapOfIntStrs = new HashMap<Integer,List<String>>();

      //Add elements
         addStringToMap(mapOfIntStrs, 1, "one");
         addStringToMap(mapOfIntStrs, 1, "two");
         addStringToMap(mapOfIntStrs, 1, "three");
         addStringToMap(mapOfIntStrs, 2, "four");
         addStringToMap(mapOfIntStrs, 2, "five");

      //Output 
         Set<Integer> keyNumSet = mapOfIntStrs.keySet();
         Iterator<Integer> keyNumItr = keyNumSet.iterator();
         while(keyNumItr.hasNext())  {
            Integer keyNum = keyNumItr.next();
            List<String> strList = mapOfIntStrs.get(keyNum);
            System.out.println(keyNum);
            for(String s : strList)  {
               System.out.println("  " + s);
            }
         }
   }
   private static final void addStringToMap(Map<Integer,List<String>> mapTo_addTo, int keyNum, String value)  {
      if(mapTo_addTo.containsKey(keyNum))  {
         mapTo_addTo.get(keyNum).add(value);
      }  else  {
         List<String> strList = new ArrayList<String>();
         strList.add(value);
         mapTo_addTo.put(keyNum, strList);
      }
   }

}

输出:

[C:\java_code\]java MultiValueHashMap
1
  one
  two
  three
2
  four
  five
<小时/>

关于每个值有多个键,您当然可以这样做,尽管我不确定是否建议这样做。根据 HashMap API :

The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.

还有 Hashtable API :

To successfully store and retrieve objects from a hashtable, the objects used as keys must implement the hashCode method and the equals method.

虽然这适用于 ArrayList<Integer>键,对于任何具有自定义键、包含非标准类的东西,除非您正确实现 hashCode()对于这些对象,HashMap可能无法正常运行。

关于java - Java 中的多对一映射,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22203083/

相关文章:

java - 具有键和值类型之间关系的对象映射

java - HashMap、Arraylist 和带有标题的列表编码到 OMElement 作为 webservice wsdl 中的响应?

java - Java HashMap 的 Eclipse 警告

java - 如何在使用maven构建的Java项目中编译spark-testing-base?

Java REST 响应值缺少拼写字符

java - 从负载均衡器后面的多个服务器清除缓存

java - 使用现有的 HashMap 创建 HashMap

java - 您是否需要自定义适配器来将不同的 subview 添加到 ListView

python - 按键排序字典 - 解包错误

javascript - 与普通对象类似地访问 JavaScript 映射