Java 有人能告诉我为什么返回空列表(NPE)吗?

Java 有人能告诉我为什么返回空列表(NPE)吗?,java,exception,merge,linked-list,Java,Exception,Merge,Linked List,我有一段代码,它应该将SortedLinkedList的两个实例合并到一个SLL中(基于mergeSort merge),但返回的是一个空列表: import java.util.LinkedList; public class SortedLinkedList<T extends Comparable<? super T>> extends LinkedList<T> { private LinkedList<T> list; //

我有一段代码,它应该将
SortedLinkedList
的两个实例合并到一个SLL中(基于mergeSort merge),但返回的是一个空列表:

import java.util.LinkedList;

public class SortedLinkedList<T extends Comparable<? super T>>
    extends LinkedList<T> {

private LinkedList<T> list; // the sorted list

// constructor, sorted with insertion sort
public SortedLinkedList(LinkedList<T> in)
{
    if(in.peek() == null || in.size() == 1)
        return;
    else {
        list = new LinkedList<T>();
        for(T e : in)
            list.add(e);
        int i, j;
        T temp;
        for(i = 0; i < list.size(); i++){
            j = i;
            temp = list.get(j);
            while(j > 0 && list.get(j-1).compareTo(temp) > 0){
                list.set(j, list.get(j-1));
                j--;
            }
            list.set(j, temp);
        }
}
}

// return the union of the sorted linked lists this
// and other
public SortedLinkedList<T> makeUnion( SortedLinkedList<T> other)
{
    list = new LinkedList<T>();
    SortedLinkedList<T> temp = new SortedLinkedList<T>(list);
    int i = 0, j = 0;
    while(i < this.size() && j < other.size()){
        if(this.get(i).compareTo(other.get(j)) <= 0){
            temp.add(this.get(i));
            i++;
        }
        else {
            temp.add(other.get(j));
            j++;
        }
    }
    while(i < this.size()){
            temp.add(this.get(i));
            i++;
    }
    while(j < other.size()){
            temp.add(other.get(j));
            j++;
        }
    return temp;
}

// print the items in list
public void print()
{
    for(T e : list)
        System.out.println(e);
}
}

编辑2:看来@Mead是对的。。。虽然size()和get()似乎适用于SLL,但add()不适用。我在想,既然我扩展了LinkedList,它也可以和SLL一起使用。它没有,覆盖它们也没有起到任何作用。。。我对此没有主意了。建议?

在查看了实现之后,我很好奇,但是您是否已经完成了一个.addAll(…)然后是Collections.sort(…)?这是我个人更喜欢的。

太好了!您的编辑几乎暴露了您的问题:您没有正确扩展LinkedList。解决这个问题,然后在工会上工作

当前的问题是:这是一个名为
SortedLinkedList
的类。我们可以假设它与LinkedList一样,但其中的值是经过排序的。因此,考虑到这一点,这应该是可行的:

LinkedList<Integer> unsorted = new LinkedList<Integer>();
unsorted.add(200);
unsorted.add(100);
unsorted.add(300);
SortedLinkedList<Integer> sorted = new SortedLinkedList<Integer>(unsorted);
System.out.println(sorted.size());
for (Integer i : sorted) {
   System.out.println(i);
}
// Should print out:
// 3
// 100
// 200
// 300
它不知道如何查看您的
this.list
变量,因此无法打印100。实际上,它将崩溃,因为索引0中没有值。您没有添加get()实际使用的实例变量,因此这些方法认为SortedLinkedList对象为空
this.list
是继承方法不知道的新变量

因此,如果我们检查您的最新编辑:

public SortedLinkedList<T> makeUnion( SortedLinkedList<T> other)
{
    LinkedList<T> temp = new LinkedList<T>();
    temp.addAll(this);
    temp.addAll(other);
    SortedLinkedList<T> merge = new SortedLinkedList(temp);
    return merge;
}
公共SortedLinkedList makeUnion(SortedLinkedList其他)
{
LinkedList temp=新建LinkedList();
临时添加所有(此);
临时添加所有(其他);
SortedLinkedList合并=新的SortedLinkedList(临时);
返回合并;
}
temp.addAll(this)
不起作用,因为
this
的所有方法都认为列表是空的,因为它们没有查看
this.list
<出于同样的原因,代码>临时添加所有(其他)也不起作用

扩展类时的常见情况是希望现有方法继续工作。这意味着您需要将数据存储在get()和其他方法期望的位置。你是怎么做到的?你已经在做了您已经在做正确的事情了——但是您是在实例变量
this.list
上做的,而不是
this
。开始调用
this.add()
this.set()
this.size()
,而不是
this.list.add()
,并完全删除实例变量
list
——这不是必需的,您有
this
。然后,数据将位于其他方法预期的位置


(并在构造函数的第一行调用super(),这样就调用了超类构造函数中的代码)。祝你作业顺利-我建议在添加新方法之前测试对象的工作状态。

与其给我们一些代码并描述其余部分,不如提供一个简短但完整的程序来演示问题。很不清楚为什么要在
makeUnion
方法中指定
list
实例变量。。。我希望这不会影响现有的清单。循环的逻辑也有点问题-我希望
while
循环在
for
循环之后,但需要在循环中检查是否已用尽
其他
…这方面存在一些问题(例如,这不是mergesort的正确实现)。您需要有测试代码来证明add()、get()和size()正在工作。然后通过调用传递LinkedList的SortedLinkedList构造函数来测试实例化(如上面的代码所示),并且add()、get()、size()在实例化之后仍然有效。按照您的实例变量“link”所暗示的方式,我怀疑它们是否正常工作-似乎您在扩展一个Java列表类,但也使用了一个私有实例变量“List”。呵呵。我的灵力告诉我答案可能是replace
list=newlinkedlist()带有
链接列表=新建链接列表()但实际上,展示整个程序会有所帮助-任何答案都是猜测我们看不到的代码。对此表示抱歉。谢谢Jon提出这个问题,我现在修复了合并并处理了这些案例@米德,我不想让你们看到一团糟,这就是为什么我认为我可以只留下那个片段。很抱歉,变量列表在顶部声明。问题是makeUnion方法应该返回一个类构造函数类型的对象,所以我确定我声明temp的那一行是我出错的地方。让人恼火的是,让一个排序的列表扩展列表接口在概念上是错误的,因为你不能遵守列表契约——也就是说,元素是按插入顺序保留的。这就是为什么java中没有SortedList接口,而有一个SortedSet。因为这是家庭作业,我不允许使用Collections.sort或list.toArray->Arrays.sort。不幸的是,现在我感到非常愚蠢。谢谢你的见解…但有一个问题:当我这样做的时候,我仍然有义务让“列表”指向“这个”,这会给出“在构造函数中泄漏这个警告”。既然名单是私人的,这是安全的,对吗?现在我只需要弄清楚如何为merge方法构造temp对象……听起来您仍然拥有(并且正在使用)
private LinkedList
。继承的方法都不知道它,请停止使用它并从代码中删除实例变量。如果要在临时列表中进行排序,请使用一个局部变量,然后将排序后的元素添加到列表中(
)。很抱歉这么烦人,我在发布该评论后不久就发现了这一点(我的评论是正确的,但在代码中错过了一个实例……失眠会让人想起这一点),但我睡着了
LinkedList<Integer> unsorted = new LinkedList<Integer>();
unsorted.add(200);
unsorted.add(100);
unsorted.add(300);
SortedLinkedList<Integer> sorted = new SortedLinked<Integer>(unsorted);
System.out.println(sorted.get(0));
public SortedLinkedList<T> makeUnion( SortedLinkedList<T> other)
{
    LinkedList<T> temp = new LinkedList<T>();
    temp.addAll(this);
    temp.addAll(other);
    SortedLinkedList<T> merge = new SortedLinkedList(temp);
    return merge;
}