我有我的代碼中的字符串列表。我將該字符串列表傳遞給一個函數並對其進行修改(我從列表中添加/刪除了少量元素)。但我不希望這些更改反映在調用者函數中。這些更改只應反映在被調用函數中。但是因爲對象是通過引用傳遞的,所以我認爲這兩個函數中的變化都會反映出來。我怎樣才能避免這一點。請幫助Java數組列表和對象傳遞
回答
可以使用Clone
方法。
caller(ArrayList<String> a)
{
callee((List<String>)a.clone());
}
callee(List<String> aCloned)
{
}
據我所知,'List'沒有'clone()'方法,因爲它沒有實現'Cloneable'。它的'ArrayList'就是這麼做的。 – SudoRahul 2013-03-26 05:23:16
@ R.J'List'是一個接口,因此它沒有任何方法。 '.clone()'方法在'Object'中定義,並且直覺上與'Cloneable'接口無關。檢查[文檔](http://docs.oracle.com/javase/7/docs/api/java/lang/Cloneable.html) – madth3 2013-03-26 05:28:37
@ madth3 - 感謝您糾正我。但是我的編輯仍然是正確的,因爲你仍然不能在'List
在將對象傳遞給函數之前,您必須複製對象。
在子方法中使用原始數組列表的新ArrayList。
裏面的方法,你可以明確地使列表的副本:
private void method(ArrayList<String> list) {
ArrayList<String> copy = new ArrayList<String>(list);
// Rest of the method
}
通常不建議使用clone
方法。看到這個clone(): ArrayList.clone() I thought does a shallow copy
不過你可以試試這個方法
public void doOperation(List<String> list){
List<String> duplicateList = new ArrayList(list);
// add, or delete stuff on duplicateList
}
在這裏,你使用ArrayList
的構造給你這是在傳遞的列表的新副本。
你必須使用循環手動從舊列表中創建新列表,並且需要傳遞給該方法。 即
List<String> list=new ArrayList<>();
list.add("first");
list.add("last");
List<String>list2 =new ArrayList<String>();
for(String value:list)
{
list2.add(new String(value));
}
System.out.println("list2-->"+list2);
new ArrayList<String>(list);
因爲是給列表的新的基準,但該對象仍然具有相同的參考。
編輯:
public class ArrayCopy {
public static void main(String[] args) {
ArrayCopy arrayCopy=new ArrayCopy();
arrayCopy.copyData();
}
public void copyData()
{
List<Test> oldList=new ArrayList<Test>();
oldList.add(new Test("1",10));
oldList.add(new Test("2",45));
List<Test> newList =new ArrayList<Test>(oldList);
System.out.println("newList-->"+newList);
/**
* New Copy of Data
*/
List<Test> newList1 =new ArrayList<Test>();
for(Test test:newList)
{
newList1.add(copyProperty(test));
}
System.out.println("newList-->"+newList1);
}
private Test copyProperty(Test test)
{
Test newTest=new Test(test.getId(), test.getNumber());
return newTest;
}
class Test{
String id;
int number;
public Test(String id,int number) {
this.id=id;
this.number=number;
}
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public int getNumber() {
return number;
}
public void setNumber(int number) {
this.number = number;
}
}
}
如果'list'中的對象可能會改變,那麼你會是對的,但由於'String's是不可變的,所以創建副本是沒用的。鑑於使用'ArrayList'構造函數的解決方案是好的。 'Cloneable'與'.clone()'方法無關。 – madth3 2013-03-26 05:47:57
@ madth3請參閱我的可編輯答案。它有測試對象。可以嗎?它仍然給予相同的客體參考。請參閱調試模式。 – iMBMT 2013-03-26 06:02:53
我一直都認爲兩個列表中的元素都是一樣的。我建議閱讀[不可變對象](http://www.javapractices.com/topic/TopicAction.do?Id=29)來理解爲什麼在某些情況下它並不重要。 – madth3 2013-03-26 06:16:21
- 1. 優雅傳遞列表和對象PARAMS
- 2. 初始數組對象和傳遞值
- 3. 傳遞對象列表或ArrayList對象
- 4. 對象和數組列表
- 5. 通過HTML表單傳遞對象的數組列表
- 6. 如何將對象數組傳遞給webAPI列表
- 7. 將JSON對象和對象列表傳遞給ASP.Net控制器
- 8. 在C#中通過引用傳遞對象和對象列表#
- 9. Java - 複製數組列表對象
- 10. 轉換JSON數組Java列表對象
- 11. 將php對象傳入java中的數組/列表中
- 12. 將對象數組傳遞給函數
- 13. 將參數數組對象傳遞出
- 14. C#比較列表對象和傳遞的參數
- 15. java rmi傳遞ImageIcon對象
- 16. java:傳遞一個對象
- 17. 在Java中傳遞對象
- 18. Java RMI - 傳遞對象
- 19. Java - 創建一個傳遞數組作爲參數的對象
- 20. 如何在Java中傳遞對象數組作爲參數
- 21. Java對象和數組
- 22. 傳遞對象到接受PARAM列表
- 23. 使用MVC Razor傳遞列表對象
- 24. 在ServiceStack中傳遞對象列表
- 25. 如何階陣列[對象]傳遞到Java函數參數
- 26. 傳遞對象數組到方法
- 27. Angular2 @input傳遞數組對象
- 28. WebScriptObject傳遞NSDictionary(關聯數組/對象)
- 29. jQuery傳遞變量到對象數組
- 30. 從數組傳遞值到對象? - PHP
的ArrayList newArrayList =(ArrayList的)oldArrayList.clone(); – Code2Interface 2013-03-26 05:15:44
增加了額外的位:如果列表中的對象不是不可變的,請注意列表中的對象也可以在被調用函數中更改。列表克隆將創建淺拷貝而不是深拷貝。所以如果你想保護列表中的對象1)做深層克隆2)使對象不可變。 – 2013-03-26 05:23:13