• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2003, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.
8  *
9  * This code is distributed in the hope that it will be useful, but WITHOUT
10  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12  * version 2 for more details (a copy is included in the LICENSE file that
13  * accompanied this code).
14  *
15  * You should have received a copy of the GNU General Public License version
16  * 2 along with this work; if not, write to the Free Software Foundation,
17  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18  *
19  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20  * or visit www.oracle.com if you need additional information or have any
21  * questions.
22  */
23 
24 /*
25  * @test
26  * @bug     4906359 6239296
27  * @summary Basic test for content-based array object methods
28  * @author  Josh Bloch, Martin Buchholz
29  * @key randomness
30  */
31 
32 package test.java.util.Arrays;
33 
34 import java.util.*;
35 import java.io.*;
36 
37 public class ArrayObjectMethods {
38     int[] sizes = {0, 10, 100, 200, 1000};
39 
test(String[] args)40     void test(String[] args) throws Throwable {
41         equal(Arrays.deepToString(null), "null");
42         equal(Arrays.deepToString(new Object[]{}), "[]");
43         equal(Arrays.deepToString(new Object[]{null}), "[null]");
44         equal(Arrays.deepToString(new Object[]{null, 1}), "[null, 1]");
45         equal(Arrays.deepToString(new Object[]{1, null}), "[1, null]");
46         equal(Arrays.deepToString(new Object[]{new Object[]{}, null}), "[[], null]");
47 
48         {
49             Object[] a = {1, null};
50             a[1] = a;
51             equal(Arrays.deepToString(a), "[1, [...]]");
52             a[0] = a;
53             equal(Arrays.deepToString(a), "[[...], [...]]");
54             a[0] = a[1] = new Object[]{1, null, a};
55             equal(Arrays.deepToString(a), "[[1, null, [...]], [1, null, [...]]]");
56         }
57 
58         for (int size : sizes) {
59             {
60                 long[] a = Rnd.longArray(size);
61                 equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
62                 equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
63             }
64             {
65                 int[] a = Rnd.intArray(size);
66                 equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
67                 equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
68             }
69             {
70                 short[] a = Rnd.shortArray(size);
71                 equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
72                 equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
73             }
74             {
75                 char[] a = Rnd.charArray(size);
76                 equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
77                 equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
78             }
79             {
80                 byte[] a = Rnd.byteArray(size);
81                 equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
82                 equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
83             }
84             {
85                 boolean[] a = Rnd.booleanArray(size);
86                 equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
87                 equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
88             }
89             {
90                 double[] a = Rnd.doubleArray(size);
91                 equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
92                 equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
93             }
94             {
95                 float[] a = Rnd.floatArray(size);
96                 equal(Arrays.toString(a), PrimitiveArrays.asList(a).toString());
97                 equal(Arrays.hashCode(a), PrimitiveArrays.asList(a).hashCode());
98             }
99             {
100                 Object[] a = Rnd.flatObjectArray(size);
101                 equal(Arrays.toString(a), Arrays.asList(a).toString());
102                 equal(Arrays.deepToString(a), Arrays.asList(a).toString());
103                 equal(Arrays.hashCode(a), Arrays.asList(a).hashCode());
104             }
105 
106             if (size <= 200) {
107                 Object[] a = Rnd.nestedObjectArray(size);
108                 List aList = deepToList(a);
109                 equal(Arrays.toString(a), Arrays.asList(a).toString());
110                 equal(Arrays.deepToString(a), aList.toString());
111                 equal(Arrays.deepHashCode(a), aList.hashCode());
112                 equal(Arrays.hashCode(a), Arrays.asList(a).hashCode());
113 
114                 Object[] deepCopy = (Object[]) deepCopy(a);
115                 check(Arrays.deepEquals(a, deepCopy));
116                 check(Arrays.deepEquals(deepCopy, a));
117 
118                 // Make deepCopy != a
119                 if (size == 0)
120                     deepCopy = new Object[] {"foo"};
121                 else if (deepCopy[deepCopy.length - 1] == null)
122                     deepCopy[deepCopy.length - 1] = "baz";
123                 else
124                     deepCopy[deepCopy.length - 1] = null;
125                 check(! Arrays.deepEquals(a, deepCopy));
126                 check(! Arrays.deepEquals(deepCopy, a));
127             }
128         }
129     }
130 
131     // Utility method to turn an array into a list "deeply," turning
132     // all primitives into objects
deepToList(Object[] a)133     List<Object> deepToList(Object[] a) {
134         List<Object> result = new ArrayList<Object>();
135         for (Object e : a) {
136             if (e instanceof byte[])
137                 result.add(PrimitiveArrays.asList((byte[])e));
138             else if (e instanceof short[])
139                 result.add(PrimitiveArrays.asList((short[])e));
140             else if (e instanceof int[])
141                 result.add(PrimitiveArrays.asList((int[])e));
142             else if (e instanceof long[])
143                 result.add(PrimitiveArrays.asList((long[])e));
144             else if (e instanceof char[])
145                 result.add(PrimitiveArrays.asList((char[])e));
146             else if (e instanceof double[])
147                 result.add(PrimitiveArrays.asList((double[])e));
148             else if (e instanceof float[])
149                 result.add(PrimitiveArrays.asList((float[])e));
150             else if (e instanceof boolean[])
151                 result.add(PrimitiveArrays.asList((boolean[])e));
152             else if (e instanceof Object[])
153                 result.add(deepToList((Object[])e));
154             else
155                 result.add(e);
156         }
157         return result;
158     }
159 
160     // Utility method to do a deep copy of an object *very slowly* using
161     // serialization/deserialization
deepCopy(Object oldObj)162     Object deepCopy(Object oldObj) {
163         try {
164             ByteArrayOutputStream bos = new ByteArrayOutputStream();
165             ObjectOutputStream oos = new ObjectOutputStream(bos);
166             oos.writeObject(oldObj);
167             oos.flush();
168             ByteArrayInputStream bin = new ByteArrayInputStream(
169                 bos.toByteArray());
170             ObjectInputStream ois = new ObjectInputStream(bin);
171             return ois.readObject();
172         } catch(Exception e) {
173             throw new IllegalArgumentException(e);
174         }
175     }
176 
177     //--------------------- Infrastructure ---------------------------
178     volatile int passed = 0, failed = 0;
pass()179     void pass() {passed++;}
fail()180     void fail() {failed++; Thread.dumpStack();}
fail(String msg)181     void fail(String msg) {System.err.println(msg); fail();}
unexpected(Throwable t)182     void unexpected(Throwable t) {failed++; t.printStackTrace();}
check(boolean cond)183     void check(boolean cond) {if (cond) pass(); else fail();}
equal(Object x, Object y)184     void equal(Object x, Object y) {
185         if (x == null ? y == null : x.equals(y)) pass();
186         else fail(x + " not equal to " + y);}
main(String[] args)187     public static void main(String[] args) throws Throwable {
188         new ArrayObjectMethods().instanceMain(args);}
instanceMain(String[] args)189     void instanceMain(String[] args) throws Throwable {
190         try {test(args);} catch (Throwable t) {unexpected(t);}
191         System.out.printf("%nPassed = %d, failed = %d%n%n", passed, failed);
192         if (failed > 0) throw new AssertionError("Some tests failed");}
193 }
194 
195 /**
196  * Methods to generate "interesting" random primitives and primitive
197  * arrays.  Unlike Random.nextXxx, these methods return small values
198  * and boundary values (e.g., 0, -1, NaN) with greater than normal
199  * likelihood.
200  */
201 
202 class Rnd {
203     private static Random rnd = new Random();
204 
nextLong()205     public static long nextLong() {
206         switch(rnd.nextInt(10)) {
207             case 0:  return 0;
208             case 1:  return Long.MIN_VALUE;
209             case 2:  return Long.MAX_VALUE;
210             case 3: case 4: case 5:
211                      return (long) (rnd.nextInt(20) - 10);
212             default: return rnd.nextLong();
213         }
214     }
215 
nextInt()216     public static int nextInt() {
217         switch(rnd.nextInt(10)) {
218             case 0:  return 0;
219             case 1:  return Integer.MIN_VALUE;
220             case 2:  return Integer.MAX_VALUE;
221             case 3: case 4: case 5:
222                      return rnd.nextInt(20) - 10;
223             default: return rnd.nextInt();
224         }
225     }
226 
nextShort()227     public static short nextShort() {
228         switch(rnd.nextInt(10)) {
229             case 0:  return 0;
230             case 1:  return Short.MIN_VALUE;
231             case 2:  return Short.MAX_VALUE;
232             case 3: case 4: case 5:
233                      return (short) (rnd.nextInt(20) - 10);
234             default: return (short) rnd.nextInt();
235         }
236     }
237 
nextChar()238     public static char nextChar() {
239         switch(rnd.nextInt(10)) {
240             case 0:  return 0;
241             case 1:  return Character.MIN_VALUE;
242             case 2:  return Character.MAX_VALUE;
243             case 3: case 4: case 5:
244                      return (char) (rnd.nextInt(20) - 10);
245             default: return (char) rnd.nextInt();
246         }
247     }
248 
nextByte()249     public static byte nextByte() {
250         switch(rnd.nextInt(10)) {
251             case 0:  return 0;
252             case 1:  return Byte.MIN_VALUE;
253             case 2:  return Byte.MAX_VALUE;
254             case 3: case 4: case 5:
255                      return (byte) (rnd.nextInt(20) - 10);
256             default: return (byte) rnd.nextInt();
257         }
258     }
259 
nextBoolean()260     public static boolean nextBoolean() {
261         return rnd.nextBoolean();
262     }
263 
nextDouble()264     public static double nextDouble() {
265         switch(rnd.nextInt(20)) {
266             case 0:  return 0;
267             case 1:  return -0.0;
268             case 2:  return Double.MIN_VALUE;
269             case 3:  return Double.MAX_VALUE;
270             case 4:  return Double.NaN;
271             case 5:  return Double.NEGATIVE_INFINITY;
272             case 6:  return Double.POSITIVE_INFINITY;
273             case 7: case 8: case 9:
274                      return (rnd.nextInt(20) - 10);
275             default: return rnd.nextDouble();
276         }
277     }
278 
nextFloat()279     public static float nextFloat() {
280         switch(rnd.nextInt(20)) {
281             case 0:  return 0;
282             case 1:  return -0.0f;
283             case 2:  return Float.MIN_VALUE;
284             case 3:  return Float.MAX_VALUE;
285             case 4:  return Float.NaN;
286             case 5:  return Float.NEGATIVE_INFINITY;
287             case 6:  return Float.POSITIVE_INFINITY;
288             case 7: case 8: case 9:
289                      return (rnd.nextInt(20) - 10);
290             default: return rnd.nextFloat();
291         }
292     }
293 
nextObject()294     public static Object nextObject() {
295         switch(rnd.nextInt(10)) {
296             case 0:  return null;
297             case 1:  return "foo";
298             case 2:  case 3: case 4:
299                      return Double.valueOf(nextDouble());
300             default: return Integer.valueOf(nextInt());
301         }
302     }
303 
longArray(int length)304     public static long[] longArray(int length) {
305         long[] result = new long[length];
306         for (int i = 0; i < length; i++)
307             result[i] = Rnd.nextLong();
308         return result;
309     }
310 
intArray(int length)311     public static int[] intArray(int length) {
312         int[] result = new int[length];
313         for (int i = 0; i < length; i++)
314             result[i] = Rnd.nextInt();
315         return result;
316     }
317 
shortArray(int length)318     public static short[] shortArray(int length) {
319         short[] result = new short[length];
320         for (int i = 0; i < length; i++)
321             result[i] = Rnd.nextShort();
322         return result;
323     }
324 
charArray(int length)325     public static char[] charArray(int length) {
326         char[] result = new char[length];
327         for (int i = 0; i < length; i++)
328             result[i] = Rnd.nextChar();
329         return result;
330     }
331 
byteArray(int length)332     public static byte[] byteArray(int length) {
333         byte[] result = new byte[length];
334         for (int i = 0; i < length; i++)
335             result[i] = Rnd.nextByte();
336         return result;
337     }
338 
booleanArray(int length)339     public static boolean[] booleanArray(int length) {
340         boolean[] result = new boolean[length];
341         for (int i = 0; i < length; i++)
342             result[i] = Rnd.nextBoolean();
343         return result;
344     }
345 
doubleArray(int length)346     public static double[] doubleArray(int length) {
347         double[] result = new double[length];
348         for (int i = 0; i < length; i++)
349             result[i] = Rnd.nextDouble();
350         return result;
351     }
352 
floatArray(int length)353     public static float[] floatArray(int length) {
354         float[] result = new float[length];
355         for (int i = 0; i < length; i++)
356             result[i] = Rnd.nextFloat();
357         return result;
358     }
359 
flatObjectArray(int length)360     public static Object[] flatObjectArray(int length) {
361         Object[] result = new Object[length];
362         for (int i = 0; i < length; i++)
363             result[i] = Rnd.nextObject();
364         return result;
365     }
366 
367     // Calling this for length >> 100 is likely to run out of memory!  It
368     // should be perhaps be tuned to allow for longer arrays
nestedObjectArray(int length)369     public static Object[] nestedObjectArray(int length) {
370         Object[] result = new Object[length];
371         for (int i = 0; i < length; i++) {
372             switch(rnd.nextInt(16)) {
373                 case 0:  result[i] = nestedObjectArray(length/2);
374                          break;
375                 case 1:  result[i] = longArray(length/2);
376                          break;
377                 case 2:  result[i] = intArray(length/2);
378                          break;
379                 case 3:  result[i] = shortArray(length/2);
380                          break;
381                 case 4:  result[i] = charArray(length/2);
382                          break;
383                 case 5:  result[i] = byteArray(length/2);
384                          break;
385                 case 6:  result[i] = floatArray(length/2);
386                          break;
387                 case 7:  result[i] = doubleArray(length/2);
388                          break;
389                 case 8:  result[i] = longArray(length/2);
390                          break;
391                 default: result[i] = Rnd.nextObject();
392             }
393         }
394         return result;
395     }
396 }
397 
398 /**
399  * Primitive arrays viewed as lists.  Inefficient but cool.
400  * This utility should be generally useful in writing regression/unit/basic
401  * tests.
402  */
403 
404 class PrimitiveArrays {
asList(final long[] a)405     public static List<Long> asList(final long[] a) {
406         return new AbstractList<Long>() {
407             public Long get(int i) { return a[i]; }
408             public int size()      { return a.length; }
409 
410             public Long set(int i, Long e) {
411                 long oldVal = a[i];
412                 a[i] = e;
413                 return oldVal;
414             }
415         };
416     }
417 
418     public static List<Integer> asList(final int[] a) {
419         return new AbstractList<Integer>() {
420             public Integer get(int i) { return a[i]; }
421             public int size()         { return a.length; }
422 
423             public Integer set(int i, Integer e) {
424                 int oldVal = a[i];
425                 a[i] = e;
426                 return oldVal;
427             }
428         };
429     }
430 
431     public static List<Short> asList(final short[] a) {
432         return new AbstractList<Short>() {
433             public Short get(int i) { return a[i]; }
434             public int size()       { return a.length; }
435 
436             public Short set(int i, Short e) {
437                 short oldVal = a[i];
438                 a[i] = e;
439                 return oldVal;
440             }
441         };
442     }
443 
444     public static List<Character> asList(final char[] a) {
445         return new AbstractList<Character>() {
446             public Character get(int i) { return a[i]; }
447             public int size()           { return a.length; }
448 
449             public Character set(int i, Character e) {
450                 Character oldVal = a[i];
451                 a[i] = e;
452                 return oldVal;
453             }
454         };
455     }
456 
457     public static List<Byte> asList(final byte[] a) {
458         return new AbstractList<Byte>() {
459             public Byte get(int i) { return a[i]; }
460             public int size()      { return a.length; }
461 
462             public Byte set(int i, Byte e) {
463                 Byte oldVal = a[i];
464                 a[i] = e;
465                 return oldVal;
466             }
467         };
468     }
469 
470     public static List<Boolean> asList(final boolean[] a) {
471         return new AbstractList<Boolean>() {
472             public Boolean get(int i) { return a[i]; }
473             public int size()         { return a.length; }
474 
475             public Boolean set(int i, Boolean e) {
476                 Boolean oldVal = a[i];
477                 a[i] = e;
478                 return oldVal;
479             }
480         };
481     }
482 
483     public static List<Double> asList(final double[] a) {
484         return new AbstractList<Double>() {
485             public Double get(int i) { return a[i]; }
486             public int size()        { return a.length; }
487 
488             public Double set(int i, Double e) {
489                 Double oldVal = a[i];
490                 a[i] = e;
491                 return oldVal;
492             }
493         };
494     }
495 
496     public static List<Float> asList(final float[] a) {
497         return new AbstractList<Float>() {
498             public Float get(int i) { return a[i]; }
499             public int size()       { return a.length; }
500 
501             public Float set(int i, Float e) {
502                 Float oldVal = a[i];
503                 a[i] = e;
504                 return oldVal;
505             }
506         };
507     }
508 }
509