Как решить проблему: нельзя ссылаться на int - PullRequest
1 голос
/ 14 августа 2010

Здесь у меня есть какое-то значение, два из которых являются целочисленными, и я не могу вызвать метод для них, поскольку они не являются ссылочными.Как я могу решить эту проблему?

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 с нулем.1004 *

@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 ]

4 голосов
/ 14 августа 2010

Запись hashcode и equals может быть утомительной и / или подверженной ошибкам, и IDE, такие как Eclipse, могут фактически автоматизировать эту задачу для вас. Есть много сторонних библиотек, которые могут облегчить эту функцию.

Чтобы использовать что-то из стандартной библиотеки, я рекомендую сделать следующее:

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());
}

Используются varargs , autoboxing и java.util.Arrays реализация служебного метода для равенства и хэш-кода массивов. Это будет иметь адекватную (хотя, возможно, не оптимальную) производительность, но код будет лаконичным и читаемым, и его всегда можно будет оптимизировать позже, если / когда это будет необходимо.


Опции сторонней библиотеки

С Apache Commons Lang , вы можете использовать EqualsBuilder и HashCodeBuilder.

В документации приведен пример типичного использования:

@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();
} 

Полученный код очень удобочитаемый, легко обслуживаемый и менее подвержен ошибкам.

Похожие вопросы

2 голосов
/ 14 августа 2010

Для метода hashcode вы можете просто оставить целые как они.Интты - это их собственные коды.Для метода 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;
    }

}

Написание правильных реализаций hashCode и equals сложноЛучше использовать вашу IDE для их генерации.Это то, что я тоже здесь сделал.

1 голос
/ 14 августа 2010

Вам необходимо использовать примитивы в штучной упаковке, в частности Integer.Для каждого примитива есть похожий объект, и они определяют методы, которые вас интересуют (hashCode, equals).

0 голосов
/ 14 августа 2010

Я думаю, что 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;
}

Таким образом, вам не нужно беспокоиться о неявной стоимости автобокса, если это проблема

0 голосов
/ 14 августа 2010

Здесь есть две проблемы.Во-первых, int s, объявленные на уровне класса как переменные экземпляра или класса, всегда инициализируются значением.Неважно, что это за значение, они определены как нечто, даже если вы явно не делаете этого.Во-вторых, нет смысла вызывать 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;
}
0 голосов
/ 14 августа 2010

srcPort и dstPort являются примитивными int с.

В вашем методе hashCode() вы сравниваете dstPort и srcPort с null.Вы не можете сделать это с примитивными типами в 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 и dstAddr также в вашем equals() методе?Что такое other в вашем equals() методе?Это полный код или только его часть?

0 голосов
/ 14 августа 2010

Инициализируйте целые числа чем-то (скажем, -1) и сравните их с -1

.

Я не понимаю, почему вы хотите получить хэш-код целого числа. Хэш-код принимает объект и возвращает уникальное (?) Целое число на основе объекта. Целое число - это просто примитивный объект, и вам нужно получить из него хеш-код для его идентификации.

Я бы просто обратился к целым числам напрямую и имел бы проверку на -1 (если вы инициализируете их -1) вместо проверки на ноль. (Насколько я понимаю, порт никогда не равен -1, поправьте меня, если это неверно)

...