Правильный ответ зависит от того, как вы хотите использовать этот класс, если равенства и hashCode должны быть недорогими, а затем рассмотрите возможность инициализации массива при построении, который можно легко сравнить. Что-то вроде этого:
import java.util.Arrays;
public class Triple {
// Use this array only for hashCode & equals.
private final int[] values;
private final int x;
private final int y;
private final int z;
public Triple(int x, int y, int z) {
this.x = x;
this.y = y;
this.z = z;
this.values = new int[]{x, y, z};
// Sort the values for simpler comparison of equality.
Arrays.sort(values);
}
@Override
public boolean equals(Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
Triple triple = (Triple) o;
return Arrays.equals(values, triple.values);
}
@Override
public int hashCode() {
return Arrays.hashCode(values);
}
}
Добавлены некоторые тесты, чтобы доказать равенство и недопущение равенства:
import static org.hamcrest.core.Is.is;
import static org.hamcrest.core.IsEqual.equalTo;
import static org.hamcrest.core.IsNot.not;
import org.junit.Assert;
import org.junit.Test;
public class TripleTest {
@Test
public void valuesInDifferentOrderAreEqual() {
Triple sortedTriple = new Triple(1, 2, 3);
Triple outOfOrderTriple = new Triple(3, 2, 1);
Assert.assertThat(sortedTriple, equalTo(outOfOrderTriple));
Assert.assertThat(sortedTriple.hashCode(), is(outOfOrderTriple.hashCode()));
}
@Test
public void valuesInOrderAreEqual() {
Triple sortedTriple = new Triple(1, 2, 3);
Triple outOfOrderTriple = new Triple(1, 2, 3);
Assert.assertThat(sortedTriple, equalTo(outOfOrderTriple));
Assert.assertThat(sortedTriple.hashCode(), is(outOfOrderTriple.hashCode()));
}
@Test
public void valuesThatAreDifferentAreNotEqual() {
Triple sortedTriple = new Triple(1, 2, 3);
Triple outOfOrderTriple = new Triple(7, 8, 9);
Assert.assertThat(sortedTriple, not(outOfOrderTriple));
Assert.assertThat(sortedTriple.hashCode(), not(outOfOrderTriple.hashCode()));
}
@Test
public void valuesWithSameSumAreNotEqual() {
Triple sortedTriple = new Triple(11, 21, 31);
Triple outOfOrderTriple = new Triple(36, 12, 21);
Assert.assertThat(sortedTriple, not(outOfOrderTriple));
Assert.assertThat(sortedTriple.hashCode(), not(outOfOrderTriple.hashCode()));
}
@Test
public void valuesWithSameProductAreNotEqual() {
Triple sortedTriple = new Triple(11, 21, 31);
Triple outOfOrderTriple = new Triple(33, 7, 31);
Assert.assertThat(sortedTriple, not(outOfOrderTriple));
Assert.assertThat(sortedTriple.hashCode(), not(outOfOrderTriple.hashCode()));
}
}
Почему это кажется очень долго? – BackSlash
Ваш метод equals * не * сравнивает перестановки. – shmosel
Однако, вот подсказка, чтобы сделать ее «короче». У вас может быть метод под названием 'asList()' в вашем классе 'Triplet', который возвращает три элемента в виде списка и возвращает' thisList(). ContainsAll (other.asList()) '- Но я думаю, что это ужасный способ решить проблему. Хороший способ - использовать 'if' и проверить все необходимые условия. – BackSlash