2017-08-26 41 views
2

我有两个ArrayList。我只想重用第二个ArrayList(temporaryArrayList)。请注意我的代码。希望你当然会理解我想让你知道的事情。有没有什么办法重用java中的arraylist?

ArrayList<ArrayList<String>> arrayListContainer = new ArrayList<>(); 
    ArrayList<String> temporaryArrayList = new ArrayList<>(); 

    temporaryArrayList.add("I"); 
    temporaryArrayList.add("you"); 
    temporaryArrayList.add("he"); 
    temporaryArrayList.add("she"); 
    temporaryArrayList.add("we"); 

    arrayListContainer.add(temporaryArrayList); 

    temporaryArrayList.clear(); 

    temporaryArrayList.add("Rahim"); 
    temporaryArrayList.add("jon"); 
    temporaryArrayList.add("don"); 
    temporaryArrayList.add("shaila"); 

    arrayListContainer.add(temporaryArrayList); 
    temporaryArrayList.clear(); 


    System.out.println(arrayListContainer.size()); 

的代码是给arrayListContainer的预期大小,但是没有得到预期的结果为

System.out.println(arrayListContainer.get(0).get(0)); 

我怎样才能做到这一点。谢天谢地接受任何形式的回复或建议。

+0

的另一种自然的方式,你在期待'的System.out.println(arrayListContainer.get(0)获得(0));'为你带来? – d512

+0

为什么你想重新使用'temporaryArrayList'?正如答案指出的那样,无论如何你都必须复制它。所以没有任何储蓄,只有更多的困惑。 – Thilo

+0

我需要一个类型arraylist的arraylist为我的项目.. – Sadhon

回答

3

您正在添加相同的对象并将其删除。 为了不同温度-列表添加到arrayListContainer你应该创建一个副本:

变化是做线:

arrayListContainer.add(temporaryArrayList); 

到:

ArrayList<String> copy = new ArrayList<>(temporaryArrayList) 
arrayListContainer.add(copy); 

另一种选择,因为蒂洛在下面的评论中建议每次都会创建一个新的temporaryArrayList,这样你就可以确保将不同的临时列表添加到arrayListContainer

+2

...或者只是不要重用temporaryArrayList。更干净。 – Thilo

2

您需要在添加它时创建ArrayList的克隆,否则当删除内容时,您将删除刚刚添加的实际列表的内容。克隆它将添加ArrayList的副本,而不是原始副本。

编辑:其实 - 基于对对方的回答蒂洛的评论 - 一个更好的解决办法是临时的ArrayList代码提取到一个方法,并调用它:

public static void main(String[] args){ 

    ArrayList<ArrayList<String>> arrayListContainer = new ArrayList<>(); 

    String[] a = {"I","you","he"}; 
    arrayListContainer.add(createArrayList(a)); 
    String[] b = {"Bob","Rahim","Betty"}; 
    arrayListContainer.add(createArrayList(b)); 

    System.out.println(arrayListContainer.size()); 
    System.out.println(arrayListContainer.get(0).get(0)); 
} 

private static ArrayList<String> createArrayList(String[] arr) { 
    ArrayList<String> temporaryArrayList= new ArrayList<>(); 
    for(String str : arr) { 
     temporaryArrayList.add(str); 
    } 
    return temporaryArrayList; 
} 
1

你不能在重复使用你想要的方式。您的ArrayList<ArrayList<String>>包含参考到对象(​​在这种情况下,参考ArrayList<String>)。如果你说

arrayListContainer.add(temporaryArrayList); 

后来,

arrayListContainer.add(temporaryArrayList); 

之间没有分配一个新的价值temporaryArrayList,你arrayListContainer将有两个引用同一个对象。 temporaryArrayList是对象的引用,即使对象的内容发生变化(除非您重新分配一个全新的对象),它也不会改变。

您需要创建一个新对象。

1

你的情况,你不需要数组列表数组列表,只让字符串数组的数组列表:

ArrayList<String[]> arrayContainer = new ArrayList<>(); 

添加完字符串,请致电:

arrayContainer.add(temporaryArrayList.toArray(new String[temporaryArrayList.size()])); 

