Java 具有多个键的映射
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/19176951/
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
Map with multiple keys
提问by xyz
I am trying to implement a map like
我正在尝试实现一个像
Map<<key1, key2>, List<value>>
Map should contain 2 keys and corresponding value would be a list. I want to add records in same list if alteast one key value is equalFor example consider following records
Map 应包含 2 个键,相应的值将是一个列表。如果 alteast 一个键值相等,我想在同一个列表中添加记录 例如考虑以下记录
R1[key1, key2]
R2[key1, null/empty] - Key1 is equal
R3[null/empty, key2] - Key2 is equal
R4[key1, key2] - Key1 and Key2 both are equal.
all should be inserted in same list like
所有都应该插入到同一个列表中
Key = <Key1,Key2>
Value = <R1, R2, R3, R4>
I cant use Guava tableor commons MulitKeyMap(dont want include whole library just for this) .
我不能使用Guava table或commons MulitKeyMap(不想为此包含整个库)。
I tried to implement a class (which I can use as a key) which will have both key1
and key2
as attribute but implementing a effective hashcode which don't consider key1 and key2 seems bit (or may be a lot) tricky
我试图实现一个类(我可以将其用作键),它将同时具有key1
和key2
作为属性,但是实现一个不考虑 key1 和 key2 的有效哈希码似乎有点(或可能很多)棘手
public class Key {
private int key1;
private int key2;
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
// Cant include key1 and key2 in hashcode
/* result = prime * result + key1;
result = prime * result + key2;*/
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Key other = (Key) obj;
if(key2 and other.key2 both not blank/null){ // pseudo code
if (key2 == other.key2)
return true;
}
if(key1 and other.key1 both not blank/null){ //pseudo code
if (key1 == other.key1)
return true;
}
return true;
}
}
It will work if I use the same hashcode for all but it will impact the performance as I have thousands of records.
如果我对所有人使用相同的哈希码,它将起作用,但它会影响性能,因为我有数千条记录。
EDIT :
I cant use nested Mapslike
编辑:
我不能使用嵌套的地图状
Map<key1, Map< key2, List<value>>>
As some records might have only one key.
因为有些记录可能只有一个键。
R1[key1, key2] - Have both keys
R2[key1, null/empty] - Key1 is equal
R3[null/empty, key2] - Key1 is missing and key2 is equal
Here R3 dont have key1 and hence cant be inserted in same location as R1 and R2
这里 R3 没有 key1,因此不能插入与 R1 和 R2 相同的位置
EDIT 2 :
编辑 2:
I also wish to maintain the intertion order.
我也希望保持intertion秩序。
采纳答案by tom
Use a TreeMap instead, this way you can make use a custom comparator for your CustomKey class instead of a Hashcode.
改用 TreeMap,这样您就可以为 CustomKey 类使用自定义比较器,而不是哈希码。
TreeMap<CustomKey, List<value>> map = new TreeMap<CustomKey, List<value>>(myComparator);
eta: instead of creating a comparator class you can make the CustomKey class implement Comparable
eta:您可以让 CustomKey 类实现 Comparable,而不是创建比较器类
回答by GordonM
Maps by definition have 1 key per value.
根据定义,映射每个值有 1 个键。
You could have a map of maps, or your key could be an object with 2 fields, but that's about as close as you can get.
你可以有一张地图,或者你的键可以是一个有 2 个字段的对象,但这是尽可能接近的。
Map of maps:
地图地图:
Map myMap<key, Map<otherkey, value>>
Custom object
自定义对象
public class MapKey {
public Object keyFirstPart;
public Object keySecondPart;
// You'll need to implement equals, hashcode, etc
}
Map myyMap <MapKey, value>
回答by SJuan76
Create another Map
that holds the relationship key->intermediateKey. The intermediate key may be a GUID or something else that is automatically generated and guaranteed to be unique.
创建另一个Map
持有关系 key->intermediateKey 的。中间密钥可以是 GUID 或其他自动生成并保证唯一的东西。
Map<String, GUID> first = new HashMap<String, GUID>();
first.put(key1, guid1);
first.put(key2, guid1);
Map<GUID, ValueType> second = new HashMap<GUID, ValueType>();
second.put(guid1, value1);
Alternatively (although I find it far more complicated, and less flexible), you could play with the keys. If key1.equals(key2)
(and, consequently, key2.equals(key1)
&& (key1.hashCode() == key2.hashCode) then
Map.get(key1)will return the same value than
Map.get(key2)`.
或者(虽然我发现它更复杂,更不灵活),您可以使用按键。If key1.equals(key2)
(and, 因此,key2.equals(key1)
&& (key1.hashCode() == key2.hashCode ) then
Map.get(key1) will return the same value than
Map.get(key2)`。
回答by CHowdappaM
Check hash code of key1 only, if it matches, then we test in equals method anyways.
只检查 key1 的哈希码,如果匹配,那么我们无论如何都在 equals 方法中进行测试。
@Override
public int hashCode() {
return key1.hashCode();
}
@Override
public boolean equals(Object obj) {
Key k = (Key)obj;
// Generic equals code goes here
if(this.key1.equals(k.key1) && this.key2.equals(k.key2) )
return true;
return false;
}
回答by ppeterka
If the HashMap like behaviour is required, I'd create two Maps, and do the magic in handling the collections (also, I'd recommend using Sets for this...):
如果需要类似 HashMap 的行为,我将创建两个 Maps,并在处理集合时发挥作用(此外,我建议为此使用 Sets...):
public class MyMap<K1, K2, V> {
Map<K1, Collection<V>> map1;
Map<K2, Collection<V>> map2;
//have to add to both lists
put(K1 k1, K2 k2, V v) {
addToCollection(map1, k1, v);
addToCollection(map2, k2, v);
}
//notice T param
<T> void addToCollection(Map<T, Collection<V>> map, T key, V value ) {
Collection<V> collection= map.get(key);
if(collection==null) {
collection= new HashSet<V>();
map.put(key, collection);
}
collection.add(value );
}
public Collection<V> get(K1 k1, K2 k2) {
Collection<V> toReturn = new HashSet<V>();
Collection<V> coll1 = map1.get(k1);
if(coll1!=null) {
toReturn.addAll(coll1);
}
Collection<V> coll2 = map2.get(k2);
if(coll2!=null) {
toReturn.addAll(coll2);
}
return toReturn;
}
}
回答by A4L
Basically the idea to achieve this is to map the keys by the value itself.
基本上实现这一点的想法是通过值本身映射键。
So you could have an internal map which does this (here I have a set of keys instead of just 2).
所以你可以有一个内部映射来做到这一点(这里我有一组键而不是只有 2 个)。
Map<V, Set<K>> keySetMap = new HashMap<V, Set<K>>();
So your Map
implementation could look something like this:
所以你的Map
实现可能是这样的:
public class MultiKeyMap<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 1L;
private Map<V, Set<K>> keySetMap = new HashMap<V, Set<K>>();
@Override
public V put(K key, V value) {
V v = null;
Set<K> keySet = keySetMap.get(value);
if(keySet == null) {
keySet = new LinkedHashSet<K>();
keySetMap.put(value, keySet);
}
keySet.add(key);
v = super.put(key, value);
// update the old keys to reference the new value
Set<K> oldKeySet = keySetMap.get(v);
if(oldKeySet != null) {
for(K k : oldKeySet) {
super.put(k, value);
}
}
return v;
}
}
This works fine for simple (immutable) Objects:
这适用于简单(不可变)对象:
@Test
public void multiKeyMapString() {
MultiKeyMap<String, String> m = new MultiKeyMap<String, String>();
m.put("1", "A");
m.put("2", "B");
for(Entry<String, String> e : m.entrySet()) {
System.out.println("K=" + e.getKey() + ", V=" + e.getValue().toString());
}
m.put("3", "A");
System.out.println("----");
for(Entry<String, String> e : m.entrySet()) {
System.out.println("K=" + e.getKey() + ", V=" + e.getValue().toString());
}
m.put("4", "C");
System.out.println("----");
for(Entry<String, String> e : m.entrySet()) {
System.out.println("K=" + e.getKey() + ", V=" + e.getValue().toString());
}
m.put("3", "D");
System.out.println("----");
for(Entry<String, String> e : m.entrySet()) {
System.out.println("K=" + e.getKey() + ", V=" + e.getValue().toString());
}
System.out.println("----");
System.out.println("values=" + m.values());
System.out.println();
System.out.println();
}
with the the test above, the output would look like
通过上面的测试,输出看起来像
K=1, V=A
K=2, V=B
----
K=1, V=A
K=2, V=B
K=3, V=A
----
K=1, V=A
K=2, V=B
K=3, V=A
K=4, V=C
----
K=1, V=D
K=2, V=B
K=3, V=D
K=4, V=C
----
values=[D, B, C]
As you see in last output, the key 1
now maps the value D
because the value previously mapped by 3
was the same as the one mapped by 1
in the step before.
正如您在上一个输出中看到的那样,键1
现在映射了值,D
因为之前映射的值与之前步骤中映射的值3
相同1
。
But it gets tricky when you want to put a list (or any mutable object) in your map, because if you change the list (add/remove an element) then the list will have another hashCode
as the one used to map the previous keys:
但是当你想在你的地图中放置一个列表(或任何可变对象)时,它会变得棘手,因为如果你更改列表(添加/删除一个元素),那么列表将有另一个hashCode
用于映射先前键的列表:
@Test
public void multiKeyMapList() {
List<String> l = new ArrayList<String>();
l.add("foo");
l.add("bar");
MultiKeyMap<String, List<String>> m = new MultiKeyMap<String, List<String>>();
m.put("1", l);
m.put("2", l);
for(Entry<String, List<String>> e : m.entrySet()) {
System.out.println("K=" + e.getKey() + ", V=" + e.getValue().toString());
}
m.get("1").add("foobar");
m.put("3", l);
System.out.println("----");
for(Entry<String, List<String>> e : m.entrySet()) {
System.out.println("K=" + e.getKey() + ", V=" + e.getValue().toString());
}
l = new ArrayList<String>();
l.add("bla");
m.put("4", l);
System.out.println("----");
for(Entry<String, List<String>> e : m.entrySet()) {
System.out.println("K=" + e.getKey() + ", V=" + e.getValue().toString());
}
m.put("3", l);
System.out.println("----");
for(Entry<String, List<String>> e : m.entrySet()) {
System.out.println("K=" + e.getKey() + ", V=" + e.getValue().toString());
}
System.out.println("----");
System.out.println("values=" + m.values());
}
The test above will output something like this:
上面的测试将输出如下内容:
K=1, V=[foo, bar]
K=2, V=[foo, bar]
----
K=1, V=[foo, bar, foobar]
K=2, V=[foo, bar, foobar]
K=3, V=[foo, bar, foobar]
----
K=1, V=[foo, bar, foobar]
K=2, V=[foo, bar, foobar]
K=3, V=[foo, bar, foobar]
K=4, V=[bla]
----
K=1, V=[foo, bar, foobar]
K=2, V=[foo, bar, foobar]
K=3, V=[bla]
K=4, V=[bla]
----
values=[[foo, bar, foobar], [bla]]
As you see the value mapped by 1
and 2
has not been updated, after only the key 3
is turned to map another value. The reason is that the hashCode
resultng from [foo, bar]
is different from the one of [foo, bar, foobar]
which causes Map#get
to not return the correct result. To get over this you need to get set of keys by comparing to the actual value.
如您所见,映射的值1
并2
没有更新,只有在将键3
转换为映射另一个值之后。原因是产生的hashCode
结果[foo, bar]
不同于[foo, bar, foobar]
导致Map#get
不返回正确结果的原因之一。要解决这个问题,您需要通过与实际值进行比较来获取一组键。
public class MultiKeyMap<K, V> extends LinkedHashMap<K, V> {
private static final long serialVersionUID = 1L;
private Map<V, Set<K>> keySetMap = new HashMap<V, Set<K>>();
@Override
public V put(K key, V value) {
V v = null;
Set<K> keySet = keySetMap.get(value);
if (keySet == null) {
keySet = new LinkedHashSet<K>();
keySetMap.put(value, keySet);
}
keySet.add(key);
v = super.put(key, value);
// update the old keys to reference the new value
for (K k : getKeySetByValue(v)) {
super.put(k, value);
}
return v;
}
@Override
public Collection<V> values() {
// distinct values
return new LinkedHashSet<V>(super.values());
}
private Set<K> getKeySetByValue(V v) {
Set<K> set = null;
if (v != null) {
for (Map.Entry<V, Set<K>> e : keySetMap.entrySet()) {
if (v.equals(e.getKey())) {
set = e.getValue();
break;
}
}
}
return set == null ? Collections.<K> emptySet() : set;
}
}
Now running both test again gives the following output:
现在再次运行这两个测试会给出以下输出:
For simple (immutable) Objects
对于简单(不可变)对象
K=1, V=A
K=2, V=B
----
K=1, V=A
K=2, V=B
K=3, V=A
----
K=1, V=A
K=2, V=B
K=3, V=A
K=4, V=C
----
K=1, V=D
K=2, V=B
K=3, V=D
K=4, V=C
----
values=[D, B, C]
For object that can change
对于可以改变的对象
K=1, V=[foo, bar]
K=2, V=[foo, bar]
----
K=1, V=[foo, bar, foobar]
K=2, V=[foo, bar, foobar]
K=3, V=[foo, bar, foobar]
----
K=1, V=[foo, bar, foobar]
K=2, V=[foo, bar, foobar]
K=3, V=[foo, bar, foobar]
K=4, V=[bla]
----
K=1, V=[bla]
K=2, V=[bla]
K=3, V=[bla]
K=4, V=[bla]
----
values=[[bla]]
I hope this helps you find a way to implement your Map. You could instead of extending an existing implementation implement the Map
interface so that you can provide an implentation for all it's methods with respect to their contracts and have the implementation of your choice as a member to handle the actual mapping.
我希望这可以帮助您找到实现 Map 的方法。您可以不扩展现有的实现来实现Map
接口,这样您就可以为所有它的方法提供与它们的契约相关的实现,并拥有您选择的实现作为处理实际映射的成员。
回答by ASD
Try this....
尝试这个....
Create a class for the key to the Map
为 Map 的键创建一个类
public class MapKey {
private Object key1;
private Object key2;
@Override
public boolean equals(Object object) {
boolean equals = false;
if (((MapKey) object).key1 == null && ((MapKey) object).key2 == null) {
equals = true;
}
if (((MapKey) object).key1.equals(this.key1) && ((MapKey) object).key2.equals(this.key2)) {
equals = true;
}
if (((MapKey) object).key1 == null && ((MapKey) object).key2.equals(this.key2)) {
equals = true;
}
if (((MapKey) object).key1.equals(this.key1) && ((MapKey) object).key2 == null) {
equals = true;
}
return equals;
}
@Override
public int hashCode() {
return 1;
}
public Object getKey1() {
return key1;
}
public void setKey1(Object key1) {
this.key1 = key1;
}
public Object getKey2() {
return key2;
}
public void setKey2(Object key2) {
this.key2 = key2;
}
}
In the above class you can modify the DataTypes of key1 and key2 as required. Here's the main class that will execute the required logic
在上面的类中,您可以根据需要修改 key1 和 key2 的 DataType。这是将执行所需逻辑的主类
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MapWithTwoKeys {
private static final Map<MapKey, List<Object>> mapWithTwoKeys = new HashMap<MapKey, List<Object>>();
public static void main(String[] args) {
// Create first map entry with key <A,B>.
MapKey mapKey1 = new MapKey();
mapKey1.setKey1("A");
mapKey1.setKey2("B");
List<Object> list1 = new ArrayList<Object>();
list1.add("List1 Entry");
put(mapKey1, list1);
// Create second map entry with key <A,B>, append value.
MapKey mapKey2 = new MapKey();
mapKey2.setKey1("A");
mapKey2.setKey2("B");
List<Object> list2 = new ArrayList<Object>();
list2.add("List2 Entry");
put(mapKey2, list2);
// Create third map entry with key <A,>.
MapKey mapKey3 = new MapKey();
mapKey3.setKey1("A");
mapKey3.setKey2("");
List<Object> list3 = new ArrayList<Object>();
list3.add("List3 Entry");
put(mapKey3, list3);
// Create forth map entry with key <,>.
MapKey mapKey4 = new MapKey();
mapKey4.setKey1("");
mapKey4.setKey2("");
List<Object> list4 = new ArrayList<Object>();
list4.add("List4 Entry");
put(mapKey4, list4);
// Create forth map entry with key <,B>.
MapKey mapKey5 = new MapKey();
mapKey5.setKey1("");
mapKey5.setKey2("B");
List<Object> list5 = new ArrayList<Object>();
list5.add("List5 Entry");
put(mapKey5, list5);
for (Map.Entry<MapKey, List<Object>> entry : mapWithTwoKeys.entrySet()) {
System.out.println("MapKey Key: <" + entry.getKey().getKey1() + ","
+ entry.getKey().getKey2() + ">");
System.out.println("Value: " + entry.getValue());
System.out.println("---------------------------------------");
}
}
/**
* Custom put method for the map.
* @param mapKey2 (MapKey... the key object of the Map).
* @param list (List of Object... the value of the Map).
*/
private static void put(MapKey mapKey2, List<Object> list) {
if (mapWithTwoKeys.get(mapKey2) == null) {
mapWithTwoKeys.put(mapKey2, new ArrayList<Object>());
}
mapWithTwoKeys.get(mapKey2).add(list);
}
}
The code is pretty straight forward and simple to understand. Let me know if this satisfies your requirement.
代码非常简单,易于理解。让我知道这是否满足您的要求。
回答by Sunil Chavan
I think below solution would work for you - I have used MyKey.javaobject as key of the HashMap. It contains the both keys and hash code. Hash code will be used to identify list of values for different set of combination of the keys you have listed in the question. This hash code is generated when you first register both keys. It is stored against each key so that even if either of the key is null you will get same hash code.
我认为以下解决方案对您有用- 我使用MyKey.java对象作为 HashMap 的键。它包含键和哈希码。哈希码将用于识别您在问题中列出的不同键组合的值列表。当您第一次注册两个密钥时会生成此哈希码。它针对每个键存储,因此即使其中一个键为空,您也将获得相同的哈希码。
MultiKeyMap.java=>Extends the HashMap and overrides 'put' and 'get' method. populateHashKey() - This method will generate/return same hash code for different combination of the keys you want.
MultiKeyMap.java=> 扩展 HashMap 并覆盖 'put' 和 'get' 方法。populateHashKey() - 此方法将为您想要的不同键组合生成/返回相同的哈希码。
NOTE: Insertion order is maintained by the Arraylist. Also all values for each key combination will be stored in same List in Map.
注意:插入顺序由 Arraylist 维护。此外,每个组合键的所有值都将存储在 Map 中的同一个 List 中。
package test.map;
public class MyKey {
private String myKey1;
private String myKey2;
private int hashKey;
public MyKey(String key1, String key2) {
this.myKey1 = key1;
this.myKey2 = key2;
}
/**
* @return the myKey1
*/
public String getMyKey1() {
return this.myKey1;
}
/**
* @param tmpMyKey1 the myKey1 to set
*/
public void setMyKey1(String tmpMyKey1) {
this.myKey1 = tmpMyKey1;
}
/**
* @return the myKey2
*/
public String getMyKey2() {
return this.myKey2;
}
/**
* @param tmpMyKey2 the myKey2 to set
*/
public void setMyKey2(String tmpMyKey2) {
this.myKey2 = tmpMyKey2;
}
/**
* Returns the hash key.
*/
@Override
public int hashCode() {
return this.hashKey;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
MyKey other = (MyKey) obj;
if(checkEqual(this.myKey1, other.myKey1)
|| checkEqual(this.myKey2, other.myKey2)) {
return true;
}
return false;
}
/*
* Checks whether key1 equals key2.
*/
private boolean checkEqual(String key1, String key2) {
if(key1 != null && key2 != null) {
return key1.equals(key2);
}
return false;
}
/**
* @return the hashKey
*/
public int getHashKey() {
return this.hashKey;
}
/**
* @param tmpHashKey the hashKey to set
*/
public void setHashKey(int tmpHashKey) {
this.hashKey = tmpHashKey;
}
}
MultiKeyMap.java -
MultiKeyMap.java -
package test.map;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class MultiKeyMap extends HashMap<MyKey, List<String>>{
private static final long serialVersionUID = 3523468186955908397L;
Map<String, Integer> hashKeyMap = new HashMap<String, Integer>();
/*
* Adds single value in the List of values against the key
*/
public List<String> addValue(MyKey tmpKey, String tmpValue) {
populateHashKey(tmpKey);
List<String> orgValue = null;
if(tmpKey.getHashKey() != -1) {
orgValue = super.get(tmpKey);
if(orgValue == null) {
orgValue = new ArrayList<String>();
super.put(tmpKey, orgValue);
}
orgValue.add(tmpValue);
}
return orgValue;
}
@Override
public List<String> put(MyKey tmpKey, List<String> tmpValue) {
populateHashKey(tmpKey);
List<String> orgValue = null;
if(tmpKey.getHashKey() != -1) {
orgValue = super.get(tmpKey);
if(orgValue == null) {
orgValue = new ArrayList<String>();
super.put(tmpKey, orgValue);
}
orgValue.addAll(tmpValue);
}
return orgValue;
}
@Override
public List<String> get(Object tmpKey) {
if(!(tmpKey instanceof MyKey)) {
return null;
}
MyKey key = (MyKey) tmpKey;
populateHashKey(key);
return super.get(key);
}
/**
* Populates the hashKey generated for the MyKey combination. If the both Key1 and Key 2 are not null and its hash key is not generated
* earlier then it will generate the hash key using both keys and stores it in class level map 'hashKeyMap' against both keys.
* @param tmpKey
*/
public void populateHashKey(MyKey tmpKey) {
int hashKey = -1;
if(tmpKey.getMyKey1() != null && this.hashKeyMap.containsKey(tmpKey.getMyKey1()+"_")) {
hashKey = this.hashKeyMap.get(tmpKey.getMyKey1()+"_");
} else if(tmpKey.getMyKey2() != null && this.hashKeyMap.containsKey("_"+tmpKey.getMyKey2())) {
hashKey = this.hashKeyMap.get("_"+tmpKey.getMyKey2());
}
/*
* Assumption - While insertion you will always add first value with Key1 and Key2 both as not null. Hash key will be build only
* when both keys are not null and its not generated earlier.
*/
if(hashKey == -1 && tmpKey.getMyKey1() != null && tmpKey.getMyKey2() != null) {
hashKey = buildHashKey(tmpKey);
this.hashKeyMap.put(tmpKey.getMyKey1()+"_", hashKey);
this.hashKeyMap.put("_"+tmpKey.getMyKey2(), hashKey);
}
tmpKey.setHashKey(hashKey);
}
public int buildHashKey(MyKey tmpKey) {
final int prime = 31;
int result = 1;
result = prime * result + ((tmpKey.getMyKey1() == null) ? 0 : tmpKey.getMyKey1().hashCode());
result = prime * result + ((tmpKey.getMyKey1() == null) ? 0 : tmpKey.getMyKey1().hashCode());
return result;
}
}
Test class -
测试班——
import test.map.MultiKeyMap;
import test.map.MyKey;
public class TestMultiKeyMap {
public static void main(String[] args) {
System.out.println("=====Add values for each type of key==========");
MyKey regKey = new MyKey("Key1", "Key2");
MultiKeyMap myMap = new MultiKeyMap();
//Register the MyKey having both keys as NOT null.
System.out.println("Entry 1:"+myMap.addValue(regKey, "Key Reg"));
MyKey key1 = new MyKey("Key1", null);
//Add value against MyKey with only Key2
System.out.println("Entry 2:"+myMap.addValue(key1, "Key1"));
MyKey key2 = new MyKey(null, "Key2");
//Add value against MyKey with only Key1
System.out.println("Entry 3:"+myMap.addValue(key2, "Key2"));
MyKey bothKey = new MyKey("Key1", "Key2");
//Add value against MyKey with only Key1
System.out.println("Entry 4:"+myMap.addValue(bothKey, "both keys"));
System.out.println("=====Retrieve values for each type of key==========");
MyKey getKey1 = new MyKey("Key1", null);
System.out.println("Values for Key1:"+myMap.get(getKey1));
MyKey getKey2 = new MyKey(null, "Key2");
System.out.println("Values for Key2:"+myMap.get(getKey2));
MyKey getBothKey = new MyKey("Key1", "Key2");
System.out.println("Values for both keys:"+myMap.get(getBothKey));
}
}
Output -
输出 -
=====Add values for each type of key==========
Entry 1:[Key Reg]
Entry 2:[Key Reg, Key1]
Entry 3:[Key Reg, Key1, Key2]
Entry 4:[Key Reg, Key1, Key2, both keys]
=====Retrieve values for each type of key==========
Values for Key1:[Key Reg, Key1, Key2, both keys]
Values for Key2:[Key Reg, Key1, Key2, both keys]
Values for both keys:[Key Reg, Key1, Key2, both keys]
回答by bsingh
Please Use the excellent helper classes EqualsBuilder and HashCodeBuilder from the Apache Commons Lang library. An example:
请使用 Apache Commons Lang 库中优秀的辅助类 EqualsBuilder 和 HashCodeBuilder。一个例子:
public class Person {
private String name;
private int age;
// ...
public int hashCode() {
return new HashCodeBuilder(17, 31). // two randomly chosen prime numbers
// if deriving: appendSuper(super.hashCode()).
append(name).
append(age).
toHashCode();
}
public boolean equals(Object obj) {
if (obj == null)
return false;
if (obj == this)
return true;
if (!(obj instanceof Person))
return false;
Person rhs = (Person) obj;
return new EqualsBuilder().
// if deriving: appendSuper(super.equals(obj)).
append(name, rhs.name).
append(age, rhs.age).
isEquals();
}
}