Как отсортировать список общих типов в Java

У меня есть набор классов, в которых есть общие атрибуты, поэтому я сделал их все распространенными базовыми классами, BaseEntity . Так что, например, Foo extends BaseEntity и Bar расширяет BaseEntity .

I also want lists of these Foo and Bar objects to be sortable, so I have implemented Comparable. I have the classes defined as Foo extends BaseEntity implements Comparable and Bar extends BaseEntity implements Comparable, and sorting of lists of Foos or Bars works as expected - and, of course, the details of the sorting are different in the different subclasses. But I can't work out how to make my sorting work when I don't know in advance whether I'll have Foos or Bars. This code, for example, fails to compile:

public class UtilityClass {

  ...bunch of stuff...

  List values;

  public List sort() {
    Collections.sort(values);
    return values;
  }

  ...more methods...
}

with the error message Bound mismatch: The generic method sort(List) of type Collections is not applicable for the arguments (List). The inferred type T is not a valid substitute for the bounded parameter >

I think the problem is that I am attempting to sort a list of BaseEntity objects, and BaseEntity itself doesn't implement Comparable. But now I face a problem: the only sensible thing to make BaseEntity objects comparable to is other BaseEntity objects, but when I add implements Comparable to BaseEntity, the compiler tells me that I've got problems now because my Foo class is trying to implement both Comparable and Comparable, which evidently is not allowed.

I know I could sidestep this issue by dropping the implements Comparable and just implementing Comparable, but then my compareTo methods will have to do ugly casting, and I thought that was exactly the sort of problem using generics was supposed to avoid.

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

Любая помощь с благодарностью получена. Благодаря!

7
nl ja de
Я уверен, что вы хотите отсортировать список объектов, а не типы?
добавлено автор Ingo, источник
Таким образом, у вас будет либо список Bar , либо список Foo , но не оба в одном и том же? Будет ли ваш шаблон MyList более активным? Если это не похоже на ненужный слой, который вызывает вашу проблему.
добавлено автор Karthik T, источник
Да, мой список - это Foo или Bar , и да, MyList - это всего лишь образец наименьшего возможного кода, который показывает проблему I У меня есть. Настоящий класс намного сложнее.
добавлено автор Dave Mulligan, источник

3 ответы

Используйте тип пересечения, например:

public class MyList> {...}

Это указывает, что T должен быть как BaseEntity , так и Comparable для себя.

7
добавлено
@newacct cn u объясните, что > фактически делает?
добавлено автор Tushar Banne, источник
для достижения наилучших результатов используйте >
добавлено автор newacct, источник
@TusharBanne: Сопоставимый является потребителем и поэтому всегда должен использоваться с ? супер , в соответствии с правилом PECS. Без ? супер , если у вас есть класс, сопоставимый с самим собой, его подкласс не может использоваться здесь как T , хотя он должен быть способен.
добавлено автор newacct, источник
Класс MyList был просто примером для отображения сообщения об ошибке. Я выбрал неправильное имя :-(, на самом деле это не список всех, и экземпляры этого класса просто должны выполнять сортировку, а не сортировать сами.
добавлено автор Dave Mulligan, источник
О, да, ты прав. Этот Comparable применяется к T , а не к MyList . Спасибо Спасибо спасибо.
добавлено автор Dave Mulligan, источник
Я не понимаю, почему это изменило бы применимость ответа. :)
добавлено автор Dolda2000, источник
потому что дженерики в java 5 хромают. ошибка «как попытка реализовать как Comparable , так и Comparable , который, очевидно, не допускается", очевидно, предложил.
добавлено автор notXX, источник

Don't use Collections.sort(List), use Collections.sort(Lst, Comparator<? extends T>) instead. Write the comparation code in the comparator.

2
добавлено

Попробуй это:

static > sort(T[] array);

Это самая общая спецификация для выполнения задачи. В принципе, он утверждает, что T - тип, который можно сравнить с самим собой.

0
добавлено
pro.jvm
pro.jvm
3 503 участник(ов)

Сообщество разработчиков Java Scala Kotlin Groovy Clojure Чат для нач-их: @javastart Наш сайт: projvm.com projvm.ru Наш канал: @proJVM Вакансии: @jvmjobs Конфы: @jvmconf

Java & Co
Java & Co
2 370 участник(ов)

Можно обсуждать с матом и без всё, что касается жабы, вплоть до холиваров. НЕ ИМЕЕТ ОТНОШЕНИЯ К САЙТУ JAVARUSH.RU ПРАВИЛА - https://t.me/javarush/75723 Вакансии сюда - https://telegram.me/joinchat/B7IzvUCnfo6d8t3yIxKguQ По вопросам - @thedude

learn.java
learn.java
1 888 участник(ов)

Чат для начинающих и не только Статистика: https://combot.org/chat/-1001083535868 Основной чат - @jvmchat

Java Underground
Java Underground
169 участник(ов)

https://vk.com/javatutorial

Javanese Questions
Javanese Questions
109 участник(ов)

Чат предназначен для обмена знаниями строго в формате в вопрос-ответ. Тема — Java, Kotlin и Android. Вопрос должен быть предварительно прогуглен, понятно и грамотно сформулирован, помечен хэштегами. Ответ — тем более. Куски кода размером в несколько строк можно писать прямо здесь, для больших кусков кода стоит использовать http://gist.github.com/, http://pastebin.com/, https://codeshare.io/ или любой аналогичный сервис. В некоторых случаях можно прикреплять скриншоты. Стикеры и гифки запрещены. Дополнять и уточнять вопросы и ответы — редактированием исходного сообщения. Обсуждения должны приводить к редактированию вопроса/ответа и удаляться. По хештегам можно искать существующие вопросы и овтеты: #вопрос #ответ #git #generics #java #server #awt #javafx #swing #kotlin #anko #tornadofx #ktor #android #recyclerView #performance #arch #network #permissions #storage #async