Java: Matriz de tipos de dados primitivos não é autobox

Eu tenho um método como este:

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

Agora eu tento chamar esse método usando um char para T :

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

Isso não funciona. Eu esperaria que o char e o char[] fossem autoboxados para Character e Character[] , mas isso não parece acontecer.

Alguma ideia?

Não há autoboxing para matrizes, apenas para primitivos. Eu acredito que este é o seu problema.

Por que o char[] seria encheckboxdo no Character[] ? Matrizes são sempre tipos de referência, portanto, não é necessário o boxe.

Além disso, seria terrivelmente caro – envolveria a criação de uma nova matriz e, em seguida, encaixotaria cada char por vez. Yikes!

Você poderia usar a reflection para obter um método que funciona para todos os tipos de matrizes, mas perderia a segurança do tipo, portanto, provavelmente não é isso que você deseja.

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

Correto, não há autoboxing para matrizes (o que resulta em estranheza em casos como int[] ints; ...; Arrays.asList(ints) – asList retorna uma lista contendo um único object, a matriz!)

Aqui está um utilitário simples para boxear um 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; } 

Você precisará de uma versão diferente para cada tipo primitivo, é claro.

Isso parece ser intencional, tanto para evitar uma operação de autoboxing tão dispendiosa, quanto porque os genéricos precisam ser compatíveis com versões anteriores do bytecode Java existente.

Veja este artigo e este bug , por exemplo.

Matrizes são um tipo de implementação de baixo nível. char[] será uma área contígua de memory com caracteres de dois bytes. Character[] será uma área contígua de memory com referências de quatro ou oito bytes. Você não pode obter um Character[] para envolver um caractere []. No entanto, uma List poderia envolver um char[] .

Matrizes de referências geralmente não são uma boa ideia, a menos que você esteja escrevendo um código de baixo nível. Você poderia, se desejar, escrever ou obter um equivalente de java.util.Arrays.asList .

Como outros já mencionaram, não há autoboxing para matrizes de primitivos. Se você quiser usar seu método com matrizes primitivas, precisará fornecer uma sobrecarga para cada tipo primitivo. Esta parece ser a maneira padrão de fazer as coisas nas bibliotecas de classs. Veja as sobrecargas em java.util.Arrays , por exemplo.

Primeiro, eu tentaria evitar matrizes tanto quanto você pode, use listas em vez disso.

Não há autoboxing para matrizes, mas há autoboxing para varargs. Então, se você declarar seu método como (com o mesmo corpo):

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

então você pode escrever

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

Pessoalmente, eu prefiro usar google google, onde você pode escrever coisas como

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

Seu código provavelmente era apenas um exemplo, mas se você realmente quisesse testar a associação, você pode fazer assim:

 Chars.contains(chars, ch); or ImmutableSet.of('a', 'b', 'c').contains('a') 

Digite Java 8 e deixe que primArray seja um identificador do tipo PrimType[] , então você pode fazer o seguinte:
BoxedType[] boxedArray = IntStream.range(0, primArray.length).mapToObj(i -> primArray[i]).toArray(BoxedType[] :: new);

Uma maneira mais simples de fazer isso é

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