使用两个(或更多)对象作为一个HashMap的关键(Using two (or more) obje

2019-06-26 23:18发布

我想某些对象存储在一个HashMap。 问题是,通常你只需要使用一个对象作为重点。 (你可以,例如,使用一个String)。我想这样做,使用多个对象是什么。 例如,一类和一个字符串。 有没有实现,一个简单和干净的方式?

Answer 1:

您密钥必须实现hashCode和equals。 如果它是一个SortedMap,它也必须实现Comparable接口

public class MyKey implements Comparable<MyKey>
{
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<MyKey,String> map= new HashMap<MyKey,String>();
map.put(new MyKey(1,"Hello"),"world");


Answer 2:

我倾向于使用列表

map.put(Arrays.asList(keyClass, keyString), value)


Answer 3:

我知道最简单的方法是做一个包装类和重写HashMap和平等。 例如:

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,从而使你的多重键的哈希和平等检查。

另外,我建议做为了安全起见对象不可改变(不可编辑),但是这是纯粹是个人偏好。



Answer 4:

阿帕奇百科全书集合有一个多键映射可能为你做的伎俩:

https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/keyvalue/MultiKey.html

它看起来像它会处理多达5“键”。



Answer 5:

你的意思是该对象将通过两个按键,或者更确切地说,它包括两个方面的关键被键入。

如果你想第一种情况。 也就是说,通过两个键的键表示反对,说一个类或对象,你需要使用两张地图。

Map<Key1, value>

Map<Key2, value>

在第二种情况下,你需要地图的地图,那么:

Map<Key1, Map<Key2, value>>


Answer 6:

你可以创建一个包含要用作键的类和字符串holder类。

public class Key {

    public MyClass key_class;
    public String key_string;

    public Key(){
        key_class = new MyClass();
        key_string = "";
    }

}

可能不是最好的解决办法,但可能。



Answer 7:

还有,人们建议创建包含其他“钥匙”一类的几个地方,我完全同意。 只是想我要补充一个有用的提示。

如果你使用Eclipse或NetBeans中,他们有一个不错的选择 - 你可以告诉Eclipse来创建基于一个或多个成员equals和hashCode方法。 所以,你只要选择你想通过检索和NB创建最你需要为你写的代码的成员(或成员)。

当然,当我只是想通过一个对象来检索,我往往只是委托的哈希码和equals方法对该对象(委托平等可能是有问题的,因为这意味着你的“钥匙扣”类之一是等于对象是它的关键,但是这很容易固定的(通常不会影响反正东西)

所以把我的头顶部:

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会做最后两个你,如果你问它。

顺便说一句,我知道我有public成员,有public final成员是完全一样的东西为具有吸气 - 不是一个真正的可怕的想法。 我开始更多的使用最近的小实用工具类,比如这个有很多这种模式。 如果成员是不是终点,它会变得更糟,因为它会像有二传手(有什么我尽量避免这些天)。



Answer 8:

人们可以使用Apache的公共集合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)); 


文章来源: Using two (or more) objects as a HashMap key
标签: java hash map