如何在 Java 中从 ArrayList 中切出 ArrayList?
Posted
技术标签:
【中文标题】如何在 Java 中从 ArrayList 中切出 ArrayList?【英文标题】:How can I slice an ArrayList out of an ArrayList in Java? 【发布时间】:2010-12-01 15:03:09 【问题描述】:如何在 Java 中获取 ArrayList
的数组切片?具体来说,我想做这样的事情:
ArrayList<Integer> inputA = input.subList(0, input.size()/2);
// where 'input' is a prepouplated ArrayList<Integer>
所以我希望这可以工作,但 Java 返回一个 List
- 所以它是不兼容的。当我尝试转换它时,Java 不会让我这样做。我需要ArrayList
- 我该怎么办?
【问题讨论】:
你为什么坚持使用ArrayList
?我认为您可能对接口的工作方式缺乏了解,因为List
和ArrayList
并非“不兼容”——ArrayList
实现了List
,而List
可能包含您需要的所有必要方法。
我坚持使用ArrayList,因为它是一个带有严格方法原型的inteview问题。我显然缺乏理解,因为 subList 应该返回一个 List 类型,但我不能将返回的 List 转换为 ArrayList。所以你告诉我男人..
他完全有可能需要一个ArrayList
,因为他需要用它调用一个接受ArrayList
的方法。可以说这种方法设计得很糟糕,应该接受List
,但这种情况不仅会出现在面试问题中,而且会出现在其他人编写的代码中,不能随便更改。同事和图书馆并不总是完美的。
见***.com/questions/1279476/…
【参考方案1】:
在 Java 中,使用接口类型而不是 API 中的具体类是一种很好的做法。
您的问题是您1 正在使用ArrayList
(可能在很多地方)您真正应该使用List
。结果,您为自己制造了一个不必要的限制,即列表是ArrayList
。
你的代码应该是这样的:
List input = new ArrayList(...);
public void doSomething(List input)
List inputA = input.subList(0, input.size()/2);
...
this.doSomething(input);
1 - 根据您的 cmets,“您”实际上是其他人......在面试问题中提出了这个问题。这可能实际上是一个技巧问题,旨在了解如何处理创建与 ArrayList
兼容的分配的 ArrayList
的(真实)切片。
您对问题提出的“解决方案”是/是这样的:
new ArrayList(input.subList(0, input.size()/2))
这可以通过制作子列表的副本来实现。它不是正常意义上的切片。此外,如果子列表很大,那么制作副本会很昂贵。
如果您受限于您无法更改的 API,以至于您必须将 inputA
声明为 ArrayList
,您或许可以实现一个ArrayList
的自定义子类,其中subList
方法返回ArrayList
的子类。然而:
-
设计、实施和测试工作量很大。
您现在已经在代码库中添加了重要的新类,可能依赖于
ArrayList
类的未记录方面(因此“可能发生变化”)方面。
您需要更改代码库中创建 ArrayList
实例的相关位置,以改为创建子类的实例。
“复制数组”解决方案更实用……请记住,这些不是真正的切片。
【讨论】:
其实subList不会做拷贝;它返回原始列表中的视图 (docs.oracle.com/javase/6/docs/api/java/util/…) 实际上@Matthew,我指的是他这样做的 OP 的自我回答:new ArrayList(input.subList(0, input.size()/2))
+1 表示这句话:在 Java 中,使用接口类型而不是 API 中的具体类是一种很好的做法。【参考方案2】:
如果您知道需要从 ArrayList 中删除的元素的 startIndex 和 endIndex,我已经找到了一种方法
让al
是原始的ArrayList 和startIndex
,endIndex
分别是要从数组中删除的开始和结束索引:
al.subList(startIndex, endIndex + 1).clear();
【讨论】:
【参考方案3】:如果没有现有方法,那么我猜你可以从 0 迭代到 input.size()/2
,获取每个连续元素并将其附加到新的 ArrayList。
编辑:实际上,我认为您可以使用该 List 并使用 one of the ArrayList constructors 实例化一个新的 ArrayList。
【讨论】:
这正是我所做的(在我阅读您的编辑之前发布了我的答案)。谢谢:) 但是 复制 List 以创建一个新的 ArrayList。 @BT - 郑重声明,这不是“切片”一词在此上下文中的通常含义。【参考方案4】:虽然这篇文章很老了。万一有人在找这个..
Guava 有助于将 List 划分为指定大小的子列表
List<Integer> intList = Lists.newArrayList(1, 2, 3, 4, 5, 6, 7, 8);
List<List<Integer>> subSets = Lists.partition(intList, 3);
【讨论】:
Guava Lists 文档的快速链接:google.github.io/guava/releases/19.0/api/docs/com/google/common/…【参考方案5】:我就是这样解决的。我忘记了 sublist 是对原始列表中元素的直接引用,所以它为什么不起作用是有道理的。
ArrayList<Integer> inputA = new ArrayList<Integer>(input.subList(0, input.size()/2));
【讨论】:
以上是关于如何在 Java 中从 ArrayList 中切出 ArrayList?的主要内容,如果未能解决你的问题,请参考以下文章