这样你可以安全地重用临时数组列表。

2

其他答案是正确的。你重复使用你的第二个ArrayList,而不是你想要的方式。

您需要了解(a)对对象的引用,以及(b)ArrayList是一个对象,该对象是对其他对象的引用的容器。

让我们看看代码执行期间的状态。

首先实例化一个ArrayList,其默认值为10个插槽。将持有对引用String对象的其他ArrayList实例的引用。

ArrayList< ArrayList<String> > arrayListContainer = new ArrayList<>(); 

enter image description here

ArrayList<String> temporaryArrayList = new ArrayList<>() ; 

enter image description here

String实例化对象,添加在我们的第二列表中的狭槽的每一个参考。请记住,该列表包含参考String对象,而不是对象本身。

temporaryArrayList.add("I") ; 
temporaryArrayList.add("you") ; 
temporaryArrayList.add("he") ; 
temporaryArrayList.add("she") ; 
temporaryArrayList.add("we") ; 

enter image description here

到第二列表添加一个参考第一列表的第一时隙。

arrayListContainer.add(temporaryArrayList) ; 

enter image description here

通过调用clear()删除对String对象与代词的所有引用。这些String对象实际上在内存中存在了一段时间,因此成为垃圾收集的候选对象,因为它们未被任何其他对象引用。所以我们在这个图表中显示它们已经消失了,但实际上它们可能会在内存中浮动一段时间。

temporaryArrayList.clear() ; 

enter image description here

实例化一些新String对象。在第二个列表的插槽中提供每个参考。

temporaryArrayList.add("Rahim") ; 
temporaryArrayList.add("jon") ; 
temporaryArrayList.add("don") ; 
temporaryArrayList.add("shaila") ; 

enter image description here

这是你的误会出现的地方。你显然想要保留代词并在他们旁边添加一些专有名称。但第一个列表不包含对String对象的引用,它保存对String对象的ArrayList的引用。因此,我们最终得到了两个对包含对专有名称字符串的引用的对象ArrayList的引用。旧的代词字符串可能会或可能不会在记忆中浮动,但我们无法再接触到它们,所以我们认为它们已经消失。

arrayListContainer.add(temporaryArrayList) ; 

enter image description here

下一页清除字符串的一个且唯一的列表。所以现在第一个ArrayList持有两个引用到现在空的第二个ArrayList

temporaryArrayList.clear() ; 

enter image description here

你结束了,其中每个元素是指向同一个空“临时”列表中的两个元素的一个列表。

如果您想积累第一个列表中的字符串,请将第一个列表重新定义为StringArrayList而不是ArrayList<String>。所以,与其这样:

​​

...这个,改变addaddAll

ArrayList<String> arrayListContainer = new ArrayList<>() ; 
ArrayList<String> temporaryArrayList = new ArrayList<>() ; 
… 
arrayListContainer.addAll(temporaryArrayList) ; // Call `addAll` to add the elements of one collection to another collection. 

提示:尽可能使用接口。

通常最好指定更通用的接口而不是具体的类,以便您可以更轻松地切换出具体的类;所以你可以使用ListList< List<String> >

List<List<String>> listContainer = new ArrayList<>(); 
1
ArrayList<ArrayList<String>> arrayListContainer = new ArrayList<>(); 
    ArrayList<String> temporaryArrayList = new ArrayList<>(); 

    temporaryArrayList.add("I"); 
    temporaryArrayList.add("you"); 
    temporaryArrayList.add("he"); 
    temporaryArrayList.add("she"); 
    temporaryArrayList.add("we"); 

    arrayListContainer.add(new ArrayList<>(temporaryArrayList)); 

    temporaryArrayList.clear(); 

    temporaryArrayList.add("Rahim"); 
    temporaryArrayList.add("jon"); 
    temporaryArrayList.add("don"); 
    temporaryArrayList.add("shaila"); 

    arrayListContainer.add(new ArrayList<>(temporaryArrayList)); 
    temporaryArrayList.clear(); 


    System.out.println(arrayListContainer.get(0).get(0)); 

这是克隆的对象:)

相关问题