我正在实现一个简单的 LinkedList
类,我希望它使用泛型。类声明为:
public class LinkedList<E> extends AbstractList<E> implements List<E> {
这是一个教学示例,因此 Abstract
父级和接口(interface)也是我自己的。当我意识到要添加和维护排序时,问题就出现了,我需要一个也是Comparable
的类(E)。我想我可以将其限制在真正产生影响的方法上。但根据下面的评论,这可能是我的基本误解。
代码如下:
public void addSorted(<E extends Comparable<E>> value) {
if (front == null || value.compareTo(front.word) <= 0) {
// insert at front of list
front = new ListNode<E>(value, front);
} else {
// insert in middle of list
ListNode<E> current = front;
while (current.next != null && current.next.word.compareTo(value) < 0) {
current = current.next;
}
current.next = new ListNode<E>(value, current.next);
}
}
在我看来,如果我永远不想调用 addSorted
那么为什么特定的类应该限于实现 Comparable
的 E 类?或者是否有一种完全不同的方法来做到这一点,使用实例的通用模拟?
最佳答案
考虑一下如果您能够同时调用 add
会发生什么和addSorted
在LinkedList
上实例:
LinkedList<String> list = new LinkedList<>();
list.add("c"); list.add("a");
list.addSorted("b");
在这种情况下,你期望"b"
在哪里?插入列表 ["c", "a"]
:
- 按字典顺序位于
"c"
之前,因此可以将其插入到开头,产生["b", "c", "a"]
; - 按字典顺序排列在
"a"
之后,因此可以将其插入到末尾,产生["c", "a", "b"]
;
但这两个列表之后都没有真正“排序”。
对我来说,解决这种歧义的唯一明显方法是强制所有添加以排序的方式完成。这意味着您应该创建 LinkedList
的子类, SortedLinkedList
,它覆盖 LinkedList.add
方法:
class SortedLinkedList<E extends Comparable<E>> extends LinkedList<E> {
void add(E element) {
// The implementation of addSorted.
}
}
<小时/>
一般来说,我处理仅适用于某些泛型类型的方法的方法是使用接受类实例作为第一个参数的方法,该方法在类的定义之外(或在定义之内)类的名称,但定义为 static
)。这意味着它不是类接口(interface)的一部分,因此对于具有不兼容泛型类型的类来说,它不存在。
例如,如果您想添加 sort
排序方法LinkedList
s,这显然只对 Comparable
的人有意义。元素:
static <E extends Comparable<E>> void sort(LinkedList<E> list) {
// ...
}
例如:
LinkedList<String> strList = new LinkedList<>();
// ... Add elements.
sort(strList); // OK.
LinkedList<Object> objList = new LinkedList<>();
// ... Add elements.
sort(objList); // Compiler error - Object is not a valid bound.
关于Java 泛型形式参数,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36481469/