user4768611
user4768611

Reputation:

compile fail on iterating list

i have a list Like this-[[1, 2, 3], [4, 5, 6, [1, 2, 3]]]

below is my code-

    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);
            }

        }
    }

why this compile fail on iterating outer list.

I know all the Object in outer is of List<Object> so this is a List<List<Object>>

on casting outer in List<List<Object>> result is compile fail.

More over if this is not desired result this should be ClassCastException rather than compile fail?

Upvotes: 2

Views: 55

Answers (7)

user4910279
user4910279

Reputation:

Define a method like:

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

and

    printFlat(outer);

Upvotes: 0

Erwin Bolwidt
Erwin Bolwidt

Reputation: 31299

Change the first for-loop to:

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

Although a List<Object> could certainly contain elements of type List<Object>, you cannot, within the constraints of the type system, say that a List<Object> can be cast to List<List<Object>>.

Because, you could have actually put something else in the list as well, like a String or an Integer. And if you then tried to iterate over it as if it was a List<List<Object>>, you'd get some very weird results (because you can't cast Integer or String to List<Object>)

If you're 100% certain that your list outer doesn't contain anything that's not a List<Object>, then you can tell Java to treat it like that in the way that I described above.

But you should realize that Java is not LISP or some other heavily list-based functional language.

What you're doing is a very improper way of data-modelling in Java. If you don't need static typing (and with all your casts and treating things as Object, that's what you're doing), then you shouldn't be using Java as a language; pick another language that fits your problem domain better!

Upvotes: 0

Ankur Singhal
Ankur Singhal

Reputation: 26077

changes in for loop,

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);
                    }

                }
            }
        }
    }

output

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

Upvotes: 0

Eran
Eran

Reputation: 393936

outer is not a List<List<Object>>, so you can't cast it do that.

You should check each element of the outer List to see if it's a List itself.

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;
                        ...

EDIT:

If the outer List can contain only List elements, you can simplify the code by changing the type of outer to List<List<Object>>.

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

Then you'll have

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;
                    ...

Upvotes: 1

Raman Shrivastava
Raman Shrivastava

Reputation: 2953

Outer is not defined as List>.

Use it like this -

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

Upvotes: 0

codeaholicguy
codeaholicguy

Reputation: 1691

Compile error because your outer type is List<Object> cannot be cast to List<List<Object>>.

Your code should be:

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);
            }

        }
    }
}   

Upvotes: 1

Roger Gustavsson
Roger Gustavsson

Reputation: 1709

Make outerof type List<List<Object>> and you won't need to cast at all.

Upvotes: 0

Related Questions