在迭代列表上编译失败

compile fail on iterating list

我有一个像这样的列表-[[1, 2, 3], [4, 5, 6, [1, 2, 3]]]

下面是我的代码-

    List<Object> inner1=new ArrayList<Object>();
    inner1.add(1);
    inner1.add(2);
    inner1.add(3);

    List<Object> inner2=new ArrayList<Object>();
    inner2.add(4);
    inner2.add(5);
    inner2.add(6);
    inner2.add(inner1);

    List<Object> outer=new ArrayList<Object>();
    outer.add(inner1);
    outer.add(inner2);

    System.out.println(outer);


    for(List<Object> list:(List<List<Object>>)outer){   //compile fail
        for(Object innerData:(List<Object>)list){
             if (innerData instanceof List) {
                for(Integer data: (List<Integer>)innerData){
                    System.out.println(data);
                }

            }else{
                System.out.println(innerData);
            }

        }
    }

为什么这个编译在迭代外部列表时失败。

我知道外部的所有对象都是 List<Object> 所以这是一个 List<List<Object>>

List<List<Object>> 中铸造外部结果是编译失败。

如果这不是想要的结果,这应该是 ClassCastException 而不是编译失败?

outer 不是 List<List<Object>>,所以你不能那样做。

您应该检查外部 List 的每个元素,看看它本身是否是一个 List。

for(Object obj : outer) {
    if (obj instanceof List) {
        List list = (List)obj;
        for(Object innerData: list) {
            if (innerData instanceof List) {
                for (Object obj2 : (List)innerData) {
                    if (obj2 instanceof Integer) {
                        Integer data = (Integer) obj2;
                        ...

编辑:

如果外层List只能包含List元素,可以通过将outer的类型改为List<List<Object>>来简化代码。

List<List<Object>> outer=new ArrayList<List<Object>>();

那么你将拥有

for(List<Object> list : outer) {
    for(Object innerData: list) {
        if (innerData instanceof List) {
            for (Object obj2 : (List)innerData) {
                if (obj2 instanceof Integer) {
                    Integer data = (Integer) obj2;
                    ...

outer 设为 List<List<Object>> 类型,您将根本不需要转换。

编译错误,因为你的外部类型是 List<Object> 无法转换为 List<List<Object>>

您的代码应该是:

for (Object list : outer) {  
    if (list instanceof List) {
        for (Object innerData : (List<Object>) list) {
            if (innerData instanceof List) {
                for (Integer data : (List<Integer>) innerData) {
                    System.out.println(data);
                }

            } else {
                System.out.println(innerData);
            }

        }
    }
}   

将第一个 for 循环更改为:

for (List<Object> list : (List<List<Object>>) (List) outer) {

虽然 List<Object> 肯定可以包含 List<Object> 类型的元素,但在类型系统的限制下,您不能说 List<Object> 可以转换为 [=14] =].

因为,您实际上也可以在列表中添加其他内容,例如 StringInteger。如果您随后尝试将其作为 List<List<Object>> 进行迭代,您会得到一些非常奇怪的结果(因为您无法将 IntegerString 转换为 List<Object>)

如果您 100% 确定您的列表外部不包含任何非 List<Object> 的内容,那么您可以告诉 Java 按照我描述的方式处理它以上。

但您应该意识到 Java 不是 LISP 或其他一些基于列表的函数式语言。

您正在做的是 Java 中非常不正确的数据建模方式。如果您不需要静态类型(以及您所有的转换和将事物视为 Object,这就是您正在做的),那么您不应该使用 Java 作为一种语言;选择另一种更适合您的问题领域的语言!

外部未定义为列表>。

像这样使用 -

for(Object list : outer){
    List<Object> o = (List<Object> list);
    // Remaining logic
}

for 循环的变化,

public static void main(String[] args) {
        List<Object> inner1 = new ArrayList<Object>();
        inner1.add(1);
        inner1.add(2);
        inner1.add(3);

        List<Object> inner2 = new ArrayList<Object>();
        inner2.add(4);
        inner2.add(5);
        inner2.add(6);
        inner2.add(inner1);

        List<Object> outer = new ArrayList<Object>();
        outer.add(inner1);
        outer.add(inner2);

        System.out.println(outer);

        for (Object list : outer) {
            if (list instanceof List) {
                for (Object innerData : (List<Object>) list) {
                    if (innerData instanceof List) {
                        for (Integer data : (List<Integer>) innerData) {
                            System.out.println(data);
                        }

                    } else {
                        System.out.println(innerData);
                    }

                }
            }
        }
    }

输出

[[1, 2, 3], [4, 5, 6, [1, 2, 3]]]
1
2
3
4
5
6
1
2
3

定义一个方法,如:

static void printFlat(Object object) {
    if (object instanceof List<?>)
        for (Object element : (List<?>)object)
            printFlat(element);
    else
        System.out.println(object);
}

    printFlat(outer);