Java 在 Map 中设置 <Integer>
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/3867333/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Set<Integer> inside Map
提问by user433947
I have a question. First, I declared a map:
我有个问题。首先,我声明了一张地图:
Map<TwoIntClass, Set<Integer>> m = new HashMap<TwoIntClass, Set<Integer>>();
Now, I want to put stuff inside this map, something like
现在,我想把东西放在这张地图里,比如
int num = 7;
m.put(new TwoIntClass(5, 3), ?? how to put num inside Set ??);
My question is, how do I put variable num inside Set. Thanks.
我的问题是,如何将变量 num 放入 Set 中。谢谢。
采纳答案by Yanick Rochon
Like Hymanand others have suggested, you need to instantiate a concrete instance of the Set
interface (like HashSet
), add your int
values in the Set
and then put the Set
into your Map
. However, if you are using a custom class for your Map
's key, I would suggest you implement the equals()
and hashCode()
method of your TwoIntClass
class to be sure that you are not creating duplicate entries inside your Map
. For example, consider this class :
就像Hyman和其他人所建议的那样,您需要实例化Set
接口的具体实例(如HashSet
),将您的int
值添加到 中Set
,然后将Set
放入您的Map
. 但是,如果您为您Map
的密钥使用自定义类,我建议您实现类的equals()
andhashCode()
方法,TwoIntClass
以确保您不会在Map
. 例如,考虑这个类:
public class TwoIntClass {
private int i1;
private int i2;
public TwoIntClass(int i1, int i2) {
this.i1 = i1;
this.i2 = i2;
}
static public void main(String...args) {
Map<TwoIntClass, Set<Integer>> map = new HashMap<TwoIntClass, Set<Integer>>();
Set<Integer> dataset = new HashSet<Integer>();
dataset.add(1);
dataset.add(2);
TwoIntClass i1 = new TwoIntClass(5, 3);
TwoIntClass i2 = new TwoIntClass(5, 3);
map.put(i1, dataset);
map.put(i2, dataset);
System.out.println( i1.hashCode() + " = " + i2.hashCode() + " == " + i2.equals(i2) + " > map count = " + map.size() );
TwoIntClass i3 = new TwoIntClass(5, 3);
System.out.println("Looking for TwoIntClass(5,3)... " + map.containsKey(i3) );
}
}
The output for executing it is :
执行它的输出是:
1476323068 = 535746438 == false > map count = 2
Looking for TwoIntClass(5,3)... false
1476323068 = 535746438 == false > 地图计数 = 2
寻找 TwoIntClass(5,3)... false
As you see, they both are "equal" (i.e. they both are constructed with the same integers), but they are distinct objects with different hash codes, therefore create two entries in the map. This could lead into possible data corruption in your application. Moreover, executing this line : map.get(new TwoIntClass(5,3)).add(3);
will generate a NullPointerException
because the key (it's hash) does not exist in the map. So, you need to implement the equals()
and hashCode()
methods to fix this, so any TwoIntClass
constructed with the same integers will be considered equal. Something like :
如您所见,它们都是“相等的”(即它们都是用相同的整数构造的),但它们是具有不同哈希码的不同对象,因此在映射中创建了两个条目。这可能会导致您的应用程序中的数据损坏。此外,执行这一行 :map.get(new TwoIntClass(5,3)).add(3);
将生成 aNullPointerException
因为映射中不存在键(它的哈希)。因此,您需要实现equals()
和hashCode()
方法来解决此问题,因此任何TwoIntClass
使用相同整数构造的都将被视为相等。就像是 :
@Override
public boolean equals(Object obj) {
if (!(obj instanceof TwoIntClass)) {
return false;
}
TwoIntClass other = (TwoIntClass) obj;
return (other.i1 == this.i1) && (other.i2 == this.i2);
}
@Override
public int hashCode() {
//return TwoIntClass.class.hashCode() | i1 | (i2 << 16);
// better implementation based on the String class
int hash = TwoIntClass.class.hashCode();
hash = (hash * 31) + i1;
hash = (hash * 31) + i2;
return hash;
}
yields a more expected result of
产生更预期的结果
1476323071 = 1476323071 == true > map count = 1
Looking for TwoIntClass(5,3)... true
1476323071 = 1476323071 == 真 > 地图计数 = 1
寻找 TwoIntClass(5,3)... true
Of course, this hashCode()
method is oversimplistic and you may need to find a yet better construct, but the bottom line is that implementing them is what I would recommend.
当然,这个hashCode()
方法是超过简单化,您可能需要找到更好的构造,但最重要的是,我会推荐实施它们。
回答by jjnguy
You will have to create the set first, add the item, and then put the set in the map. There is no good way to initialize a set inline in Java. (This may change when java 7 comes out.)
您必须先创建集合,添加项目,然后将集合放入地图中。在 Java 中没有好的方法来初始化一个内联的集合。(当 java 7 出现时,这可能会改变。)
int num = 7;
Set<Integer> set = new HashSet<Integer>();
set.add(num);
m.put(new TwoIntClass(5, 3), set);
回答by nanda
回答by Hyman
You have to be sure that the related Set
is instantiated and inserted into the Map
before doing anything. You could use something like
在做任何事情之前,您必须确保相关项Set
已实例化并插入到 中Map
。你可以使用类似的东西
public void safeInsert(TwoIntClass tic, Integer element)
{
if (!map.contains(tic))
map.put(tic, new HashSet<Integer>());
map.get(tic).add(element);
}
Mind that you can't use directly Set
since it's an interface, so choose an actual implementation (eg. HashSet
)
请注意您不能直接使用,Set
因为它是一个接口,所以选择一个实际的实现(例如。HashSet
)
With Java8 every thing become easier:
有了 Java8,一切都变得更容易了:
map.computeIfAbsent(tic, k -> new HashSet<>()).add(element);
回答by Péter T?r?k
int num = 7;
TwoIntClass twoInts = new TwoIntClass(5, 3);
m.put(twoInts, new HashSet<Integer>());
m.get(twoInts).add(num);
回答by Michael D
Each time you want to put something in the set, you need to check if the set already exists, and create the set if it does not. ie:
每次要在集合中放入一些东西时,都需要检查该集合是否已经存在,如果不存在则创建该集合。IE:
int num = 7;
TwoIntClass twoInt = new TwoIntClass(5, 3);
Set<Integer> intSet = m.get(twoInt);
if(num == null) {
intSet = new HashSet<Integer>();
intSet.put(twoInt, intSet);
}
intSet.add(num);
There's a perfect abstraction over this in google's guava libraries called SetMultimapthat you should consider using, especially if this is a repeated pattern in your code.
谷歌的番石榴库中有一个完美的抽象,称为SetMultimap,您应该考虑使用它,特别是如果这是您的代码中的重复模式。
回答by ColinD
I'd recommend using a SetMultimapfrom Guavainstead. This saves you from having to think about creating the sets yourself.
我建议使用SetMultimap从番石榴代替。这使您不必考虑自己创建集合。
SetMultimap<TwoIntClass, Integer> multimap = HashMultimap.create();
TwoIntClass twoInts = new TwoIntClass(5, 3);
int num = 7;
multimap.put(twoInts, num);
Set<Integer> set = multimap.get(twoInts); // set contains 7
multimap.put(twoInts, 8);
multimap.put(twoInts, 9); // set now contains 7, 8 and 9