web-dev-qa-db-ja.com

Java:プリミティブデータ型の配列はオートボックス化されません

私はこのような方法を持っています:

public static <T> boolean isMemberOf(T item, T[] set)
{
    for (T t : set) {
        if (t.equals(item)) {
            return true;
        }
    }
    return false;
}

ここで、charに対してTを使用してこのメ​​ソッドを呼び出そうとします。

char ch = 'a';
char[] chars = new char[] { 'a', 'b', 'c' };
boolean member = isMemberOf(ch, chars);

これは機能しません。 charchar[]CharacterCharacter[]に自動ボックス化されると思いますが、そうではないようです。

何か洞察はありますか?

29
David Koelle

配列の自動ボックス化はなく、プリミティブのみです。これがあなたの問題だと思います。

41
Eddie

char[]Character[]にボックス化されるのはなぜですか?配列は常に参照型であるため、ボックス化は必要ありません。

さらに、それは恐ろしいほど高価になります-それは新しい配列を作成し、次に各文字を順番にボックス化することを含みます。うわぁ!

14
Jon Skeet

リフレクションを使用して、すべてのタイプの配列で機能するメソッドを取得できますが、タイプの安全性が失われるため、これはおそらく必要なことではありません。

import Java.lang.reflect.Array
public static boolean isMemberOfArray(Object item, Object array)
{
    int n = Array.getLength(array)
    for (int i = 0; i < n; i++) {
        if (Array.get(array, i).equals(item)) {
            return true;
        }
    }
    return false;
}
3
newacct

正解です。配列の自動ボックス化はありません(int[] ints; ...; Arrays.asList(ints)のような場合は奇妙になります-asListは単一のオブジェクト(配列)を含むリストを返します!)

配列をボックス化する簡単なユーティリティを次に示します。

public static Integer[] boxedArray(int[] array) {
    Integer[] result = new Integer[array.length];
    for (int i = 0; i < array.length; i++)
        result[i] = array[i];
    return result;
}

もちろん、プリミティブ型ごとに異なるバージョンが必要になります。

2
SecretCode

他の人が述べたように、プリミティブの配列の自動ボクシングはありません。プリミティブ配列でメソッドを使用する場合は、プリミティブ型ごとにオーバーロードを指定する必要があります。これは、クラスライブラリで物事を行うための標準的な方法のようです。たとえば、 Java.util.Arrays のオーバーロードを参照してください。

1
Ben Lings

これは、このような高価なオートボクシング操作を回避するためと、ジェネリックが既存のJavaバイトコード)との下位互換性が必要なため、設計によるもののようです。

たとえば、 この記事 および このバグ を参照してください。

1
Josh Lee

配列は、低レベルの実装タイプのものです。 char[]は、2バイト文字の連続したメモリ領域になります。 Character[]は、4バイトまたは8バイトの参照を持つメモリの連続領域になります。 Character[]を取得してchar []をラップすることはできません。ただし、List<Character>char[]をラップする可能性があります。

低レベルのコードを記述していない限り、参照の配列は通常はお勧めできません。必要に応じて、Java.util.Arrays.asListに相当するものを記述または取得できます。

まず、配列をできるだけ避け、代わりにリストを使用するようにします。

配列の自動ボックス化はありませんが、可変引数の自動ボックス化はあります。したがって、メソッドを(同じ本文で)として宣言すると、次のようになります。

public static <T> boolean isMemberOf(T item, T ... set)

その後、あなたは書くことができます

isMemberOf('a', 'a', 'b', 'c');

個人的には、グーグルのグアバを使うのが好きです。

char ch = 'a';
char[] chars = new char[] { 'a', 'b', 'c' };
boolean member = isMemberOf(ch, Chars.asList(chars).toArray(new Character[0]));

あなたのコードはおそらく単なる例でしたが、本当にメンバーシップをテストしたい場合は、次のように行うことができます。

Chars.contains(chars, ch);

or

ImmutableSet.of('a', 'b', 'c').contains('a')
1
Jirka

Java 8と入力し、primArrayをタイプ_PrimType[]_の識別子とすると、次のようになります。 できる 以下をせよ:
BoxedType[] boxedArray = IntStream.range(0, primArray.length).mapToObj(i -> primArray[i]).toArray(BoxedType[] :: new);

1
bodmas

これを行う簡単な方法は

char ch = 'a';
String chars = "abc";
boolean member = chars.indexOf(ch) >= 0;
0
Peter Lawrey