Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

toArray() method in Collection class

In Collection class are 2 toArray() methods: <T> T[] toArray(T[] a) and Object[] toArray(). There is no E[] toArray() method. Why? It is connected with type erasures, but there is for example method - boolean add(E e). Why is it possible to create parametrized add and it is not possible to create toArray() method?

like image 994
Pawel Avatar asked Jan 23 '14 19:01

Pawel


People also ask

Why do you need toArray () method in the collection interface?

The toArray methods are provided as a bridge between collections and older APIs that expect arrays on input. The array operations allow the contents of a Collection to be translated into an array. The simple form with no arguments creates a new array of Object .

What does toArray () do in java?

The toArray() method of ArrayList is used to return an array containing all the elements in ArrayList in the correct order.

Which of the following methods is are available in collections class?

The Collections class It contains polymorphic algorithms that operate on collections, “wrappers”, which return a new collection backed by a specified collection, and a few other odds and ends. This class contains methods for collection framework algorithms, such as binary search, sorting, shuffling, reverse, etc.


1 Answers

There is no E[] toArray() method. Why?

There's no way it could actually create an E[] at execution time, because it wouldn't know the type of array to create, due to type erasure.

The add method will really accept anything, but the compiler just checks that the argument type is compatible with E first. Nothing needs to be known at execution time. Likewise for something like List.get, the compiler inserts a cast into the calling code:

List<String> strings = new ArrayList<>();
strings.add("hello");
String first = strings.get(0);

is compiled to the same code as this pre-generics code:

List strings = new ArrayList();
strings.add("hello");
String first = (String) strings.get(0);

Now that's fine here, because we know the String type at execution time in the calling code... but in toArray(), the code creating the array needs to know the type... and type erasure means that it doesn't actually know that. The array which is passed into toArray() allows it to create an array of the same type. Indeed, the actual type of the object created can be shown to depend on the array you pass in:

import java.util.*;

public class Test {

    public static void main(String[] args) {
        List<Object> objects = new ArrayList<Object>();
        objects.add("xyz");

        Object[] array1 = objects.toArray(new String[0]);
        Object[] array2 = objects.toArray(new Object[0]);
        System.out.println(array1.getClass()); // class [Ljava.lang.String;
        System.out.println(array2.getClass()); // class [Ljava.lang.Object;
    }
}

If we'd passed in new Integer[0] it would have compiled, but then we'd have got a ClassCastException when toArray tried to cast a String (the only element) to Integer.

like image 167
Jon Skeet Avatar answered Sep 26 '22 06:09

Jon Skeet