7

I am attempting to convert an ArrayList of class SomeClass to an ArrayList of class Object. This new ArrayList of Object will then be passed to a function. I currently have done the following:

// convert ArrayList<SomeClass> to generic ArrayList<Object>

Object[] objectArray = someClassList.toArray();
ArrayList<Object> objects = new ArrayList<Object>();

for (int i = 0; i < objectArray.length; i++) {
    objects.add(objectArray[i]);
}

someFunction(objects);

public void someFunction(ArrayList<Object> objects) {
    // do something with objects
}

Is there a more efficient or "standard" way of doing this? Is what I am doing "wrong" in the first place?

The purpose of converting it to ArrayList of class Object is that I have created an external library to process ArrayList of generic Objects.

Lii
  • 11,553
  • 8
  • 64
  • 88
Acadian_Ghost
  • 238
  • 3
  • 15
  • 4
    Can you change the library that wants `ArrayList` input? It should probably be taking something like `ArrayList>` or `List>`. – user2357112 Nov 24 '15 at 17:48
  • Why not pass the original `ArrayList` directly, with a cast? – Kayaman Nov 24 '15 at 17:48
  • What external processing are you trying to do? – brso05 Nov 24 '15 at 17:48
  • just do `void someFunction(ArrayList> objects)`. It's effectively a list of objects then. You can't cast between generic types: http://stackoverflow.com/questions/2745265/is-listdog-a-subclass-of-listanimal-why-arent-javas-generics-implicitly-p – zapl Nov 24 '15 at 17:54
  • Great thanks. That points me in the right direction for some more research regarding the use of ArrayList>. – Acadian_Ghost Nov 24 '15 at 18:05

4 Answers4

7

If you are able to change the function's signature to taking an ArrayList<? extends Object> objects or an ArrayList<?> objects (or even better, List instead of ArrayList), you will be able to pass your ArrayList<SomeClass> directly.

The reason an ArrayList<SomeClass> is not an ArrayList<Object> is that an ArrayList<Object> would accept that you add() any kind of Object into it, which is not something you can do with an ArrayList<SomeClass>. On the other hand, an ArrayList<? extends Object> will allow you to retrieve elements from the list, but not add elements, so ArrayList<SomeClass> can safely be assigned to it.

Aasmund Eldhuset
  • 37,289
  • 4
  • 68
  • 81
  • 1
    I want to add the fact that `ArrayList>` is actually an abbreviation for `ArrayList extends Object>` -- they denote exactly the same type. – Lii Dec 25 '15 at 10:49
1

Since you created the external library, I think it would be easier to modify the function signature to accept lists of any type. This can be accomplished using the unbounded wildcard ?:

public static void someFunction(List<?> objects) {
    // whatever
}

Then you don't need to make any conversions to call it:

public static void main(String[] args) {
    List<String> words = new ArrayList<>();
    someFunction(words);
}

Also, unless you have a good reason not to, it would be better to accept any List in someFunction instead of limiting your input to ArrayLists. This makes your code more flexible and easier to change in the future.

Anderson Vieira
  • 8,919
  • 2
  • 37
  • 48
0

It is possible to transform the type parameters of a type in arbitrary ways with two casts:

ArrayList<SomeClass> l1 = ...;
ArrayList<Object> l2 = (ArrayList<Object>) (Object) l1;

But, as Aasmund Eldhuset also says in his answer: This is probably not a good idea! It is better to give a more suitable type to l2 instead, like ArrayList<?>.

This code gives you an compile warning saying Type safetyThat: Unchecked cast from Object to ArrayList<Object> for a reason. If for example a String is added to l2 and then someone reads l1 and expects a SomeClass they will get a very unexpected ClassCastException.

Lii
  • 11,553
  • 8
  • 64
  • 88
0

A simple way to convert a List<SubFoo> to a List<Foo> is to use Collections.unmodifiableList(listOfSubFoos), which is perfectly type-safe and actually enforces that you can't do anything bad with it (like adding a DifferentSubFoo).

Louis Wasserman
  • 191,574
  • 25
  • 345
  • 413