0

I'm doing a beginner Java tutorial on ArrayList that asks me to do the below

// Create a method called removeOdd
    // Remove all the odd numbers from an ArrayList 

    // removeOdd(Arrays.asList(1,2,3,5,8,13,21)) => {2, 8}
    // removeOdd(Arrays.asList(7,34,2,3,4,62,3)) => {34, 2, 4, 62}

The below is my code

import java.util.ArrayList;
import java.util.Arrays;


public class Ex4_RemoveOdd {

    public static void main(String[] args) {

        removeOdd((ArrayList<Integer>) Arrays.asList(1,2,3,5,8,13,21));
        removeOdd((ArrayList<Integer>) Arrays.asList(7,34,2,3,4,62,3));
    }

    public static void removeOdd(ArrayList<Integer> list){
        for (int i = 0; i < list.size(); i++){
            int num = list.get(i);
            if (num % 2 != 0){
                list.remove(i);
            }
        }
        System.out.println(list);
    }
}

The code runs, but gives me the below error code

Exception in thread "main" java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList

Does anyone know what I did wrong?

I understand there is another similar question on SO

However I kind of think our situations are different since the OP did not declare a list within a method using AsList like I did.

Thanks so much for your time :)

5
  • 7
    What you did wrong: not read the api documentation of Arrays.asList(). Does it say it returns an ArrayList? Does it say that the returned list has a variable size? Everything becomes easier, and you learn a lot, when you read the documentation. Commented Jan 14, 2015 at 22:28
  • I wonder whether System.out.println(list) would output anything meaningful here. Commented Jan 14, 2015 at 22:30
  • Also, even if you don't cast and return a List<Integer>, you'll get an UnsupportedOperationException if you try to remove a value from a fixed array (hint: don't use Arrays.asList for this task) Commented Jan 14, 2015 at 22:31
  • @ValentinRuano well I fixed the code and System.out.println(list) does print meaningful output in my case. I get [2, 5, 8, 21] for my first run of the removeOdd method Commented Jan 14, 2015 at 23:01
  • @JBNizet @spudone yea the problem is that the question itself told me to use removeOdd(Arrays.asList(1,2,3,5,8,13,21)), so as a beginner I got confused between what the api was saying and what the question was saying :/ That being said, I'll make sure to trust the API more than the question in the future Commented Jan 14, 2015 at 23:03

3 Answers 3

3

The method Arrays.asList returns a List, but it's not java.util.ArrayList. It's a private nested class ArrayList, nested inside Arrays, and it's different. It doesn't support addition or removal of the generated list.

To make an actual java.util.ArrayList, pass the List to the proper ArrayList constructor, that takes a Collection, e.g.

removeOdd(new ArrayList<Integer>(Arrays.asList(1, 2, 3, 5, 8, 13, 21)));

As for why the inner class is referred to as java.util.Arrays$ArrayList, that is because the the dollar sign $ separates the enclosing class name from the nested class name.

Sign up to request clarification or add additional context in comments.

6 Comments

(Why it was called ArrayList instead of something more fitting and less name-clashing .. but it is what it is.)
@user2864740 Because it is also List which internally uses array as container for elements. But I agree name could be better.
To me, ..$ArrayList seems pretty close to ArrayList - and I doubt such has reduced the OPs confusion. If it were Arrays$ArrayWrapperList I would clearly go, "wait, uh what?!?"
@user2864740 the name of the class is Arrays$ArrayList, not ArrayList, so they're clearly not the same. Period.
@user2864740 I would go with something like ArrayWrappingList, because ArrayWrapperList feels more like Wrapper for ArrayList (which may also be confusing) but I don't remember seeing any class names with ...ing part, so I suspect such name could be also considered as bad.
|
1

Does anyone know what I did wrong?

There are two classes called ArrayList one you can use directly and one you shouldn't. You can't cast one to the other just because they happen to have the same name.

Fortunately you don't need to be doing this in the first place as you don't need to specify that an ArrayList is required. You can write it such that any mutable list can be passed. BTW Arras.aslIst is a fixed length so you can't use it here.

Instead I would suggest not altering you list but rather printing the result.

printEven(Arrays.asList(1,2,3,5,8,13,21));
printEven(Arrays.asList(7,34,2,3,4,62,3));

public static void removeOdd(Iterable<Integer> list) {
    List<Integer> even = new ArrayList<>();
    for (integer i: list) if (i %2 == ) even.add(i);
    System.out.println(even);
}

Comments

0

The problem is here:

removeOdd((ArrayList<Integer>) Arrays.asList(1,2,3,5,8,13,21));

An ArrayList is not the same as the List returned by Arrays#asList, and the stacktrace is telling you:

Exception in thread "main" java.lang.ClassCastException: java.util.Arrays$ArrayList cannot be cast to java.util.ArrayList

Create a new ArrayList and pass the List returned from Arrays#asList as argument:

removeOdd(new ArrayList<Integer>(Arrays.asList(1,2,3,5,8,13,21)));

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.