我正在使用 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。
我在这里做错了什么?
答案 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)
所以,这就是程序正在做的事情:
现在,在步骤2中,Stack已经具有该列表的引用,当它在步骤3中被清除时,引用具有包含0个元素的列表。
因此,在步骤4中,返回相同(空)列表,因此sysout
打印0。
如果您希望该堆栈保留旧列表,则可以执行
mSearchResults = new ArrayList<>();
而不是
mSearchResults.clear();