Java:原始数据types的数组不会自动装箱
我有这样的一个方法:
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);
这不起作用。 我期望char
和char[]
被自动装箱到Character
和Character[]
,但是这似乎没有发生。
任何见解?
数组没有自动装箱,只能用于基元。 我相信这是你的问题。
为什么char[]
被装箱到Character[]
? 数组总是引用types,所以不需要装箱。
此外,这将是非常昂贵的 – 这将涉及创build一个新的arrays,然后拳击每个字符。 哎呀!
你可以使用reflection来获得适用于所有types的数组的方法,但是你会失去types安全性,所以这可能不是你想要的。
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; }
正确的是,数组没有自动装箱(这会导致类似int[] ints; ...; Arrays.asList(ints)
– asList返回一个包含单个Object,数组的List!
这是一个简单的实用程序来放置一个数组。
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; }
当然,您将需要为每种基本types使用不同的版本。
这似乎是为了避免昂贵的自动装箱操作,并且因为generics必须与现有的Java字节码向后兼容。
例如,看到这篇文章和这个错误 。
数组是一个低级的实现types的东西。 char[]
将是一个连续的双字节字符的内存区域。 Character[]
将是连续的四个或八个字节引用的内存区域。 你不能得到一个Character[]
来包装一个char []。 但是List<Character>
可以包装一个char[]
。
除非编写低级代码,否则引用数组通常不是一个好主意。 如果你愿意的话,你可以写或获得一个java.util.Arrays.asList
的等价物。
正如其他人所说,原始数组没有自动装箱。 如果你想在原始数组中使用你的方法,你将需要为每个原始types提供一个重载。 这似乎是在类库中做事的标准方式。 例如,查看java.util.Arrays中的重载。
首先,我会尽量避免使用数组,而是使用列表。
数组没有自动装箱,但有可变参数的可变参数。 所以,如果你声明你的方法(具有相同的身体):
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]));
你的代码可能只是一个例子,但如果你真的想testing成员资格,你可以这样做:
Chars.contains(chars, ch); or ImmutableSet.of('a', 'b', 'c').contains('a')
inputJava 8并让primArray
成为PrimType[]
types的标识符,然后您可以执行以下操作:
BoxedType[] boxedArray = IntStream.range(0, primArray.length).mapToObj(i -> primArray[i]).toArray(BoxedType[] :: new);
一个简单的方法来做到这一点
char ch = 'a'; String chars = "abc"; boolean member = chars.indexOf(ch) >= 0;