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