如何在Java中获取有效的子列表?

26

我在Java中遇到了一个奇怪的问题。 我有一个ArrayList,想要取其中的子列表。 但我却得到了以下异常:

package javatest;

import java.util.ArrayList;

public class JavaTest {

    public static void main(String[] args) {
        ArrayList<Integer> alist = new ArrayList<Integer>();
        alist.add(10);
        alist.add(20);
        alist.add(30);
        alist.add(40);
        alist.add(50);
        alist.add(60);
        alist.add(70);
        alist.add(80);
        ArrayList<Integer> sub = (ArrayList<Integer>) alist.subList(2, 4);
        for (Integer i : sub)
            System.out.println(i);
    }
}

运行时出现异常:“main”线程中的java.lang.ClassCastException:java.util.RandomAccessSubList无法转换为java.util.ArrayList,在javatest.JavaTest.main(JavaTest.java:17)处;Java结果:1

如何正确地获取子列表?

谢谢


1
坚持使用接口列表而不是实现,你就会没问题。请参考zeropage的答案。 - Santosh Gokak
6个回答

46

将其变为:

List sublist = new ArrayList();
sublist = new ArrayList<String>(alist.subList(2, 4));

它应该可以正常工作


1
这是非常不正确的。第一行代码完全没有作用,它创建了一个新的Array list,但在下一行创建一个新的ArraysList<String>时就被丢弃了。新的ArrayList是用alist.subList返回的值初始化的。而alist.subList实际上是支持alist的子列表,两者是非常不同的。 - Howard Swope

24

尽可能使用集合的界面进行工作。您正在将子列表的结果向下转换,但API指定它返回List而不是ArrayList)。在这里,实现者选择返回不同类型以使他们的生活更轻松。

此外,API文档指定子列表将返回映射到原始列表上的List,所以要小心!


5
我原本期望 FooList 的子列表仍然是一个 FooList,我觉得这是合理的想法。不管怎样,谢谢 :) - George Kastrinis

8

试试这个...

List<Integer> alist = new ArrayList<Integer>();
alist.add(10);
alist.add(20);
alist.add(30);
alist.add(40);
alist.add(50);
alist.add(60);
alist.add(70);
alist.add(80);
List<Integer> sub = alist.subList(2, 4);
for (Integer i : sub)
  System.out.println(i);

3

尝试

List<Integer> sub = alist.subList(2, 4);

2
    public List<E> subList(int fromIndex, int toIndex) {
    return (this instanceof RandomAccess ?
            new RandomAccessSubList<E>(this, fromIndex, toIndex) :
            new SubList<E>(this, fromIndex, toIndex));
    }

就像在ArrayList的实现中一样,它返回List,正如@George Kastrinis所说,尽可能使用接口。


0

将代码改为:

List<Integer> sub = alist.subList(2, 4);

sublist() 方法返回一个 List,它不一定是一个 ArrayList(这里实际上是一个 RandomAccessSublist,所以强制转换失败)。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接