2014-09-11 2 views
17

Я использую сопоставимый интерфейс все время, чтобы обеспечить естественный порядок для моего класса через collection.sort.Объяснение общих <T extends Сопоставимый <? super T>> в коллекции.sort/сопоставимый код?

В принципе, если у меня есть класс человека, я получу его для реализации интерфейса Comparable и обеспечит реализацию compareTo. Однако в определении Collections.sort в Javadocs, я вижу эту подпись

public static <T extends Comparable<? super T>> void sort(List<T> list) 

Я не понимаю, это определение дженериков вообще? Должен ли он просто сказать

<T implements Comparable<T>> 

Может ли кто-нибудь помочь мне с этим?

+7

Это означает, что либо класс 'сам или один из его супер классов T' реализует' Comparable'. –

+0

@ PM77-1 Благодарим вас за это упрощенное объяснение, и кажется, что '>' является наиболее правильным – Mushy

ответ

23

На самом деле это означает, что T может осуществить Comparable<? super T>, а не только Comparable<T>.

Например, это означает, что Student класс может реализовать Comparable<Person>, где Student является подклассом Person:

public class Person {} 

public class Student extends Person implements Comparable<Person> { 
    @Override public int compareTo(Person that) { 
     // ... 
    } 
} 

В этом случае список может быть отсортирован по Collections.sort(), но только на основе Person-х свойства, потому что вы передаете экземпляр Student в compareTo() как Person (если, конечно, вы его не убьете).

На практике, однако, вы никогда не увидите класс Student, реализующий класс Comparable<Person>. Это потому, что Person, вероятно, внедрил Comparable<Person>, а Student наследует его реализацию. Конечный результат тот же самый: вы можете передать List<Student> до Collections.sort() и отсортировать его по Person.

Разница между Comparable<T> и Comparable<? super T> более очевидна в the overloaded version of Collections.sort(), что занимает Comparator<? super T>:

class ByAgeAscending implements Comparator<Person> { 
    @Override public int compare(Person a, Person b) { 
     return a.getAge() < b.getAge(); 
    } 
} 

List<Student> students = getSomeStudents(); 
Collections.sort(students, new ByAgeAscending()); 
5

Вы всегда используете extends с универсальными подстановочными знаками, даже если параметр type реализует интерфейс.

Если вы посмотрите на класс, который реализует Comparable, вы увидите, что он на самом деле должен (должен) реализовать Comparable<T>, где T - сам класс.

Имеет смысл, если вы думаете о параметре типа, переданном интерфейсу Comparable, и о том, как он используется в методе compareTo().

Как указано в краткой заявке PM 77-1, ключевое слово супер позволяет либо классу, либо T, либо одному из его родителей реализовать Comparable.

Смежные вопросы