1 /* 2 * Copyright (c) 2019, 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 import java.util.ArrayList; 25 import java.util.Arrays; 26 import java.util.Collection; 27 import java.util.HashMap; 28 import java.util.HashSet; 29 import java.util.LinkedHashMap; 30 import java.util.LinkedHashSet; 31 import java.util.List; 32 import java.util.Map; 33 import java.util.stream.LongStream; 34 35 /* 36 * @test 37 * @summary HashMap.toArray() behavior tests 38 * @author tvaleev 39 */ 40 public class ToArray { 41 public static void main(String[] args) { 42 checkMap(false); 43 checkMap(true); 44 checkSet(false); 45 checkSet(true); 46 } 47 48 private static <T extends Comparable<T>> void checkToArray(String message, T[] expected, Collection<T> collection, 49 boolean ignoreOrder) { 50 if (ignoreOrder) { 51 Arrays.sort(expected); 52 } 53 checkToObjectArray(message, expected, collection, ignoreOrder); 54 checkToTypedArray(message, expected, Arrays.copyOf(expected, 0), collection, ignoreOrder); 55 checkToTypedArray(message, expected, expected.clone(), collection, ignoreOrder); 56 if (expected.length > 0) { 57 T[] biggerArray = Arrays.copyOf(expected, expected.length * 2); 58 System.arraycopy(expected, 0, biggerArray, expected.length, expected.length); 59 checkToTypedArray(message, expected, biggerArray, collection, ignoreOrder); 60 } 61 } 62 63 private static <T extends Comparable<T>> void checkToTypedArray(String message, T[] expected, T[] inputArray, 64 Collection<T> collection, boolean ignoreOrder) { 65 T[] res = collection.toArray(inputArray); 66 if (expected.length <= inputArray.length && res != inputArray) { 67 throw new AssertionError(message + ": not the same array returned"); 68 } 69 if (res.getClass() != expected.getClass()) { 70 throw new AssertionError(message + ": wrong class returned: " + res.getClass()); 71 } 72 if (res.length < expected.length) { 73 throw new AssertionError(message + ": length is smaller than expected: " + res.length + " < " + expected.length); 74 } 75 if (ignoreOrder) { 76 Arrays.sort(res, 0, Math.min(res.length, expected.length)); 77 } 78 if (inputArray.length <= expected.length) { 79 if (!Arrays.equals(res, expected)) { 80 throw new AssertionError(message + ": not equal: " + Arrays.toString(expected) + " != " + 81 Arrays.toString(res)); 82 } 83 } else { 84 int mismatch = Arrays.mismatch(expected, res); 85 if (mismatch != expected.length) { 86 throw new AssertionError(message + ": mismatch at " + mismatch); 87 } 88 if (res[expected.length] != null) { 89 throw new AssertionError(message + ": no null at position " + expected.length); 90 } 91 // The tail of bigger array after expected.length position must be untouched 92 mismatch = Arrays 93 .mismatch(expected, 1, expected.length, res, expected.length + 1, res.length); 94 if (mismatch != -1) { 95 throw new AssertionError(message + ": mismatch at " + mismatch); 96 } 97 } 98 } 99 100 private static <T extends Comparable<T>> void checkToObjectArray(String message, T[] expected, 101 Collection<T> collection, boolean ignoreOrder) { 102 Object[] objects = collection.toArray(); 103 if (objects.getClass() != Object[].class) { 104 throw new AssertionError(message + ": wrong class returned: " + objects.getClass()); 105 } 106 if (ignoreOrder) { 107 Arrays.sort(objects); 108 } 109 int mismatch = Arrays.mismatch(expected, objects); 110 if (mismatch != -1) { 111 throw new AssertionError(message + ": mismatch at " + mismatch); 112 } 113 } 114 115 private static void checkMap(boolean ordered) { 116 Map<String, String> map = ordered ? new LinkedHashMap<>() : new HashMap<>(); 117 checkToArray("Empty-keys", new String[0], map.keySet(), !ordered); 118 checkToArray("Empty-values", new String[0], map.values(), !ordered); 119 120 List<String> keys = new ArrayList<>(); 121 List<String> values = new ArrayList<>(); 122 for (int i = 0; i < 100; i++) { 123 keys.add(String.valueOf(i)); 124 values.add(String.valueOf(i * 2)); 125 map.put(String.valueOf(i), String.valueOf(i * 2)); 126 checkToArray(i + "-keys", keys.toArray(new String[0]), map.keySet(), !ordered); 127 checkToArray(i + "-values", values.toArray(new String[0]), map.values(), !ordered); 128 } 129 map.clear(); 130 checkToArray("Empty-keys", new String[0], map.keySet(), !ordered); 131 checkToArray("Empty-values", new String[0], map.values(), !ordered); 132 } 133 134 private static void checkSet(boolean ordered) { 135 Collection<String> set = ordered ? new LinkedHashSet<>() : new HashSet<>(); 136 checkToArray("Empty", new String[0], set, !ordered); 137 set.add("foo"); 138 checkToArray("One", new String[]{"foo"}, set, !ordered); 139 set.add("bar"); 140 checkToArray("Two", new String[]{"foo", "bar"}, set, !ordered); 141 142 Collection<Long> longSet = ordered ? new LinkedHashSet<>() : new HashSet<>(); 143 for (int x = 0; x < 100; x++) { 144 longSet.add((long) x); 145 } 146 checkToArray("100", LongStream.range(0, 100).boxed().toArray(Long[]::new), longSet, !ordered); 147 longSet.clear(); 148 checkToArray("After clear", new Long[0], longSet, !ordered); 149 for (int x = 0; x < 100; x++) { 150 longSet.add(((long) x) | (((long) x) << 32)); 151 } 152 checkToArray("Collisions", LongStream.range(0, 100).mapToObj(x -> x | (x << 32)) 153 .toArray(Long[]::new), longSet, !ordered); 154 } 155 }