如何从Java中的ArrayList中切出ArrayList?

时间:2009-09-26 07:20:43

标签: java arraylist

如何在Java中获取ArrayList的数组切片?具体来说,我想做这样的事情:

ArrayList<Integer> inputA = input.subList(0, input.size()/2);
// where 'input' is a prepouplated ArrayList<Integer>

所以我希望这可以工作,但Java返回List - 因此它不兼容。当我试图施展它时,Java不会让我。我需要ArrayList - 我该怎么办?

5 个答案:

答案 0 :(得分:104)

在Java中,最好使用接口类型而不是API中的具体类。

您的问题是您正在使用ArrayList(可能在很多地方),您应该使用List。因此,您使用不必要的约束为列表ArrayList创建了问题。

这就是你的代码应该是这样的:

List input = new ArrayList(...);

public void doSomething(List input) {
   List inputA = input.subList(0, input.size()/2);
   ...
}

this.doSomething(input);

你提出的解决问题的“解决方案”是:

new ArrayList(input.subList(0, input.size()/2))

通过制作子列表的副本来工作。它不是正常意义上的切片。此外,如果子列表很大,那么制作副本将是昂贵的。


如果您受到无法更改的API的约束,那么您必须inputA声明为ArrayList,您可能会能够实现ArrayList的自定义子类,其中subList方法返回ArrayList的子类。但是:

  1. 设计,实施和测试需要做很多工作。
  2. 您现在已经为您的代码库添加了重要的新类,可能依赖于ArrayList类的未记录方面(因此“可能会发生变化”)。
  3. 您需要更改代码库中创建ArrayList实例的相关位置,以创建子类的实例。
  4. “复制数组”解决方案更实用......请记住,这些不是真正的切片。

答案 1 :(得分:6)

如果没有现有方法,那么我猜你可以从0迭代到input.size()/2,获取每个连续元素并将其附加到新的ArrayList。

编辑:实际上,我认为您可以使用该列表并使用它来使用one of the ArrayList constructors实例化新的ArrayList。

答案 2 :(得分:4)

如果您知道需要从ArrayList中删除的元素的startIndex和endIndex,我找到了一种方法

al成为原始的ArrayList,startIndexendIndex分别是从数组中删除的开始和结束索引:

al.subList(startIndex, endIndex + 1).clear();

答案 3 :(得分:0)

尽管这篇文章很老。如果有人在找这个。。

番石榴有助于将列表划分为指定大小的子列表

List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8);
    List<List<Integer>> subSets = Lists.partition(intList, 3);

答案 4 :(得分:-5)

这就是我解决它的方式。我忘了子列表是对原始列表中元素的直接引用,所以它为什么不起作用是有道理的。

ArrayList inputA = new ArrayList(input.subList(0,input.size()/ 2));