调用pop()时堆栈返回错误的项目

时间:2017-06-25 08:45:36

标签: java list stack push pop

我正在使用 Stack 类来推送List<Integer>并再次从堆栈中弹出该项:

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());
}

我在推送到堆栈后清理列表。

pushToStack函数输出日志:

推送项目:10

清算清单

清除后的

大小: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打印日志:

pop后的结果大小:0

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

我在这里做错了什么?

2 个答案:

答案 0 :(得分: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操作制作列表的副本;它只是存储了对堆栈中唯一列表的引用。

答案 1 :(得分:0)

所以,这就是程序正在做的事情:

  1. 在列表中添加10个元素
  2. 将该列表推送到堆栈
  3. 清除列表
  4. 从堆栈中弹出元素并检查大小
  5. 现在,在步骤2中,Stack已经具有该列表的引用,当它在步骤3中被清除时,引用具有包含0个元素的列表。 因此,在步骤4中,返回相同(空)列表,因此sysout打印0。

    如果您希望该堆栈保留旧列表,则可以执行

    mSearchResults = new ArrayList<>();
    

    而不是

    mSearchResults.clear();