簡體   English   中英

Java中的多對一映射

[英]Many to one mappings in Java

我試圖在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);
  }

這樣做,如果我put

  ks.put("abc") 

  ks.put("abc")

這里ks是包含上述方法的類的瞬間。

它導致了

{1916062554=abc, 958031277=abc}

但我想要的是

191602554,958031277=abc

如果我在這些鍵中的任何一個上使用get() ,它應該輸出值abc。 delete()應該刪除最新的密鑰而不會損害其他密鑰。

我想過要用

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 String,然后在所需的objectID存在時檢查與blobstring關聯的值列表。 如果是,那么我從列表中刪除該對象id並附加新映射。 有幫助嗎?

編輯2

上面給出了更新和工作的get和put方法。

Map JavaDoc說:

地圖不能包含重復的鍵; 每個鍵最多可以映射一個值。

但是你可以通過使值成為字符串列表來解決這個問題:

   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

HashMap類大致相當於Hashtable,除了它是不同步的並且允許空值。

Hashtable API

要成功存儲和檢索哈希表中的對象,用作鍵的對象必須實現hashCode方法和equals方法。

因此,雖然這可以使用ArrayList<Integer>鍵,但對於包含非標准類的自定義鍵的任何內容,除非您正確地為這些對象實現hashCode() ,否則HashMap可能無法正常運行。

您似乎需要將幾個數據結構作為類中的字段:

  • stringMap: Map<Integer,String>
    • {1916062554=abc, 958031277=abc}
    • 因為get你想要查找的關鍵項目
  • keys: Map<String,List<Integer>>
    • { "abc" = {1916062554, 958031277}
    • 因為要delete您需要按順序知道給定項目的鍵。

要添加到地圖:

 public void put(String item) {
     List<Integer> list = getOrCreateList(item,keys);
     int key = calculateKey(item,list);
     list.add(key);
     stringMap.put(key,item);
 }

 private static List<Integer> getOrCreateList(String item, Map<String,List<Integer>> map) {
     List<Integer> list = map.get(item);
     if(list == null) {
         list = new ArrayList<Integer>();
         map.put(item,list);
     }
     return list;
 }

要從地圖中獲取很容易:

 public String get(int key) {
     return stringMap.get(key);
 }

要從地圖中刪除 - 如果我正確理解您的要求 - 您需要在列表中找到與提供的密鑰對應的最新密鑰...

 public void delete(int key) {
     String item = stringMap.get(key);
     if(item == null) {
        // ... deal with
     }
     List<Integer> keys = keys.get(item);

     // lazily using methods which don't exist in the Java API
     // but which illustrate the point.
     keys.removeLast();
     if(keys.isEmpty()) {
         stringMap.remove(key);
         list.remove(item);
     }
 }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM