2017-06-25 46 views
0

我使用堆栈类从堆栈再次推List<Integer>和弹出项背:栈上调用pop()方法返回错误的项目

Stack<List<Integer>> mStack = new Stack<>(); 

public void pushToStack(View view){ 
    List<Integer> mSearchResults = new ArrayList<>(); 
    for(int i=0; i< 10;i++){ 
     mSearchResults.add(i); 
    } 
    Log.d(TAG,"Pushing item: " + mSearchResults.size()); 
    mStack.push(mSearchResults); 

    Log.d(TAG,"Clearing list"); 
    mSearchResults.clear(); 
    Log.d(TAG,"Size after clearing : " + mSearchResults.size()); 
} 

我推叠后结算清单。清除后

尺寸10

清除列表::

的pushToStack函数输出的日志:

推项0

public void popFromStack(View view){ 
    if(mStack.size() == 0){ 
     Log.d(TAG,"Stack is Empty"); 
    }else{ 
     List<Integer> searchResults = mStack.pop(); 
     Log.d(TAG,"Result size after pop: " + searchResults.size()); 
    } 
} 

和popFromStack首席TS日志:

结果大小弹出后:0

我不知道为什么mStack.pop()返回0作为列表项的大小而不是10

我在做什么错在这里?

+1

您正在推送堆栈中的列表,并清除该列表。你为什么期望清单不被清除?如果你把一个瓶子放在一个房间里,然后倒空那个瓶子,然后把瓶子从房间里拿出来,它将是空的,不是吗? –

+0

@JBNizet java通过值传递方法参数而不是引用。不是吗? – Pankaj

+1

它通过的值*是一个参考。任何非基本变量或参数都是对象的*引用*。请参阅[此答案](https://stackoverflow.com/a/40523/4125191)。 – RealSkeptic

回答

2

堆栈在调用pop()时不返回错误的项目。堆栈返回正确的项目。您可以通过以下验证这一点:

Log.d(TAG, "list: " + System.identityHashCode(searchResults)); 
Log.d(TAG, "list: " + System.identityHashCode(mSearchResults)); 

什么情况是,一个Stack<List<Integer>>包含有List<Integer>型这是一种对象类型的项目。在Java对象总是通过引用访问,这意味着一个Stack<List<Integer>>包含引用到整数列表。

这反过来意味着当您修改列表时,堆栈将继续保存对它的引用,所以无论您在列表上执行的任何更改都将可见。

本质上,push操作确实而不是做一个副本的列表;它只是将一个引用存储到堆栈上的唯一列表中。

0

所以,这是什么程序是这样做的:

  1. 添加列表中的
  2. 10个元素推动该列表到堆栈
  3. 清除列表
  4. 流行元素从栈并检查大小

现在,在第2步中,堆栈已经有该列表的引用,当它在步骤3中被清除时,引用然后有一个包含0个元素的列表。 因此,在步骤4中,相同的(空)名单被收回到因此,sysout打印0

如果希望堆栈保留旧列表,那么你可以做

mSearchResults = new ArrayList<>(); 

,而不是

mSearchResults.clear(); 
相关问题