谁能告诉我为什么这会返回一个空列表(NPE)?
我有这段代码,应该将 SortedLinkedList
的两个实例合并到一个 SLL 中(基于 mergeSort 合并),但返回一个空列表:
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);
}
}
在 SLL 构造函数中,我让它简单地返回null
list (私有变量 list 在此方法的第一行初始化)。然而,据我所知,这仍然应该给我一个 SLL 对象(最初也是 null
)。我可以在方法本身中很好地添加到 temp ,但在打印列表时会出现 NullPointerException 。
我意识到将 get 与 LinkedList
一起使用并不是很有效。解决这个问题后我会用迭代器切换它们。
任何提示将不胜感激。
编辑:有趣的是,如果我将两个列表放入临时 LL 中,然后在其上使用构造函数,我会得到相同的结果。这些类型是兼容的,因为 SLL 扩展了 LL:
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;
}
EDIT2:看来 @Mead 是正确的...虽然 size() 和 get() 似乎适用于 SLL,但 add() 则不然。我想既然我扩展了 LinkedList,它也可以与 SLL 一起使用。它没有,并且覆盖它们也没有任何作用......我对此没有想法。建议?
I have this code that is supposed to merge two instances of SortedLinkedList
into one SLL (based on mergeSort merge), but is returning an empty list instead:
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);
}
}
In the SLL constructor, I have it simply return on a null
list (and the private variable, list, is initialized in the first line of this method). However from what I know, this should still give me an SLL object (initially also null
). I can add to temp just fine in the method itself, but get a NullPointerException
when printing the list.
I realize it's not very efficient to use get with LinkedList
. I'll switch them with an iterator after I settle this.
Any hints would be quite appreciated.
EDIT: Interestingly, I get the same result if I put both lists in a temporary LL and then use the constructor on it. The types are compatible since SLL extends LL:
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;
}
EDIT2: It seems @Mead was correct... while size() and get() seem to work for the SLL, add() does not. I was thinking that since I'm extending LinkedList, it would work with the SLL as well. It didn't, and overriding them did nothing as well... I'm out of ideas for this. Suggestions?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
查看实现后只是好奇,但是您不能先执行 .addAll(...) ,然后执行 Collections.sort(...) 吗?这就是我个人所希望的。
just curious after looking at the implementation, but couldn't you have just done a .addAll(...) followed by a Collections.sort(...)? That's what I would have preferred personally.
伟大的!您的编辑几乎揭示了您的问题:您没有正确扩展 LinkedList。解决这个问题,然后致力于工会。
当前的问题:这是一个名为
SortedLinkedList
的类。我们可以假设它就像 LinkedList 一样,但其中的值是排序的。因此,考虑到这一点,这应该有效:但它不会。运行你的代码,它会打印出什么?
后退?为什么打印出来是这样的?首先,考虑可以在类代码中使用的两个变量:
this
引用 SortedLinkedList 对象,this.list
引用该 SortedLinkedList 对象内的实例变量。然后让我们看看构造函数:当您添加到列表时,您将调用this.list.add()
。您所编写的内容使 SortedLinkedList 成为list
实例变量的包装器 - 您不是添加到 SortedLinkedList (this
) 中,而是添加到其中的列表 (this.list
)。使用
this.list
实例变量的唯一方法是构造函数、print 和 makeUnion。所有其他 LinkedList 方法都不知道list
变量,因此当我调用 get():它不知道查看您的
this.list
变量,所以它不会打印 100 份。事实上,它会崩溃,因为索引 0 中没有值。您没有添加到 get() 实际使用的实例变量,因此该方法认为 SortedLinkedList 对象是空的。this.list
是继承方法不知道的新变量。因此,如果我们检查您的最新编辑:
temp.addAll(this)
不起作用,因为this
的所有方法都认为该列表为空,因为它们是不看this.list
。出于同样的原因,temp.addAll(other)
也不起作用。扩展类时常见的情况是您希望现有方法继续工作。这意味着您需要将数据存储在 get() 和其他方法期望的位置。你是怎么做到的?好吧,你已经在这么做了! 您已经在做正确的事情 - 但您是在实例变量
this.list
而不是this
上执行此操作。开始调用this.add()
、this.set()
、this.size()
而不是this.list.add ()
并完全删除实例变量list
- 不需要,你有this
。然后数据将位于其他方法期望的位置。(并在构造函数的第一行调用 super() ,因此调用超类构造函数中的代码)。祝你的作业好运 - 我建议在添加新方法之前测试对象的工作原理。
Great! Your edit pretty much reveals your problem: you're not extending the LinkedList properly. Fix that, and then work on union.
The problem at hand: This is a class called
SortedLinkedList
. We can assume it's meant to be just like LinkedList, but the values in it are sorted. So, given that, this should work:But it will not. Run your code, what does it print out?
Back? Why did it print out that? First, consider two variables you can use in the class's code:
this
refers to the SortedLinkedList object, andthis.list
refers to an instance variable inside that SortedLinkedList object. Then let's look at the constructor: when you add to the list, you're callingthis.list.add()
. What you have written makes SortedLinkedList a wrapper around thelist
instance variable - you're not adding to the SortedLinkedList (this
) you are adding to a list inside that (this.list
).The only methods that use your
this.list
instance variable are the constructor, print, and makeUnion. All the other LinkedList methods aren't aware of thelist
variable, so when I call get():It doesn't know to look in your
this.list
variable, so it won't get 100 to print. In fact, it will crash because there is no value in index 0. You didn't add to the instance variables that get() actually uses, so the methods think that SortedLinkedList object is empty.this.list
is a new variable that the inheritted methods don't know about.So, if we examine your latest edit:
temp.addAll(this)
doesn't work, because all the methods ofthis
think that the list is empty because they're not looking atthis.list
.temp.addAll(other)
doesn't work either, for the same reason.What is common when you extend classes is that you want the existing methods to continue working. This means that you need to store the data where get() and other methods expect it to be. How do you do that? Well, you're already doing it! You are already doing the right thing - but you are doing it on the instance variable
this.list
instead ofthis
. Start callingthis.add()
,this.set()
,this.size()
instead ofthis.list.add()
and remove the instance variablelist
completely - it's not needed, you havethis
. Then the data will be where the other methods expect it to be.(And call super() on the first line of your constructor, so the code in the super class's constructor is called). Good luck on your homework - I'd recommend testing the object works as-is before adding new methods.