web-dev-qa-db-ja.com

配列のArrays.asList()

この変換の何が問題になっていますか?

_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()を使用して実行できることを理解していますが、これには興味があります。

38
nbl

次の簡単な例を考えてみましょう。

_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);
}
_
42
Esko Luontola

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);
}    
9
Rich Seller

この例外には2つの原因があります。

1

Arrays.asList(factors)List<int[]>を返します。ここでfactorsint配列です

2

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> 
8
dfa

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;
}
6
Tom

Arrays.asList(factors)は、List<int[]>ではなく、List<Integer>を返します。 new ArrayListの代わりにnew ArrayList<Integer>を実行しているため、そのためのコンパイルエラーは発生しませんが、ArrayList<Object>を含むint[]を作成し、それを暗黙的にキャストします。 arraylistをArrayList<Integer>に。もちろん、これらの「整数」の1つを使用しようとすると、例外が発生します。

2
sepp2k

自動ボクシングが実際に機能しない例が見つかったと思います。 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);
}
2

これは、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インターフェースの実装に関係しています

0
CoDeR

私が理解している限り、コレクションクラスの並べ替え関数は、同等のインターフェイスを実装するコレクションの並べ替えにのみ使用できます。

整数の配列を提供しています。おそらく、Integerなどの既知のWrapperクラスの1つでこれをラップする必要があります。整数は同等のものを実装します。

本格的なJavaに取り組んできてから長い時間が経ちましたが、sort関数に関するいくつかの事項を読むと役立ちます。

0
Kevin Boyd