需要一个Java映射/表,其中包含一个值的多个键。 价值通常会改变

我需要的是一个允许多个键访问单个对象的集合。

我需要对这个对象进行频繁的修改。

对于500k +条目,它也必须是高效的。

java.util.Map任何实现都会这样做 – 对在单独的键下添加特定值的次数没有限制

 Map m = new HashMap(); m.put("Hello", 5); m.put("World", 5); System.out.println(m); // { Hello->5, World->5 } 

如果你想要一个地图,其中一个键与多个值相关联,这称为多地图 ,您可以从google java collections API或Apache的commons-collections中获取一个

呃… …

 Map map = new HashMap(); Object someValue = new Object(); map.put(new Object(), someValue); map.put(new Object(), someValue); 

现在,地图包含两次相同的值,可通过不同的键访问。 如果这不是你想要的,你应该重新设计你的问题。 🙂

我有点不同地解释他的要求。 如果想要两个完全不同的键集来访问相同的基础值,该怎么办? 例如:

  "Hello" ------| |----> firstObject 3 ------| "Monkey" ------| |----> secondObject 72 ------| 14 -----------> thirdObject "Baseball" ------| |----> fourthObject 18 ------| 

显然有两个映射,一个用于整数键,一个用于String键,因为一个映射中的更新不会反映在另一个映射中。 假设您修改了Map ,更新了“Monkey”以映射到fifthObject。 此修改的结果是更改该映射中的Entry ,但这当然不会影响其他映射。 所以你想要的是:

  "Monkey" ------| |----> fifthObject 72 ------| 

你现实中得到的是:

  "Monkey" -----------> fifthObject 72 -----------> secondObject 

我在这种情况下做的是拥有两个并排的映射,但不是让它们说Map我会使它们成为Map ,其中关联的数组是单个成员数组。 我第一次将一个键与一个值相关联,如果还没有数组,并且该键返回null,我创建该数组,并将我想要的任何其他键与它相关联(在该键的映射中)。 随后,我只修改数组的内容,但从不引用数组本身,这就是一个魅力。

  "Monkey" -------> fifthObjectArray ------| |-----> fifthObjectArray[0] 72 -------> fifthObjectArray ------| 

可能会做你想要的:

 import java.util.*; class Value { public String toString() { return x.toString(); } Integer x=0; } public class Main { public static void main(String[] arguments) { Map m=new HashMap(); final Value v=new Value(); m.put(1,v); m.put(2,v); System.out.println(m.get(1)); System.out.println(m.get(2)); vx=42; System.out.println(m.get(1)); System.out.println(m.get(2)); } 

你的问题实际上让我想到让这堂课来处理这样的事情。 我目前正在研究2D游戏引擎,你的问题让我完全想起了我需要的东西。

顺便说一下,我相信你想要的是;

一个保存键和值的对象,但你也可以保持公共键值(我特意使用这个对象来减少cpu,但代价是只需要多一点内存。)

此类’K类型是主键类型。 T类型是HashSet值类型。

您实现和使用此对象的方式是:

 MapValueSet mainmap = new MapValueSet() HashSet tags = new HashSet(); public void test(){ ObjectType1 = new ObjectType1(); ObjectType2 = new ObjectType2(); tags.add(mainmap.put(ObjectType1,ObjectType2); mainmap.get(ObjectType1,Integer); } 

你需要在你实现它的任何类中的set或arraylist中保存唯一标记,因为如果你没有,你将存储实体而不知道哪个是哪个。 因此,将从put()方法获得的整数存储到arraylist或set中,然后迭代它。

您可以检查此Class的值(如果存在),或者将值设置为哪些关键对象。

这是Class MapValueSet;

 import java.util.HashMap; import java.util.HashSet; import java.util.Map; public class MapValueSet { Indexer indxK = new Indexer(); Indexer indxT = new Indexer(); Map kTags = new HashMap(); Map tTags = new HashMap(); Map> MapK = new HashMap>(); Map> MapT = new HashMap>(); public int put(K k, T t){ int tag = -1; if(!kTags.containsKey(k)){ kTags.put(k, indxK.getNextTag()); } if(!MapK.containsKey(kTags.get(k))){ MapK.put(kTags.get(k), new HashSet()); } if(!tTags.containsKey(t)){ tTags.put(t, tag = indxT.getNextTag()); } if(!MapT.containsKey(tTags.get(t))){ MapT.put(tag = tTags.get(t), new HashSet()); } MapK.get(kTags.get(k)).add(tTags.get(t)); MapT.get(tag = tTags.get(t)).add(kTags.get(k)); return tag; } @SuppressWarnings("unchecked") public T get(K k, int tag){ Object[] tArr = tTags.keySet().toArray(); for(int i = 0; i < tArr.length; i++){ if(tTags.get((T)tArr[i])== tag){ return (T)tArr[i]; } } return null; } public boolean removeAtKey(K k, T t){ int kTag = -1; int tTag = -1; if(kTags.get(k) != null){ kTag = kTags.get(k); } if(tTags.get(t) != null){ tTag = tTags.get(t); } if(kTag == -1 || tTag == -1){ System.out.println("Keys are Blank at: removeAtKey(k,t)"); return false; } boolean removed = false; if(MapK.get(kTag) != null){ removed = MapK.get(kTag).remove(tTag); } if(MapT.get(tTag) != null){ MapT.get(tTag).remove(kTag); } if(!MapK.containsKey(kTag)){ kTags.remove(k); indxK.removeTag(kTag); } if(MapK.containsKey(kTag)){ tTags.remove(t); indxT.removeTag(tTag); } return removed; } public void removeAtValue(T t){ if(!tTags.containsKey(t)){ return; } Object[] keyArr = MapT.get(tTags.get(t)).toArray(); for(int i = 0; i < keyArr.length; i++){ MapK.get(keyArr[i]).remove(tTags.get(t)); } indxT.removeTag(tTags.get(t)); MapT.remove(tTags.get(t)); tTags.remove(t); } public boolean mapContains(T t){ if(tTags.get(t) == null){ return false; } int tTag = tTags.get(t); return MapT.get(tTag) != null && !MapT.get(tTag).isEmpty(); } public boolean containsKey(K k){ if(kTags.get(k) == null){ return false; } return MapK.containsKey(kTags.get(k)); } public boolean keyContains(K k, T t){ if(kTags.get(k) != null && tTags.get(t) != null){ return MapK.get(kTags.get(k)).contains(tTags.get(t)); } return false; } @Override public String toString(){ String s = ""; s = s+ "Key Map: " + MapK.toString() + "\n"; s = s+ "Value Map: " + MapT.toString() + "\n"; s = s+ "KeyTag Map: " + kTags.toString() + "\n"; s = s+ "ValueTag Map: " + tTags.toString() + "\n"; s = s+ "KeyTag List: " + indxK.activeSet().toString() + "\n"; s = s+ "ValueTag List: " + indxT.activeSet().toString(); return s; } }