Как получилось, что параметр типового типа "extends" Comparable не "реализует"?
Я попытался написать общую функцию, которая удаляет повторяющиеся элементы из массива.
public static <E extends Comparable<E>> ArrayList<E> removeDuplicate(E[] arr) {
//do quicksort
Arrays.sort(arr);
ArrayList<E> list = new ArrayList<E>();
int i;
for(i=0; i<arr.length-1; i++) {
if(arr[i].compareTo(arr[i+1]) != 0) { //if not duplicate, add to the list
list.add(arr[i]);
}
}
list.add(arr[i]); //add last element
return list;
}
Как вы можете видеть, вы не можете передавать примитивный тип, например массив int [], поскольку я сравниваю элементы методом compareTo(), который определен в интерфейсе Comparable.
Я заметил первую строку (объявление метода):
public static <E extends Comparable<E>> ArrayList<E> removeDuplicate(E[] arr) {
Как получилось, что "extends Comparable"?
Сопоставимый интерфейс, поэтому почему он не "реализует Comparable"? Это первый раз, когда я написал универсальную функцию, поэтому я немного запутался в таких деталях. (любое удивление помешало бы мне понять..)
EDIT: эта статья относится к этой теме.
http://www.tutorialspoint.com/java/java_generics.htm
Ответы
Ответ 1
Если вы хотите использовать то, что реализует, вы просто пишете как общий параметр
class Bar extends Foo<String> { /* Code */}
Подстановочный знак, о котором Вы говорите, - это три
- "? extends Type": обозначает семейство подтипов типа Type. Это самый полезный шаблон
- "Супер Тип": обозначает семейство супертипов типа Тип
- "?": Обозначает набор всех типов или любой
Вы метод должен выглядеть так
public static <T extends Comparable<? super T>> Collection<T> sort(T[] list) {
Collection<T> list = new ArrayList<T>();
//do quicksort
Arrays.sort(arr);
Collection<T> list = new ArrayList<T>();
int i;
for(i=0; i<arr.length-1; i++) {
if(arr[i].compareTo(arr[i+1]) != 0) { //if not duplicate, add to the list
list.add(arr[i]);
}
}
list.add(arr[i]); //add last element
//btw how do You know that last is not duplicate
return list;
}
Для подробностей, пожалуйста, посетите эту страницу
Ответ 2
Это просто соглашение, выбранное для дженериков. При использовании параметров ограниченного типа вы используете extends (даже если это может означать инструменты в некоторых случаях) или super.
Вы можете даже сделать что-то вроде <E extends Comparable<E> & Cloneable>
, чтобы определить, что объект, который заменит параметр типа, должен реализовать оба этих интерфейса.
Ответ 3
С одной стороны, E
может быть интерфейсом.