Java通用形式参数

时间:2016-04-07 15:59:55

标签: java generics

我正在实现一个简单的LinkedList类,我希望它使用泛型。类声明是:

public class LinkedList<E> extends AbstractList<E> implements List<E> {

这是一个教学示例,因此Abstract父级和界面也是我自己的。当我意识到要添加和维护排序时,问题出现了,我需要一个类(E),它也是Comparable。我认为我可以将其限制在实际上有所作为的方法。但根据以下评论,这可能是我的基本误解。

以下是代码:

  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?或者有一种完全不同的方式来实现它,通用模拟实例?

1 个答案:

答案 0 :(得分:2)

如果您能够在add个实例上同时调用addSortedLinkedList,请考虑会发生什么:

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"];

但之后这两个名单都没有真正“排序”。

对我而言,解决这种歧义的唯一明显方法是强制所有添加以排序方式完成。这意味着您应该创建LinkedListSortedLinkedList的子类,它会覆盖LinkedList.add方法:

class SortedLinkedList<E extends Comparable<E>> extends LinkedList<E> {
  void add(E element) {
    // The implementation of addSorted.
  }
}

一般来说,我处理应该只适用于某些泛型类型的方法的方法是使用一个接受类的实例作为第一个参数的方法,在类的定义之外(或在定义内部)该类,但定义为static)。这意味着它不是类接口的一部分,因此对于具有不兼容泛型类型的类不存在。

例如,如果您想添加sort方法来对LinkedList进行排序,这显然只对具有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.