SortedSet <TestClass>сравнение на равенство одного поля и сортировка другим - PullRequest
0 голосов
/ 16 ноября 2011

Пожалуйста, просмотрите код:

/* Run1.java */
package test;

import java.util.Iterator;
import java.util.SortedSet;
import java.util.TreeSet;

public class Run1 
{
    static public void main(String[] args)
    {
        SortedSet<TestClass> s = new TreeSet<TestClass>(); 

        s.add( new TestClass("name1", 100) );
        s.add( new TestClass("name2", 10) );
        s.add( new TestClass("name3", 1) );
        s.add( new TestClass("name4", 10) );
        s.add( new TestClass("name5", 100) );

        Iterator<TestClass> it = s.iterator();

        while(it.hasNext())
        {
            TestClass t = it.next();
            System.out.println( t.name+' '+t.value );
        }
    }
}

/* TestClass.java */
package test;

public class TestClass implements Comparable<TestClass> 
{
    public String name;
    public int value;

    public TestClass(String name, int value) {
        this.name = name;
        this.value = value;
    }

    public int compareTo(TestClass o) 
    {
        return this.value - o.value;
    }

    public boolean equals(Object o) 
    {
        if (!(o instanceof TestClass))
            return false;
        TestClass n = (TestClass)o;

        return this.name.equals(n.name);
    }

    public int hashCode() 
    {
        return 31*name.hashCode();
    }

    public String toString() 
    {
        return name;
    }
}

Распечатать

name3 1
name2 10
name1 100

как я вижу, потому что compareTo используется для проверки на равенство (когда возвращается 0). Но мне нужно проверить уникальность по полю TestClass.name и отсортировать только по TestClass.value

Ответы [ 4 ]

2 голосов
/ 16 ноября 2011

как насчет взлома метода CompareTo следующим образом:

public int compareTo(TestClass o) 
{
    if (this.name != null && this.name.equals(o.name)) {
        return 0;
    }


    return this.value - o.value;
}

Это должно сделать проверку на равенство по имени (удалить дубликаты) при сортировке по значению

2 голосов
/ 16 ноября 2011

Результаты compareTo() и equals() должны быть совместимы в этом случае, что означает, что вам нужно учитывать равенство при сравнении.Например:

public int compareTo(TestClass o) 
{
    return (this.value == o.value) ? this.name.compareTo(o.name) : this.value - o.value;
}

, который вводит под-порядок по имени для объектов с одинаковым значением, делая результат совместимым с вашей реализацией equals().

1 голос
/ 16 ноября 2011

Если я правильно понимаю, то вы хотите, чтобы ваш CompareTo всегда реализовывал «естественный порядок» для класса. Это означает, что клиент класса будет ожидать, что класс будет вести себя. По контракту сравнение должно быть согласовано с equals, поэтому я всегда использую equals как:

return compareTo(obj)==0;

Это гарантирует последовательность.

Тогда, если вам нужен другой порядок сортировки, вы должны реализовать другой класс, который реализует Comparable. Таким образом, вы можете иметь согласованность классов и отдельные порядки сортировки.

0 голосов
/ 16 ноября 2011

Написать компаратор, который сравнивает объекты TestClass.

public class TVComparator implements Comparator<TestClass> {
    public int compare(TestClass o1, TestClass o2) {
        if (o1.name.equals(o2.name)) return 0;
        return o1.value - o2.value;
    }
}

Ради простоты я пропустил любые проверки на нулевые значения.

...