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

Java 调用pop()时堆栈返回错误的项,java,list,stack,Java,List,Stack,我正在使用Stack类来推送List并再次从堆栈中弹出项目: Stack<List<Integer>> mStack = new Stack<>(); public void pushToStack(View view){ List<Integer> mSearchResults = new ArrayList<>(); for(int i=0; i< 10;i++){ mSearchResult

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

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());
}
Stack mStack=new Stack();
公共空间推土铲(视图){
List mSearchResults=new ArrayList();
对于(int i=0;i<10;i++){
添加(i);
}
Log.d(标记“pusing item:+mSearchResults.size());
mStack.push(mSearchResults);
日志d(标签“清算清单”);
mSearchResults.clear();
Log.d(标记“清除后的大小:”+mSearchResults.Size());
}
推到堆栈后,我正在清除列表

pushToStack功能输出日志:

推送项目:10

清算清单

清除后的大小:0

public void popFromStack(视图){
如果(mStack.size()==0){
Log.d(标记“堆栈为空”);
}否则{
List searchResults=mStack.pop();
Log.d(标签,“pop之后的结果大小:”+searchResults.size());
}
}
popFromStack打印日志:

pop后的结果大小:0

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


我做错了什么?

那么,程序就是这样做的:

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

    如果希望堆栈保留旧列表,则可以这样做

    mSearchResults = new ArrayList<>();
    

    所以,这就是程序所做的:

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

    如果希望堆栈保留旧列表,则可以这样做

    mSearchResults = new ArrayList<>();
    

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

    Log.d( TAG, "list: " + System.identityHashCode( searchResults ) );
    Log.d( TAG, "list: " + System.identityHashCode( mSearchResults ) );
    
    发生的情况是,
    堆栈
    包含类型为
    列表
    的项,该列表是对象类型。在java中,对象总是通过引用进行访问,这意味着
    堆栈包含对整数列表的引用

    这反过来意味着,当您修改列表时,堆栈将继续保存对它的引用,因此您对列表执行的任何更改都将可见


    本质上,
    push
    操作没有复制列表;它只是存储了对堆栈上唯一列表的引用。

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

    Log.d( TAG, "list: " + System.identityHashCode( searchResults ) );
    Log.d( TAG, "list: " + System.identityHashCode( mSearchResults ) );
    
    发生的情况是,
    堆栈
    包含类型为
    列表
    的项,该列表是对象类型。在java中,对象总是通过引用进行访问,这意味着
    堆栈包含对整数列表的引用

    这反过来意味着,当您修改列表时,堆栈将继续保存对它的引用,因此您对列表执行的任何更改都将可见


    本质上,
    push
    操作没有复制列表;它只是存储了对堆栈上唯一列表的引用。

    您正在堆栈上推送一个列表,并清除该列表。为什么你认为名单不会被清除?如果你把瓶子放在房间里,然后清空瓶子,然后把瓶子从房间里拿出来,瓶子会是空的,不是吗?@JBNizet java通过值而不是引用传递方法参数。不是吗?它传递的值是一个引用。任何非基本变量或参数都是对对象的引用。看,你正在堆栈上推送一个列表,并清除该列表。为什么你认为名单不会被清除?如果你把瓶子放在房间里,然后清空瓶子,然后把瓶子从房间里拿出来,瓶子会是空的,不是吗?@JBNizet java通过值而不是引用传递方法参数。不是吗?它传递的值是一个引用。任何非基本变量或参数都是对对象的引用。看见