How to cast ArrayList<> from List<>

JavaGenericsCasting

Java Problem Overview


Can somebody please explain me why I can't cast List<> to ArrayList<> with first approach and I do with second one? Thank you.

First approach:

ArrayList<Task> tmp = ((ArrayList<Task>)mTrackytAdapter.getAllTasks(token));

Second approach:

ArrayList<Task> tmp = new ArrayList<Task>(mTrackytAdapter.getAllTasks(token));

Java Solutions


Solution 1 - Java

When you do the second one, you're making a new arraylist, you're not trying to pretend the other list is an arraylist.

I mean, what if the original list is implemented as a linkedlist, or some custom list? You won't know. The second approach is preferred if you really need to make an arraylist from the result. But you can just leave it as a list, that's one of the best advantages of using Interfaces!

Solution 2 - Java

When you are using second approach you are initializing arraylist with its predefined values. Like generally we do ArrayList listofStrings = new ArrayList<>(); Let's say you have an array with values, now you want to convert this array into arraylist.

you need to first get the list from the array using Arrays utils. Because the ArrayList is concrete type that implement List interface. It is not guaranteed that method asList, will return this type of implementation.

List<String>  listofOptions = (List<String>) Arrays.asList(options);

then you can user constructoru of an arraylist to instantiate with predefined values.

ArrayList<String> arrlistofOptions = new ArrayList<String>(list);

So your second approach is working that you have passed values which will intantiate arraylist with the list elements.

More over

ArrayList that is returned from Arrays.asList is not an actual arraylist, it is just a wrapper which doesnt allows any modification in the list. If you try to add or remove over Arrays.asList it will give you

> UnsupportedOperationException

Solution 3 - Java

Try running the following code:

List<String> listOfString = Arrays.asList("Hello", "World");
ArrayList<String> arrayListOfString = new ArrayList(listOfString);
System.out.println(listOfString.getClass());
System.out.println(arrayListOfString.getClass());

You'll get the following result:

class java.util.Arrays$ArrayList
class java.util.ArrayList

So, that means they're 2 different classes that aren't extending each other. java.util.Arrays$ArrayList signifies the private class named ArrayList (inner class of Arrays class) and java.util.ArrayList signifies the public class named ArrayList. Thus, casting from java.util.Arrays$ArrayList to java.util.ArrayList and vice versa are irrelevant/not available.

Solution 4 - Java

The second approach is clearly wrong if you want to cast. It instantiate a new ArrayList.

However the first approach should work just fine, if and only if getAllTasks return an ArrayList.

It is really needed for you to have an ArrayList ? isn't the List interface enough ? What you are doing can leads to Runtime Exception if the type isn't correct.

If getAllTasks() return an ArrayList you should change the return type in the class definition and then you won't need a cast and if it's returning something else, you can't cast to ArrayList.

Solution 5 - Java

Just try this :

ArrayList<SomeClass> arrayList;

 public SomeConstructor(List<SomeClass> listData) {
        arrayList.addAll(listData);
}

Solution 6 - Java

You can cast List<> to ArrayList<> if you understand what you doing. Java compiler won't block it.

But:

  1. It's bad practice to casting parent type to child type (or interface to implementation type) without checking. This way better:

if (list instanceof ArrayList<Task>) { ArrayList<Task> arraylist = (ArrayList<Task>) list; }

  1. Maybe you don't need implementation type as reference. Look SonarQube warning https://sbforge.org/sonar/rules/show/squid:S1319. You can avoid this casting in the most cases.
  2. You can use Guava method: ArrayList<Task> arraylist = Lists.newArrayList(list);

Solution 7 - Java

The first approach is trying to cast the list but this would work only if the List<> were an ArrayList<>. That is not the case. So you need the second approach, that is building a new ArrayList<> with the elements of the List<>

Solution 8 - Java

Because in the first one , you're trying to convert a collection to an ArrayList. In the 2nd one , you just use the built in constructor of ArrayList

Solution 9 - Java

May be:

ArrayList<ServiceModel> services = new ArrayList<>(parking.getServices());
intent.putExtra("servicios",services);

Solution 10 - Java

import java.util.List;
import java.util.Arrays;
import java.util.*;

public class Merge
{  
  public static void main(String[] args) {
  // This is normal way
  // List<Integer> l1 = new ArrayList<Integer>(); l1.add(2); l1.add(5); l1.add(10); l1.add(22); 
  // List<Integer> l2 = new ArrayList<Integer>(); l2.add(3); l2.add(8); l2.add(15); 

 //Array.asList only have the list interface, but ArrayList is inherited from List Interface with few more property like ArrayList.remove()
 List<Integer> templ1 = Arrays.asList(2,5,10,22); 
 List<Integer> templ2 =  Arrays.asList(3,8,12);
//So creation of ArrayList with the given list is required, then only ArrayList.remove function works. 
 List<Integer> l1 = new ArrayList<Integer>(templ1);
 List<Integer> l2 = new ArrayList<Integer>(templ2);
 List<Integer> l3 = new ArrayList<Integer>();

 Iterator itr1 = l1.iterator();
 while(itr1.hasNext()){
    int x = (Integer) itr1.next();
    Iterator itr2 = l2.iterator();
    while(itr2.hasNext()) {
      int y = (Integer) itr2.next(); 
      if(x < y) {
        l3.add(x);
        break;
      }
      else{
        l3.add(y);
        itr2.remove();
         
      }
    }
 }
 
 Iterator it = l1.iterator(); 
 while (it.hasNext()){
  int k = (Integer) it.next();
  if (l3.contains(k)){
     continue;
  }
  else{
     l3.add(k);
     System.out.println(k);
  }
 }
 
 Iterator itr2 = l2.iterator();
 while (itr2.hasNext()){
  int k = (Integer) itr2.next();
  l3.add(k);
 }
 
 System.out.println(l3);
 }
}

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionEugeneView Question on Stackoverflow
Solution 1 - JavacorsiKaView Answer on Stackoverflow
Solution 2 - JavaHarshView Answer on Stackoverflow
Solution 3 - JavarebulanyumView Answer on Stackoverflow
Solution 4 - JavakrtekView Answer on Stackoverflow
Solution 5 - Javavikas kumarView Answer on Stackoverflow
Solution 6 - JavaAtetcView Answer on Stackoverflow
Solution 7 - JavajdehaanView Answer on Stackoverflow
Solution 8 - JavaYossaleView Answer on Stackoverflow
Solution 9 - JavaRolfy MontufarView Answer on Stackoverflow
Solution 10 - JavaRBuser2769569View Answer on Stackoverflow