Java 泛型形式参数

标签 java generics

我正在实现一个简单的 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 会发生什么和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"] ;

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

对我来说,解决这种歧义的唯一明显方法是强制所有添加以排序的方式完成。这意味着您应该创建 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/

相关文章:

generics - 如何实现采用特征MyTrait <A>的结构? [复制]

java - 在Android中使用setVisibility?

java - 使用 Android 上的 OpenGL ES 2.0,在帧缓冲区上渲染时是否可以保留多重采样?

java web 应用程序与 java 桌面应用程序集成

java - 我无法弄清楚比较器

java - 为什么泛型类型参数 get 方法会抛出 NullPointerException

java - 如何使用作为 List<Super> 返回的 List<Sub>

java - 在重复任务中调用 'this' 时出现静态问题

java - 返回具有泛型的对象子类

generics - 使用标准的 haskell 泛型库进行类型化类型同构