2017-06-25 64 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(); 
相關問題