我正在尝试在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 方法。
最佳答案
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/