如何解决问题:int无法解除引用

时间:2010-08-14 09:14:22

标签: java hashcode equals

这里我有一些值,其中两个是整数,我不能调用它们的方法,因为它们不是引用。我该如何解决这个问题?

String srcAddr, dstAddr, protocol;
int srcPort, dstPort;

public int hashCode() {

        final int prime = 31;
        int result = 1;
        result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode());
        result = prime * result + ((dstPort == null) ? 0 : dstPort.hashCode());
        result = prime * result + ((srcAddr == null) ? 0 : srcAddr.hashCode());
        result = prime * result + ((srcPort == null) ? 0 : srcPort.hashCode());
        return result;

}

另外,我也有一个相同的方法,下面显示了错误的一部分,与上面相同我无法将int与null进行比较。

@Override
public boolean equals(Object obj) {

    if (srcPort == null) {
        if (other.srcPort != null)
            return false;
    } else if (!srcPort.equals(other.srcPort))
        return false;

    if (srcPort == null) {
        if (other.srcPort != null)
            return false;
    } else if (!srcPort.equals(other.srcPort))
        return false;
}

如何解决此错误?

7 个答案:

答案 0 :(得分:4)

编写hashcodeequals可能会很乏味和/或容易出错,而像Eclipse这样的IDE实际上可以为您自动执行此任务。有许多第三方库也可以促进此功能。

要使用标准库中的内容,我建议您执行以下操作:

import java.util.Arrays;

// conveniently packs varargs to array 
private static Object[] pack(Object... objs) {
   return objs;
}

private Object[] fieldsAsArray() {
   return pack(srcAddr, dstAddr, protocol, srcPort, dstPort);
}

@Override public int hashCode() {
   return Arrays.hashCode(this.fieldsAsArray());
}

@Override public boolean equals(Object o) {
   // TODO: instanceof check, cast and assign o to other

   return Arrays.equals(this.fieldsAsArray(), other.fieldsAsArray());
}

这使用varargsautoboxingjava.util.Arrays实用程序方法实现数组的相等性和哈希码。这将具有足够的(尽管可能不是最佳的)性能,但代码是简洁和可读的,并且如果/在必要时可以随后进行优化。


第三方库选项

Apache Commons Lang,您可以使用EqualsBuilderHashCodeBuilder

文档中有典型用法示例:

@Override public boolean equals(Object obj) {
   if (obj == null) { return false; }
   if (obj == this) { return true; }
   if (obj.getClass() != this.getClass()) {
     return false;
   }
   MyClass other = (MyClass) obj;
   return new EqualsBuilder()
                 .appendSuper(super.equals(obj))
                 .append(field1, other.field1)
                 .append(field2, other.field2)
                 .append(field3, other.field3)
                 .isEquals();
}

@Override public int hashCode() {
   return new HashCodeBuilder(17, 37)
                 .append(field1)
                 .append(field2)
                 .append(field3)
                 .toHashCode();
} 

生成的代码非常易读,易于维护,并且不易出错。

相关问题

答案 1 :(得分:2)

对于hashcode方法,您可以按原样保留整数。 Ints是他们自己的hascodes。对于equals方法,只需使用=进行比较即可。所以代码变成了:

public class Connection {

    String srcAddr, dstAddr, protocol; int srcPort, dstPort;

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode());
        result = prime * result + dstPort;
        result = prime * result
                + ((protocol == null) ? 0 : protocol.hashCode());
        result = prime * result + ((srcAddr == null) ? 0 : srcAddr.hashCode());
        result = prime * result + srcPort;
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Connection other = (Connection) obj;
        if (dstAddr == null) {
            if (other.dstAddr != null)
                return false;
        } else if (!dstAddr.equals(other.dstAddr))
            return false;
        if (dstPort != other.dstPort)
            return false;
        if (protocol == null) {
            if (other.protocol != null)
                return false;
        } else if (!protocol.equals(other.protocol))
            return false;
        if (srcAddr == null) {
            if (other.srcAddr != null)
                return false;
        } else if (!srcAddr.equals(other.srcAddr))
            return false;
        if (srcPort != other.srcPort)
            return false;
        return true;
    }

}

