Quel est le problème avec cette 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);
}
J'ai fait cela après avoir lu la solution trouvée dans Create ArrayList from array . La deuxième ligne (tri) dans getTheNumber(...)
provoque l'exception suivante:
Exception dans le thread "principal" Java.lang.ClassCastException: [Je ne peux pas être casté en Java.lang.Comparable]
Qu'est-ce qui ne va pas ici? Je me rends compte que le tri pourrait être fait avec Arrays.sort()
, je suis juste curieux de savoir celui-ci.
Prenons l'exemple simplifié suivant:
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);
}
}
Sur la ligne println, cela imprime quelque chose comme "[[I @ 190d11]", ce qui signifie que vous avez réellement construit une ArrayList qui contient int tableaux.
Votre IDE et le compilateur doivent avertir des affectations non contrôlées dans ce code. Vous devez toujours utiliser new ArrayList<Integer>()
ou new ArrayList<>()
au lieu de new ArrayList()
Si vous l'aviez utilisé, il y aurait eu une erreur de compilation en raison de la tentative de passer List<int[]>
Au constructeur.
Il n'y a pas de boîte automatique de int[]
À Integer[]
, Et de toute façon, la boîte automatique n'est que du sucre syntaxique dans le compilateur, dans ce cas, vous devez faire la copie du tableau manuellement:
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);
}
Vous essayez de convertir int [] en entier [], ce n'est pas possible.
Vous pouvez utiliser les ArrayUtils de commons-lang pour convertir les entiers en entiers avant d'obtenir la liste à partir du tableau:
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);
}
il y a deux causes à cette exception:
Arrays.asList(factors)
renvoie un List<int[]>
où factors
est un int array
vous avez oublié d'ajouter le paramètre type à:
ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));
avec:
ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));
résultant en une erreur au moment de la compilation:
trouvé: Java.util.List <int []> requis: Java.util.List <Java.lang.Integer>
Utilisez Java.utils.Arrays:
public int getTheNumber(int[] factors) {
int[] f = (int[])factors.clone();
Arrays.sort(f);
return f[0]*f[(f.length-1];
}
Ou si vous voulez être efficace, évitez toute allocation d'objet, faites simplement le travail:
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;
}
Arrays.asList(factors)
renvoie un List<int[]>
, pas un List<Integer>
. Puisque vous faites new ArrayList
au lieu de new ArrayList<Integer>
vous n'obtenez pas d'erreur de compilation pour cela, mais créez un ArrayList<Object>
qui contient un int[]
et vous avez ensuite implicitement jeté ce tableau sur ArrayList<Integer>
. Bien sûr, la première fois que vous essayez d'utiliser l'un de ces "nombres entiers", vous obtenez une exception.
Je pense que vous avez trouvé un exemple où la boxe automatique ne fonctionne pas vraiment. Parce que Arrays.asList(T... a)
a un paramètre varargs, le compilateur considère apparemment l'int [] et retourne un List<int[]>
avec un seul élément.
Vous devez changer la méthode en ceci:
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);
}
et éventuellement ajouter ceci pour la compatibilité
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);
}
Cela fonctionne de Java 5 à 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);
}
Dans Java 4 il n'y a pas de vararg ... :-)
cela provient de Java API "sort
public static void sort (List list) Trie la liste spécifiée dans l'ordre croissant, selon l'ordre naturel de ses éléments. Tous les éléments de la liste doivent implémenter l'interface Comparable. En outre, tous les éléments de la liste doivent être mutuellement comparables (c'est-à-dire que e1.compareTo (e2) ne doit pas lever d'exception ClassCastException pour les éléments e1 et e2 de la liste). "
cela a à voir avec la mise en œuvre de l'interface comparable
Pour autant que je le comprenne, la fonction de tri dans la classe de collection ne peut être utilisée que pour trier les collections implémentant l'interface comparable.
Vous lui fournissez un tableau d'entiers. Vous devriez probablement envelopper cela dans l'une des classes Wrapper connues telles que Integer. Entier implémente comparable.
Cela fait longtemps que je n'ai pas travaillé sur du Java sérieux, mais lire quelques informations sur la fonction de tri peut aider.