ThinkChat🤖让你学习和工作更高效,注册即送10W Token,即刻开启你的AI之旅 广告
## 泛型和基本数组 在本章的前面,我们被提醒,泛型不能和基元一起工作。在这种情况下,我们必须从基元数组转换为包装类型的数组,并且还必须从另一个方向转换。下面是一个转换器可以同时对所有类型的数据执行操作: ```java // onjava/ConvertTo.java // (c)2017 MindView LLC: see Copyright.txt // We make no guarantees that this code is fit for any purpose. // Visit http://OnJava8.com for more book information. package onjava; public interface ConvertTo { static boolean[] primitive(Boolean[] in) { boolean[] result = new boolean[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; // Autounboxing return result; } static char[] primitive(Character[] in) { char[] result = new char[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static byte[] primitive(Byte[] in) { byte[] result = new byte[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static short[] primitive(Short[] in) { short[] result = new short[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static int[] primitive(Integer[] in) { int[] result = new int[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static long[] primitive(Long[] in) { long[] result = new long[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static float[] primitive(Float[] in) { float[] result = new float[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static double[] primitive(Double[] in) { double[] result = new double[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } // Convert from primitive array to wrapped array: static Boolean[] boxed(boolean[] in) { Boolean[] result = new Boolean[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; // Autoboxing return result; } static Character[] boxed(char[] in) { Character[] result = new Character[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static Byte[] boxed(byte[] in) { Byte[] result = new Byte[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static Short[] boxed(short[] in) { Short[] result = new Short[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static Integer[] boxed(int[] in) { Integer[] result = new Integer[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static Long[] boxed(long[] in) { Long[] result = new Long[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static Float[] boxed(float[] in) { Float[] result = new Float[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } static Double[] boxed(double[] in) { Double[] result = new Double[in.length]; for(int i = 0; i < in.length; i++) result[i] = in[i]; return result; } } ``` **primitive()** 的每个版本都创建一个准确长度的适当基元数组,然后从包装类的 **in** 数组中复制元素。如果任何包装的数组元素是 **null** ,你将得到一个异常(这是合理的—否则无法选择有意义的值进行替换)。注意在这个任务中自动装箱如何发生。 下面是对 **ConvertTo** 中所有方法的测试: ```java // arrays/TestConvertTo.java import java.util.*; import onjava.*; import static onjava.ArrayShow.*; import static onjava.ConvertTo.*; public class TestConvertTo { static final int SIZE = 6; public static void main(String[] args) { Boolean[] a1 = new Boolean[SIZE]; Arrays.setAll(a1, new Rand.Boolean()::get); boolean[] a1p = primitive(a1); show("a1p", a1p); Boolean[] a1b = boxed(a1p); show("a1b", a1b); Byte[] a2 = new Byte[SIZE]; Arrays.setAll(a2, new Rand.Byte()::get); byte[] a2p = primitive(a2); show("a2p", a2p); Byte[] a2b = boxed(a2p); show("a2b", a2b); Character[] a3 = new Character[SIZE]; Arrays.setAll(a3, new Rand.Character()::get); char[] a3p = primitive(a3); show("a3p", a3p); Character[] a3b = boxed(a3p); show("a3b", a3b); Short[] a4 = new Short[SIZE]; Arrays.setAll(a4, new Rand.Short()::get); short[] a4p = primitive(a4); show("a4p", a4p); Short[] a4b = boxed(a4p); show("a4b", a4b); Integer[] a5 = new Integer[SIZE]; Arrays.setAll(a5, new Rand.Integer()::get); int[] a5p = primitive(a5); show("a5p", a5p); Integer[] a5b = boxed(a5p); show("a5b", a5b); Long[] a6 = new Long[SIZE]; Arrays.setAll(a6, new Rand.Long()::get); long[] a6p = primitive(a6); show("a6p", a6p); Long[] a6b = boxed(a6p); show("a6b", a6b); Float[] a7 = new Float[SIZE]; Arrays.setAll(a7, new Rand.Float()::get); float[] a7p = primitive(a7); show("a7p", a7p); Float[] a7b = boxed(a7p); show("a7b", a7b); Double[] a8 = new Double[SIZE]; Arrays.setAll(a8, new Rand.Double()::get); double[] a8p = primitive(a8); show("a8p", a8p); Double[] a8b = boxed(a8p); show("a8b", a8b); } } /* Output: a1p: [true, false, true, true, true, false] a1b: [true, false, true, true, true, false] a2p: [123, 33, 101, 112, 33, 31] a2b: [123, 33, 101, 112, 33, 31] a3p: [b, t, p, e, n, p] a3b: [b, t, p, e, n, p] a4p: [635, 8737, 3941, 4720, 6177, 8479] a4b: [635, 8737, 3941, 4720, 6177, 8479] a5p: [635, 8737, 3941, 4720, 6177, 8479] a5b: [635, 8737, 3941, 4720, 6177, 8479] a6p: [6882, 3765, 692, 9575, 4439, 2638] a6b: [6882, 3765, 692, 9575, 4439, 2638] a7p: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] a7b: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] a8p: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] a8b: [4.83, 2.89, 2.9, 1.97, 3.01, 0.18] */ ``` 在每种情况下,原始数组都是为包装类型创建的,并使用 **Arrays.setAll()** 填充,正如我们在 **TestCouner.java** 中所做的那样(这也验证了 **Arrays.setAll()** 是否能同 **Integer** ,**Long** ,和 **Double** )。然后 **ConvertTo.primitive()** 将包装器数组转换为对应的基元数组,**ConverTo.boxed()** 将其转换回来。