Сортировка списка суперклассов объектов из двух подклассов

У меня есть список типа Superclass A, и в этом списке есть несколько объектов из двух подклассов, Subclass B и Subclass C, и я хочу отсортировать их по алфавиту, а затем отфильтровать объекты из любого подкласса, примерно так:

List <A> listA= new ArrayList<A>();

Collections.sort(listA);
    for (A iterator : listA)
        if (iterator instanceof B)
            System.out.println(iterator);

Мой вопрос в том, как мне структурировать свой код. Должен ли я реализовать Comparable <A> и

public int compareTo(A a) {
    return name.compareTo(a.getName());
}

как в Superclass, так и в Subclass? Если я недостаточно ясно выразился, пожалуйста, так и скажите.

РЕДАКТИРОВАТЬ: я получал ошибку из-за метода, который я оставил в одном из подклассов, который уже был унаследован от суперкласса, и я думал, что ошибка как-то связана со структурой Comparable<A>, потому что я не был уверен, что это было правильно, но у меня уже был код, как все, что вы мне сказали, но все равно спасибо.


person Big Puncho    schedule 21.06.2013    source источник


Ответы (6)


Если вы можете сравнивать экземпляры SuperclassA независимо от того, являются ли они SubclassB или SubclassC, то ваше решение только с Comparable<SuperclassA> в суперклассе имеет смысл. Если реализация требует знания данных, специфичных для подклассов, добавьте абстрактные методы, которые предоставляют эти данные в SuperclassA, и вызовите их в своем компараторе.

person Sergey Kalinichenko    schedule 21.06.2013

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

Нет, достаточно, если вы реализуете его в своем Суперклассе А. Метод будет унаследован подклассами.

person Puce    schedule 21.06.2013

я предлагаю вам реализовать Comparator

public NameAndClassComparator implements Comparator<A> {
    public int compare(A left, a right) {
        if(left == null && right == null) {
            return 0;
        }
        if(left == null) {
            return -1;
        }
        if(right == null) {
            return 1;
        }

        int retVal = left.getname().compareTo(right.getName());

        if(retVal == 0) {
            retVal = left.getClass().getName().compareTo(right.getClass().getName());
        }

        return retVal;
    }
}

А затем используйте этот компаратор для сравнения ваших объектов:

Collections.sort(listA, new NameAndClassComparator());
person Marco Forberg    schedule 21.06.2013

Вам нужно реализовать Comparable только в суперклассе. После реализации подклассы будут использовать один и тот же метод в вашем суперклассе для сравнения экземпляров.

Если вы хотите сравнить два подкласса по-разному, вам нужно переопределить метод compareTo() в ваших подклассах.

Даже в этом случае вам все равно нужно реализовать Comparable в суперклассе.

person Raza    schedule 21.06.2013

Вы должны реализовать Comparable в Суперклассе A как

Class A implements Comparable<A>{
    .....
    .....

    public int compareTo(Object obj){
       if( null != obj && (obj instanceOf A || obj instanceOf B || obj instanceOf C)){
         //Compare your properties here and return -1, 0 or 1 depending on the result of comparision.
        }else{
           throw new IlligalArgumentException();
        }
 }
person Vaibhav Raj    schedule 21.06.2013

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

person Manish Doshi    schedule 21.06.2013