编写hashCodeequals的正确实现非常棘手。更好地使用IDE来生成它们。这就是我在这里所做的。

答案 2 :(得分:1)

您需要使用盒装基元,特别是Integer。每个基元都有一个类似的对象,它们定义了您感兴趣的方法(hashCodeequals)。

答案 3 :(得分:0)

将整数初始化为某事(比如-1)并将它们与-1进行比较

我不明白你为什么要得到一个整数的Hashcode。 Hashcode接受一个对象并返回一个基于该对象的唯一(?)整数。整数只是一个原始对象,您应该从中获取一个哈希码来识别它。

我只是直接引用整数并检查-1(如果将它们初始化为-1)而不是检查为null。 (据我所知,端口永远不会为-1,如果这是假的话,请纠正我)

答案 4 :(得分:0)

srcPortdstPort是原始int s。

hashCode()方法中,您要将dstPortsrcPortnull进行比较。你不能用Java中的原始类型做到这一点。只需在hashCode()方法中写下这样的行:

result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode());
result = prime * result + dstPort;
result = prime * result + ((srcAddr == null) ? 0 : srcAddr.hashCode());
result = prime * result + srcPort;

equals()方法中,您尝试在equals()上调用srcPort方法。您无法在Java中调用基本类型的方法。使用==来比较确切类型。

请注意,您的equals()方法也包含两次相同的代码块;这很可能是一个错误。您不必在srcAddr方法中检查dstAddrequals()吗? other方法中的equals()是什么?这是完整的代码还是仅仅是其中的一部分?

答案 5 :(得分:0)

这里有两个问题。首先,在类级别声明的int作为实例或类变量始终初始化为一个值。无论该值是什么,它们都被定义为某种东西,即使您没有明确地这样做。其次,将hashCode()调用为基本类型的东西是没有意义的,因为它们没有可以调用的方法。

我的实现看起来像这样:

public int hashCode() {

        final int prime = 31;
        int result = 1;
        result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode());
        result = prime * result + dstPort;
        result = prime * result + ((srcAddr == null) ? 0 : srcAddr.hashCode());
        result = prime * result + srcPort.hashCode;
        return result;

}

public boolean equals(Object obj) {
    if (!(obj instanceof MyClass)) {
        return false;
    }

    //Cast obj to a MyClass

    if (other.srcPort != scrPort) {
            return false;
    }

    if (other.dstPort != dstPort) {
            return false;
    }

    //Check the other variables too.

    //We didn't fall into any if-statements.
    return true;
}

答案 6 :(得分:0)

我认为Shakedown有你的答案,只是使用盒装的Integer类型:

String srcAddr, dstAddr, protocol; Integer srcPort, dstPort;

public int hashCode() {

    final int prime = 31;
    int result = 1;
    result = prime * result + ((dstAddr == null) ? 0 : dstAddr.hashCode());
    result = prime * result + ((dstPort == null) ? 0 : dstPort);
    result = prime * result + ((srcAddr == null) ? 0 : srcAddr.hashCode());
    result = prime * result + ((srcPort == null) ? 0 : srcPort);
    return result;

}

或者使用0作为默认值(因为如果没有设置值,那就是你返回的内容),如下所示:

String srcAddr="", dstAddr=""; int srcPort=0,dstPort=0; //empty string has hashCode 0

public int hashCode() {
  final int prime = 31;
  int result = 1;
  result = prime * result + dstAddr.hashCode();
  result = prime * result + dstPort;
  result = prime * result + srcAddr.hashCode();
  result = prime * result + srcPort;
  return result;
}

这样,如果出现问题,您无需担心自动装箱的隐性成本