この変換の何が問題になっていますか?
_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);
}
_
Create ArrayList from array にある解決策を読んだ後にこれを作成しました。 getTheNumber(...)
の2行目(ソート)により、次の例外が発生します。
スレッド「メイン」の例外Java.lang.ClassCastException:[Java.lang.Comparableにキャストできません]
ここで何が間違っていますか?ソートはArrays.sort()
を使用して実行できることを理解していますが、これには興味があります。
次の簡単な例を考えてみましょう。
_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);
}
}
_
Println行では、これは "[[I @ 190d11]"のようなものを出力します。これは、int arraysを含むArrayListを実際に構築したことを意味します。
あなたのIDEそしてコンパイラはそのコードの未チェックの割り当てについて警告する必要があります。new ArrayList<Integer>()
の代わりにnew ArrayList<>()
またはnew ArrayList()
を常に使用する必要があります使用していた場合は、_List<int[]>
_をコンストラクターに渡そうとしたため、コンパイルエラーが発生していました。
_int[]
_から_Integer[]
_へのオートボクシングはありません。とにかく、オートボクシングはコンパイラの構文上のシュガーにすぎないため、この場合は配列のコピーを手動で行う必要があります。
_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);
}
_
Int []をInteger []にキャストしようとしていますが、これは不可能です。
Commons-langのArrayUtilsを使用して、配列からリストを取得する前にintを整数に変換できます。
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);
}
この例外には2つの原因があります。
Arrays.asList(factors)
はList<int[]>
を返します。ここでfactors
はint配列です
typeパラメーターを以下に追加するのを忘れました:
ArrayList<Integer> f = new ArrayList(Arrays.asList(factors));
で:
ArrayList<Integer> f = new ArrayList<Integer>(Arrays.asList(factors));
コンパイル時エラーになります:
found:Java.util.List <int []> required:Java.util.List <Java.lang.Integer>
Java.utils.Arraysを使用します。
public int getTheNumber(int[] factors) {
int[] f = (int[])factors.clone();
Arrays.sort(f);
return f[0]*f[(f.length-1];
}
または、効率的にしたい場合は、すべてのオブジェクトの割り当てを避けて、実際に作業を行ってください:
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)
は、List<int[]>
ではなく、List<Integer>
を返します。 new ArrayList
の代わりにnew ArrayList<Integer>
を実行しているため、そのためのコンパイルエラーは発生しませんが、ArrayList<Object>
を含むint[]
を作成し、それを暗黙的にキャストします。 arraylistをArrayList<Integer>
に。もちろん、これらの「整数」の1つを使用しようとすると、例外が発生します。
自動ボクシングが実際に機能しない例が見つかったと思います。 Arrays.asList(T... a)
にはvarargsパラメータがあるため、コンパイラは明らかにint []を考慮し、List<int[]>
に単一の要素が含まれています。
メソッドを次のように変更する必要があります。
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);
}
おそらく互換性のためにこれを追加します
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);
}
これは、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);
}
Java 4に可変引数はありません... :-)
これはJava API "sort
public static void sort(List list)要素の自然順序付けに従って、指定されたリストを昇順でソートします。リスト内のすべての要素は、Comparableインターフェイスを実装する必要があります。さらに、リスト内のすべての要素は相互に比較可能である必要があります(つまり、e1.compareTo(e2)はリスト内の要素e1およびe2に対してClassCastExceptionをスローしてはなりません)。
comparableインターフェースの実装に関係しています
私が理解している限り、コレクションクラスの並べ替え関数は、同等のインターフェイスを実装するコレクションの並べ替えにのみ使用できます。
整数の配列を提供しています。おそらく、Integerなどの既知のWrapperクラスの1つでこれをラップする必要があります。整数は同等のものを実装します。
本格的なJavaに取り組んできてから長い時間が経ちましたが、sort関数に関するいくつかの事項を読むと役立ちます。