Tablice.asList () tablicy

Co jest złego w tym nawróceniu?

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);
}

Zrobiłem to po przeczytaniu rozwiązania znalezionego w Create ArrayList from array . Druga linia (sortowanie) w getTheNumber(...) powoduje następujący wyjątek:

Wyjątek w wątku "main" java.lang.ClassCastException: [I cannot be cast to java.lang.Porównywalne]

Co tu się dzieje? Zdaję sobie sprawę, że sortowanie można zrobić za pomocą Arrays.sort(), jestem tylko ciekawa tego.
Author: Community, 2009-08-08

9 answers

Rozważmy następujący uproszczony przykład:

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);
    }
}

W linii println wyświetla coś w stylu "[[I @ 190d11]", co oznacza, że rzeczywiście skonstruowałeś ArrayList zawierający tablice int .

Twoje IDE i kompilator powinny ostrzegać o niezaznaczonych zadaniach w tym kodzie. Należy zawsze używać new ArrayList<Integer>() lub new ArrayList<>() zamiast new ArrayList(). Jeśli go użyłeś, wystąpiłby błąd kompilacji z powodu próby przekazania List<int[]> do konstruktor.

Nie ma autoboxingu od int[] do Integer[], a w każdym razie autoboxing jest tylko cukrem składniowym w kompilatorze, więc w tym przypadku musisz wykonać kopię tablicy ręcznie:

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);
}
 43
Author: Esko Luontola,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-07-28 21:57:09

Próbujesz zamienić int [] na Integer [], nie jest to możliwe.

Możesz użyć tablic commons-lang, aby przekonwertować ints na liczby całkowite przed pobraniem listy z tablicy:

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);
}    
 9
Author: Rich Seller,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-08-23 08:51:31

Istnieją dwie przyczyny tego wyjątku:

1

Arrays.asList(factors) zwraca List<int[]> Gdzie factorsjest int array

2

Zapomniałeś dodać parametr type do:

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

Z:

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

Wynikający z błędu czas kompilacji :

found   : java.util.List<int[]>
required: java.util.List<java.lang.Integer>
 8
Author: dfa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-02-01 23:33:00

Użyj Javy.utils.Tablice:

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

Lub jeśli chcesz być skuteczny unikaj alokacji obiektów po prostu wykonaj pracę:

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;
}
 6
Author: Tom,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-08 13:54:56

Myślę, że znalazłeś przykład, gdzie auto-Boks tak naprawdę nie działa. Ponieważ Arrays.asList(T... a) ma parametr varargs, kompilator najwyraźniej rozważa int [] i zwraca {[3] } z pojedynczym elementem w nim.

Należy zmienić metodę na taką:

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);
}

I ewentualnie dodać to dla kompatybilności

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);
}
 2
Author: Robert Petermeier,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-08 13:36:16

Arrays.asList(factors) zwraca List<int[]>, a nie List<Integer>. Ponieważ wykonujesz new ArrayList zamiast new ArrayList<Integer>, nie otrzymujesz błędu kompilacji, ale tworzysz ArrayList<Object>, który zawiera int[], a następnie domyślnie przypisujesz tę tablicę do ArrayList<Integer>. Oczywiście za pierwszym razem, gdy próbujesz użyć jednej z tych "liczb całkowitych", dostajesz wyjątek.

 2
Author: sepp2k,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2010-09-07 12:24:29

To działa od Javy 5 do 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);
}

W Javie 4 nie ma vararg... :-)

 1
Author: Nuno Rafael Figueiredo,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-08-04 21:19:27

To jest z Java API "Sortuj

Public static void sort (lista list) Sortuje określoną listę w porządku rosnącym, zgodnie z naturalną kolejnością jej elementów. Wszystkie elementy listy muszą zaimplementować porównywalny interfejs. Ponadto wszystkie elementy w wykazie muszą być wzajemnie porównywalne (czyli e1.compareTo (e2) nie może rzucać ClassCastException dla żadnych elementów e1 i e2 na liście)."

Ma to związek z implementacją porównywalnego interfejsu

 0
Author: CoDeR,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-08 12:38:33

O ile to Rozumiem, funkcja sortowania w klasie collection może być używana tylko do sortowania kolekcji implementujących porównywalny interfejs.

Dostarczasz mu tablicę liczb całkowitych. Prawdopodobnie powinieneś zawinąć to wokół jednej ze znanych klas Opakowujących, takich jak Integer. Integer implementuje porównywalne.

Dawno nie pracowałem nad jakąś poważną Javą, jednak czytanie jakiejś sprawy na temat funkcji sortowania pomoże.

 0
Author: Kevin Boyd,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2009-08-08 12:39:00