2016-09-27 7 views
0

Я построил свой собственный класс, который реализует сопоставимые (возможно, не соответствующие), и когда я пытаюсь использовать HashSet для хранения элементов, HashSet иногда утверждает, что элемент находится в HashSet, даже если он не является , Я думал, что это связано с контрольными проверками, но я подтвердил, что это не так. Что не так?Java TreeSet не работает как ожидается

Vertex класс equals и getHashcode: класс

public class Vertex implements Comparable<Vertex>{ 

    // some code ... 

    @Override 
    public boolean equals(Object obj) { 
     Vertex other = (Vertex) obj; 
     return this.getPosition().equals(other.getPosition()); 
    } 


    @Override 
    public int hashCode() { 
     int hashCode1 = Integer.parseInt(this.getPosition().getX() + "" + this.getPosition().getY()); 
     return hashCode1; 
    } 
} 

Должность:

public class Position { 
    private int x; 
    private int y; 


    public Position(int x, int y) { 
     this.x = x; 
     this.y = y; 
    } 

    public int getX() { 
     return x; 
    } 

    public int getY() { 
     return y; 
    } 

    @Override 
    public boolean equals(Object obj) { 
     Position other = (Position) obj; 
     return this.x == other.x && this.y == other.y; 
    } 

    @Override 
    public String toString() { 
     //return String.format("x = %d, y = %d", x, y); 
     return String.format("(%d, %d)", x, y); 
    } 
} 

EDIT: Вот реализация

public static void test(Vertex[][] grid) { 
    TreeSet<Vertex> someSet = new TreeSet<Vertex>(){{ 
     add(new Vertex(new Position(3, 4), false)); 
     add(new Vertex(new Position(0, 5), false)); 
    }}; 
    Vertex v = new Vertex(new Position(2, 5), false); 
    if (someSet.contains(v)) { 
     System.out.println("error"); 
    } else { 
     System.out.println("ok"); 
    } 
} 

Вышеприведенные печатает error.

+1

Ваш хэш-код не уникален, например, он будет возвращать одинаковое значение для двух разных точек, то есть (2,31) & (21,3) – Sanjeev

+0

какие у вас ключи? Являются ли ваши ключи реалистичными равными и hashcode полностью? I –

+0

Вы должны включить код, который использует классы, которые вы опубликовали (т. Е. Код, который создает HashSet). – Eran

ответ

0

Я понял проблему. Как заметил @NicolasFilotto, я не упомянул функцию compareTo. Основанный на a past post, TreeSet не использует hashCode, но использует compareTo (я предполагаю для двоичного поиска). Вот почему мои тестовые случаи терпели неудачу.

0

С вашей hashcode расчет очков (1,12) и (11,2) будет считаться идентичным.

См. best-implementation-for-hashcode-method для получения рекомендаций по хэш-кодам.

+4

Это не нарушает контракт hashCode - двум не равным объектам разрешено иметь один и тот же hashCode. Является ли это хорошим или плохим hashCode, это другая проблема. – Eran

+0

Я понимаю это, но разве Java не обрабатывает конфликты? – ljeabmreosn

+2

@ljeabmreosn Java обрабатывает столкновение. Было бы легче ответить на ваш вопрос, если бы вы разместили более подходящий код. – Eran