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


80

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

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

因此,我希望这能够正常工作,但是Java返回List-,因此不兼容。而且当我尝试投射它时,Java不会让我这么做。我需要ArrayList-该怎么办?


4
为什么您坚持使用ArrayList?我认为您可能缺少一点了解接口如何工作的原因List,因为ArrayList它们不是“不兼容”的—ArrayList实现List,并且List可能包含您需要的所有必要方法。
孟买

2
我坚持使用ArrayList,因为它是带有刚性方法原型的inteview问题。我显然确实缺乏理解,因为subList应该返回List类型,但是我无法将返回的List转换为ArrayList。所以你告诉我男人..
BT

4
他完全有可能需要一个,ArrayList因为他随后需要使用接受一个的方法来调用该方法ArrayList。可以说,这种方法的设计很差,应该接受List,但是这种情况不仅会出现在面试问题中,还会出现在其他人编写的代码中,人们不能随便改变。同事和图书馆并不总是完美的。
重力

Answers:


124

在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为an ArrayList,则可以实现的自定义子类,ArrayList其中该subList方法将返回的子类ArrayList。然而:

  1. 设计,实施和测试将需要大量工作。
  2. 现在,您已经在代码库中添加了重要的新类,可能依赖于该类未记录方面(因此可能会发生更改)方面ArrayList
  3. 您需要在代码库中创建ArrayList实例的地方更改相关位置,以创建子类的实例。

“复制数组”解决方案更为实用……请记住,这些不是真实的切片。


5
实际上,subList不会复制。它返回一个视图到原来的列表(docs.oracle.com/javase/6/docs/api/java/util/...
马特

3
其实@Matthew,我指的是OP的自我解答功能:new ArrayList(input.subList(0, input.size()/2))
Stephen C

1
对于该词组+1:在Java中,优良作法是在API中使用接口类型而不是具体的类。
Ilonpilaaja

6

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

al是原始ArrayList和startIndexendIndex是开始和结束索引被分别从阵列中移除:

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

6

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

编辑:实际上,我认为您可以使用该List并使用ArrayList构造函数之一实例化新的ArrayList


2
那就是我所做的(在阅读您的修改之前先发布答案)。谢谢:)
英国电信2009年

但这会复制List以创建一个新的ArrayList。
Joren

2
@BT-根据记录,在这种情况下,“切片”一词通常不是什么意思。
Stephen C


-4

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

ArrayList<Integer> inputA = new ArrayList<Integer>(input.subList(0, input.size()/2));
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.