[java] Arrays.asList() of an array

What is wrong with this conversion?

public int getTheNumber(int[] factors) {
    ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));  
    Collections.sort(f);
    return f.get(0)*f.get(f.size()-1);
}

I made this after reading the solution found in Create ArrayList from array. The second line (sorting) in getTheNumber(...) causes the following exception:

Exception in thread "main" java.lang.ClassCastException: [I cannot be cast to java.lang.Comparable]

What is wrong here? I do realize that sorting could be done with Arrays.sort(), I'm just curious about this one.

This question is related to java arrays integer arraylist

The answer is


Let's consider the following simplified example:

public class Example {
    public static void main(String[] args) {
        int[] factors = {1, 2, 3};
        ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));
        System.out.println(f);
    }
}

At the println line this prints something like "[[I@190d11]" which means that you have actually constructed an ArrayList that contains int arrays.

Your IDE and compiler should warn about unchecked assignments in that code. You should always use new ArrayList<Integer>() or new ArrayList<>() instead of new ArrayList(). If you had used it, there would have been a compile error because of trying to pass List<int[]> to the constructor.

There is no autoboxing from int[] to Integer[], and anyways autoboxing is only syntactic sugar in the compiler, so in this case you need to do the array copy manually:

public static int getTheNumber(int[] factors) {
    List<Integer> f = new ArrayList<Integer>();
    for (int factor : factors) {
        f.add(factor); // after autoboxing the same as: f.add(Integer.valueOf(factor));
    }
    Collections.sort(f);
    return f.get(0) * f.get(f.size() - 1);
}

I think you have found an example where auto-boxing doesn't really work. Because Arrays.asList(T... a) has a varargs parameter the compiler apparently considers the int[] and returns a List<int[]> with a single element in it.

You should change the method into this:

public int getTheNumber(Integer[] factors) {
    ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));  
    Collections.sort(f);
    return f.get(0) * f.get(f.size() - 1);
}

and possibly add this for compatibility

public int getTheNumber(int[] factors) {
    Integer[] factorsInteger = new Integer[factors.length];
    for(int ii=0; ii<factors.length; ++ii) {
        factorsInteger[ii] = factors[ii];
    }

    return getTheNumber(factorsInteger);
}

You are trying to cast int[] to Integer[], this is not possible.

You can use commons-lang's ArrayUtils to convert the ints to Integers before getting the List from the array:

public int getTheNumber(int[] factors) {
    Integer[] integers = ArrayUtils.toObject(factors);
    ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(integers));
    Collections.sort(f);
    return f.get(0)*f.get(f.size()-1);
}    

Arrays.asList(factors) returns a List<int[]>, not a List<Integer>. Since you're doing new ArrayList instead of new ArrayList<Integer> you don't get a compile error for that, but create an ArrayList<Object> which contains an int[] and you then implicitly cast that arraylist to ArrayList<Integer>. Of course the first time you try to use one of those "Integers" you get an exception.


this is from Java API "sort

public static void sort(List list) Sorts the specified list into ascending order, according to the natural ordering of its elements. All elements in the list must implement the Comparable interface. Furthermore, all elements in the list must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the list)."

it has to do with implementing the Comparable interface


Use java.utils.Arrays:

public int getTheNumber(int[] factors) {
    int[] f = (int[])factors.clone();
    Arrays.sort(f);
    return f[0]*f[(f.length-1];
}

Or if you want to be efficient avoid all the object allocation just actually do the work:

public static int getTheNumber(int[] array) {
    if (array.length == 0)
        throw new IllegalArgumentException();
    int min = array[0];
    int max = array[0];
    for (int i = 1; i< array.length;++i) {
        int v = array[i];
        if (v < min) {
            min = v;
        } else if (v > max) {
            max = v;
        }
    }
    return min * max;
}

there are two cause of this exception:

1

Arrays.asList(factors) returns a List<int[]> where factors is an int array

2

you forgot to add the type parameter to:

ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));

with:

ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));  

resulting in a compile-time error:

found   : java.util.List<int[]>
required: java.util.List<java.lang.Integer>

This works from Java 5 to 7:

public int getTheNumber(Integer... factors) {
    ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));
    Collections.sort(f);
    return f.get(0)*f.get(f.size()-1);
}

In Java 4 there is no vararg... :-)


As far as I understand it, the sort function in the collection class can only be used to sort collections implementing the comparable interface.

You are supplying it a array of integers. You should probably wrap this around one of the know Wrapper classes such as Integer. Integer implements comparable.

Its been a long time since I have worked on some serious Java, however reading some matter on the sort function will help.


Examples related to java

Under what circumstances can I call findViewById with an Options Menu / Action Bar item? How much should a function trust another function How to implement a simple scenario the OO way Two constructors How do I get some variable from another class in Java? this in equals method How to split a string in two and store it in a field How to do perspective fixing? String index out of range: 4 My eclipse won't open, i download the bundle pack it keeps saying error log

Examples related to arrays

PHP array value passes to next row Use NSInteger as array index How do I show a message in the foreach loop? Objects are not valid as a React child. If you meant to render a collection of children, use an array instead Iterating over arrays in Python 3 Best way to "push" into C# array Sort Array of object by object field in Angular 6 Checking for duplicate strings in JavaScript array what does numpy ndarray shape do? How to round a numpy array?

Examples related to integer

Python: create dictionary using dict() with integer keys? How to convert datetime to integer in python Can someone explain how to append an element to an array in C programming? How to get the Power of some Integer in Swift language? python "TypeError: 'numpy.float64' object cannot be interpreted as an integer" What's the difference between integer class and numeric class in R PostgreSQL: ERROR: operator does not exist: integer = character varying C++ - how to find the length of an integer Converting binary to decimal integer output Convert floats to ints in Pandas?

Examples related to arraylist

Adding null values to arraylist How to iterate through an ArrayList of Objects of ArrayList of Objects? Dynamically adding elements to ArrayList in Groovy How to replace existing value of ArrayList element in Java How to remove the last element added into the List? How to append elements at the end of ArrayList in Java? Removing Duplicate Values from ArrayList How to declare an ArrayList with values? In Java, can you modify a List while iterating through it? Load arrayList data into JTable