我正在尝试在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方法,即如何在列表映射中插入键。需要帮助。
我能够使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方法。
答案 0 :(得分:1)
地图不能包含重复的键;每个键最多可以映射一个值。
但是你可以通过将值设为 list 字符串来解决这个问题:
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
关于每个值的多个键,你当然可以这样做,虽然我不确定它是否值得推荐。根据{{3}}:
HashMap类大致相当于Hashtable,除了它是不同步的并且允许空值。
要成功存储和检索哈希表中的对象,用作键的对象必须实现hashCode方法和equals方法。
因此虽然这适用于ArrayList<Integer>
键,但对于包含非标准类的自定义键的任何内容,除非您正确地为这些对象实现hashCode()
,否则HashMap
可能不会功能正常。
答案 1 :(得分:1)
您的类中似乎需要一些数据结构作为字段:
Map<Integer,String>
{1916062554=abc, 958031277=abc}
等get
您希望按键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);
}
}