使用两个(或更多)对象作为HashMap键
我想将某些对象存储在HashMap中。 问题是,通常只使用一个对象作为密钥。 (例如,您可以使用String。)我想要使用多个对象。 例如,Class和String。 有没有一种简单而干净的方法来实现它?
你的密钥必须实现hashCode和equals。 如果它是SortedMap ,它还必须实现Comparable接口
public class MyKey implements Comparable { private Integer i; private String s; public MyKey(Integer i,String s) { this.i=i; this.s=s; } public Integer getI() { return i;} public String getS() { return s;} @Override public int hashcode() { return i.hashcode()+31*s.hashcode(); } @Override public boolean equals(Object o) { if(o==this) return true; if(o==null || !(o instanceof MyKey)) return false; MyKey cp= MyKey.class.cast(o); return i.equals(cp.i) && s.equals(cp.s); } public int compareTo(MyKey cp) { if(cp==this) return 0; int i= i.compareTo(cp.i); if(i!=0) return i; return s.compareTo(cp.s); } @Override public String toString() { return "("+i+";"+s+")"; } } public Map map= new HashMap(); map.put(new MyKey(1,"Hello"),"world");
我倾向于使用列表
map.put(Arrays.asList(keyClass, keyString), value)
我所知道的最简单的方法是创建一个包装类并重写hashmap和equals。 例如:
public class KeyClass { private String element1; private String element2; //boilerplate code here @Override public boolean equals(Object obj) { if (obj instanceof KeyClass) { return element1.equals(((KeyClass)obj).element1) && element2.equals(((KeyClass)obj).element2); } return false; } @Override public int hashCode() { return (element1 + element2).hashcode(); } }
当然,我建议使用StringBuilder和其他任何东西,但这样你就重写了equals和hashcode,从而允许对你的多个键进行哈希和相等检查。
此外,为了安全起见,我建议使对象不可变(不可编辑),但这纯粹是首选。
Apache Commons Collections有一个多键映射,可以帮到你:
看起来它最多可以处理5个“键”。
你的意思是对象将被两个键键入,或者更确切地说是一个由两个键组成的键。
如果你想要第一个案例。 也就是说,由两个键(例如类或对象)键入的对象需要使用两个映射。
Map Map
在第二种情况下,您需要一张地图,所以:
Map>
您可以创建一个holder类,其中包含您想要作为键的类和字符串。
public class Key { public MyClass key_class; public String key_string; public Key(){ key_class = new MyClass(); key_string = ""; } }
可能不是最好的解决方案,但可能性。
有些地方人们建议创建一个包含其他人的“Key”课程,我完全同意。 只是想我会添加一个有用的提示。
如果您使用eclipse或netbeans,它们有一个很好的选择 – 您可以告诉Eclipse基于一个或多个成员创建equals和hashcode方法。 因此,您只需选择要检索的成员(或成员),NB就会创建您需要为其编写的大部分代码。
当然,当我只想通过一个对象检索时,我经常只是将hashcode和equals方法委托给该对象(委托equals可能会有问题,因为这意味着你的一个“Key holder”类将等于那个对象这是关键,但这很容易修复(并且通常不会影响任何事情)
从头到尾:
class KeyHolder { public final String key; public final Object storeMe; public KeyHolder(String key, Object storeMe) { this.key=key; this.storeMe=storeMe; } public equals(Object o) { return (o instanceof KeyHolder && ((KeyHolder)o).key.equals(key)); } public hashcode() { return key.hashCode(); } }
这就是它的全部内容,如果你要求它,eclipse会为你做最后两个。
顺便说一句,我知道我有公共成员,公共最终成员与吸气者完全一样 – 不是一个非常可怕的想法。 我最近开始在这样的小实用程序类上使用这种模式。 如果该成员不是最终成员,那就更糟了,因为它就像拥有一个二传手(我试图避开这些日子)。
可以使用apache的commons集合lib的MultiKey
类来解决这个问题。 这是一个简单的例子:
import org.apache.commons.collections.keyvalue.MultiKey; HashMap map = new HashMap(); MultiKey multiKey = new MultiKey(key1, key2); map.put(multikey,value); //to get map.get(new MultiKey(key1,key2));