添加泛型集合排序方法时出错

时间:2015-10-16 04:09:06

标签: java sorting generics collections

我正在尝试拨打Collections.sort(c);但我收到错误:

The method sort(List<T>) in the type Collections is not applicable
for the arguments (Collection<capture#1-of ? extends E>)

这是我的代码:

import java.lang.*;

public class SortedLinkedList<E extends Comparable<E>> extends LinkedList<E> {
    LinkedList<Object> list = new LinkedList();
    SortedLinkedList()
    {

    }

     SortedLinkedList(Collection<? extends E> c)
    {
        //return sorted linked list of c
        Collections.sort(c);
    }

    public int compareTo(Collection<? extends E> c) {
        // TODO Auto-generated method stub

        return 0;
    }
}

我已经使用扩展类似接口的泛型类声明了该类。 但这仍然无法帮助解决错误。我跟踪了这​​个被标记为重复的帖子,但它没有多大帮助。这是我第一次尝试在java中学习泛型。任何帮助深表感谢。 -Thanks!

1 个答案:

答案 0 :(得分:1)

类型<E extends Comparable<E>>很好,但还有其他一些问题:

  • cCollection,但除非CollectionList,否则您无法对Collection进行排序,因为只有List Collection允许按特定顺序排列和重新排列元素。其他类型的c,例如Setbag,则不会。您可以将List强制转换为c,但仍然是排序错误的对象。看起来您想将SortedLinkedList(Collection<? extends E> c) { list.addAll(c); Collections.sort(list); } 的内容放入链接列表,然后对 进行排序:

    LinkedList<Object>
  • 列表声明为LinkedList<E>,但应为new LinkedList();,(or maybe List<E>),以便声明它包含可排序对象。

  • list should be new LinkedList<E>()的分配,可以是shortened to new LinkedList<>()

进行足够的更改以使代码编译,但让我们深入研究。我推断你在这里尝试做的是创建一个通用的容器集合,它是一个链接列表,其中的元素始终按排序顺序保持不变。在这种情况下,您要做的一些更改是:

  • private变量应为final,以防止其他课程使用它。如果您不想在初始化后重新分配变量,那么将其设置为public也会很好,这可以防止意外重新分配,并澄清这就是您使用它的方式。

  • 构造函数应为compareTo以允许从其他包进行访问。

  • 我不确定你的LinkedList方法是什么意思。 (如何定义一个整个集合与另一个集合的比较?)可能应将其删除。

  • 目前您正在封装和扩展LinkedList,这没有任何意义。您的类的每个实例都有两个 list s,一个位于LinkedList变量中,另一个继承自父级。你需要决定其中一个。

    • 如果您想扩展 list,那么您可以完全摆脱public SortedLinkedList(Collection<? extends E> c) { super.addAll(c); Collections.sort(this); } 变量并调用超类方法。 E.g:

      LinkedList

      在这种情况下,您需要覆盖父类的任何变量方法,以确保它们都不能用于破坏您的类按排序顺序维护其元素的不变量。例如,覆盖add(E element)并使其在正确的位置插入新元素。虽然add(int position, E element)应该被覆盖以抛出UnsupportedOperationException,因为在指定的索引位置插入元素是没有意义的,因为元素在排序列表中的位置已经暗示了它的价值。

      扩展LinkedList的一个缺点是,将来可能会将新的变异方法添加到LinkedList类,这样就可以让用户破坏你的集合的不变量。< / p>

    • 如果您希望使用list变量封装 extends LinkedList<E>,那么您应删除implements List<E>,而不是LinkedList

      在这种情况下,您需要为接口的所有方法提供实现,但是您可以通过扩展Java Collections Framework提供的一个抽象骨架类来正确实现其中的大多数,例如{{3 }}

    • 第三种可能性:既不扩展也不封装import java.lang.*;,而是从头开始编写链表。

  • 不需要行java.langimport java.util.*; public class SortedLinkedList<E extends Comparable<E>> extends AbstractSequentialList<E> implements List<E> { private final LinkedList<E> list = new LinkedList<>(); public SortedLinkedList() {} public SortedLinkedList(Collection<? extends E> c) { list.addAll(c); Collections.sort(list); } @Override public boolean add(E element) { list.add(element); Collections.sort(list); return true; } @Override public ListIterator<E> listIterator(int index) { // Rather than returning list.listIterator(index) directly, we // encapsulate it to block the add and set methods: return new ListIterator<E>() { private final ListIterator<E> base = list.listIterator(index); @Override public boolean hasNext() { return base.hasNext(); } @Override public E next() { return base.next(); } @Override public boolean hasPrevious() { return base.hasPrevious(); } @Override public E previous() { return base.previous(); } @Override public int nextIndex() { return base.nextIndex(); } @Override public int previousIndex() { return base.previousIndex(); } @Override public void remove() { base.remove(); } @Override public void set(E e) { // prevent unsorting the list throw new UnsupportedOperationException(); } @Override public void add(E e) { // prevent unsorting the list throw new UnsupportedOperationException(); } }; } @Override public int size() { return list.size(); } } AbstractSequentialList中的所有内容。

以下是基于上述修复的示例:

List

大部分AbstractSequentialList方法都可以毫不费力地实现,感谢神奇的超类ListIterator.remove()超类。但是,如果您检查is imported by default,那么如果您覆盖这些方法,则可以改进,因为继承的实现主要是为了最大限度地减少扩展类的工作量。例如。要清除列表,它会迭代每个元素并小心地逐个删除它们(通过LinkedList),而推迟到clear()的{​​{1}}方法会更快。< / p>

此外,不是在添加元素后重新排序整个列表,而是将其直接插入到正确的位置会更有效。您可以通过the source执行此操作,但我会留给您:)

另一个不错的功能是允许使用自定义ListIterator.add构建类来用于排序元素。这将允许使用未实现Comparable的元素类型,以及覆盖默认排序的能力(例如,类的用户可以为Comparator提供Comparatorcase-insensitive ordering of Strings是支持此类功能的类的示例。

我希望这个例子无论如何都有助于展示概念。