Domanda

Ho un metodo come questo:

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

Ora cerco di chiamare questo metodo che utilizza un char per T:

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

Questo non funziona. Mi aspetto il char[] e Character per ottenere autoboxed a Character[] e <=>, ma questo non sembra accadere.

Tutte le comprensioni?

È stato utile?

Soluzione

Non c'è autoboxing per gli array, solo per le primitive. Credo che questo sia il tuo problema.

Altri suggerimenti

Perché sarebbe char[] essere inscatolato a Character[]? Gli array sono sempre tipi di riferimento, quindi non è necessario boxe.

Inoltre, sarebbe terribilmente costoso - si tratterebbe di creare un nuovo array e poi boxe ogni char a sua volta. Yikes!

Si potrebbe utilizzare la reflection per ottenere un metodo che funziona per tutti i tipi di array, ma si perderebbe la sicurezza di tipo, quindi questo non è probabilmente quello che volete.

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

Una corretta, non v'è alcuna autoboxing per gli array (che si traduce in stranezze in casi come int[] ints; ...; Arrays.asList(ints) -! AsList restituisce una lista contenente un singolo oggetto, la matrice)

Ecco un semplice programma di utilità di box un array.

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

Avrete bisogno di una versione diversa per ogni tipo primitivo, naturalmente.

Questo sembra essere in base alla progettazione, sia per evitare una tale operazione autoboxing costosa, sia perché farmaci generici devono essere retrocompatibile con il bytecode Java esistente.

questo articolo e questo bug , per esempio.

Gli array sono un tipo di implementazione a basso livello di cose. char[] sarà un'area contigua di memoria con caratteri a due byte. Character[] sarà un'area contigua di memoria con riferimenti a quattro o otto byte. Non è possibile ottenere un List<Character> per avvolgere un char []. Tuttavia, un java.util.Arrays.asList potrebbe avvolgere un <=>.

Gli array di riferimenti di solito non sono una buona idea a meno che non si sta scrivendo codice di basso livello. Si potrebbe, se lo si desidera, scrivere o ottenere un equivalente di <=>.

Come altri hanno detto, non v'è alcuna autoboxing per le matrici di primitive. Se si desidera utilizzare il metodo con gli array primitivi, è necessario fornire un sovraccarico per ogni tipo primitivo. Questo sembra essere il modo standard di fare le cose nelle librerie di classi. Vedere i sovraccarichi in java.util.Arrays , per esempio.

In primo luogo, vorrei cercare di evitare gli array come più possibile, utilizzare gli elenchi invece.

Non c'è autoboxing per gli array, ma non v'è autoboxing per varargs. Quindi, se si dichiara il metodo di come (con lo stesso corpo):

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

allora si può scrivere

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

Personalmente, io preferisco usare guava di Google, in cui è possibile scrivere le cose come

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

Il tuo codice è stato probabilmente solo un esempio, ma se si voleva davvero per testare l'adesione, in si può fare in questo modo:

Chars.contains(chars, ch);

or

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

Inserisci Java 8 e lasciare primArray essere un identificatore di tipo PrimType[], allora si possono effettuare le seguenti operazioni:
BoxedType[] boxedArray = IntStream.range(0, primArray.length).mapToObj(i -> primArray[i]).toArray(BoxedType[] :: new);

Un modo più semplice per farlo è

char ch = 'a';
String chars = "abc";
boolean member = chars.indexOf(ch) >= 0;
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top