如何将第三方类对象用作Hashmap密钥?

时间:2014-08-07 14:54:27

标签: java oop hashmap

好的,我理解equals和hashcode的工作原理以及它们在hashmap中的使用方式。 但是这个问题在我脑海中浮现,如果我有一个没有覆盖哈希码和等号的第三方对象,我甚至不允许修改它。

请考虑以下课程:

//Unmodifiable class
public final class WannaBeKey{

    private String id;

    private String keyName;

    //Can be many more fields

    public String getId()
    {
          return id;
    }

    public String getKeyName()
    {
          return id;
    }
    //no hashcode or equals :(

  }

现在我想把这个类作为我的Hashmap键,显然它不会在没有equals和hashcode的情况下工作。我想知道有没有办法处理这种情况?我无法想到任何事情,或者我无法理解......

感谢。

4 个答案:

答案 0 :(得分:8)

我之前遇到过这种情况,并通过为WannaBeKey创建一个包装器来解决这个问题:

public class WannaBeKeyWrapper {

  private final WannaBeKey key;


  public WannaBeKeyWrapper(WannaBeKey key) {
    this.key = key;
  } 

  public boolean equals(Object obj) {

    // Insert equality based on WannaBeKey
  }

  public int hashCode() {
    // Insert custom hashcode in accordance with http://docs.oracle.com/javase/7/docs/api/java/lang/Object.html#hashCode()
  }
}

显然,这会将您的SetSet<WannaBeKey>更改为Set<WannaBeKeyWrapper>,但您应该能够对此进行说明。

答案 1 :(得分:4)

您可以为具有重写方法的对象创建包装器。然后,您可以使用包装类作为哈希映射的键。

答案 2 :(得分:1)

您可以使用所需的语义将实际对象包装在另一个实例中:

class KeyWrapper {

  WannaBeKey key; // constructor omitted

  @Override
  public int hashCode() {
    return key.getId().hashCode();
  }

  @Override
  public boolean equals(Object o) {
    // equals method implementation
  }
}

或者,您可以简单地扩展课程(如果课程不是您在编辑中所述的final)。

答案 3 :(得分:1)

这个问题已经得到了彻底的回答,但我认为值得一提的是,上述解决方案是特定设计模式的一部分,称为Decorator

Adapter或Wrapper模式使用的解决方案基本相同,但更多的是将代码转换为不同的接口,而Decorator则用于扩展。