1 /* 2 * Copyright (C) 2021 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 /* 18 * @test 19 * @bug 8000955 20 * @summary Map.Entry implementations need to comply with Map.Entry.hashCode() defined behaviour. 21 * @author ngmr 22 */ 23 package test.java.util.Map; 24 25 import java.util.*; 26 import java.util.concurrent.ConcurrentHashMap; 27 import java.util.concurrent.ConcurrentSkipListMap; 28 29 import org.junit.Assert; 30 import org.testng.annotations.Test; 31 32 public class EntryHashCode { 33 private static final int TEST_SIZE = 100; 34 35 static final Object[][] entryData = { 36 new Object[TEST_SIZE], 37 new Object[TEST_SIZE] 38 }; 39 40 @SuppressWarnings("unchecked") 41 static final Map<Object,Object>[] maps = (Map<Object,Object>[])new Map[] { 42 new HashMap<>(), 43 new Hashtable<>(), 44 new IdentityHashMap<>(), 45 new LinkedHashMap<>(), 46 new TreeMap<>(), 47 new WeakHashMap<>(), 48 new ConcurrentHashMap<>(), 49 new ConcurrentSkipListMap<>() 50 }; 51 52 static { 53 for (int i = 0; i < entryData[0].length; i++) { 54 // key objects need to be Comparable for use in TreeMap 55 entryData[0][i] = new Comparable<Object>() { 56 public int compareTo(Object o) { 57 return (hashCode() - o.hashCode()); 58 } 59 }; 60 entryData[1][i] = new Object(); 61 } 62 } 63 addTestData(Map<Object,Object> map)64 private static void addTestData(Map<Object,Object> map) { 65 for (int i = 0; i < entryData[0].length; i++) { 66 map.put(entryData[0][i], entryData[1][i]); 67 } 68 } 69 70 @Test testEntryHashCode()71 public void testEntryHashCode() throws Exception { 72 Exception failure = null; 73 for (Map<Object,Object> map: maps) { 74 addTestData(map); 75 76 try { 77 for (Map.Entry<Object,Object> e: map.entrySet()) { 78 Object key = e.getKey(); 79 Object value = e.getValue(); 80 int expectedEntryHashCode = 81 (Objects.hashCode(key) ^ Objects.hashCode(value)); 82 83 Assert.assertEquals(e.hashCode(), expectedEntryHashCode); 84 } 85 } catch (Exception e) { 86 if (failure == null) { 87 failure = e; 88 } else { 89 failure.addSuppressed(e); 90 } 91 } finally { 92 map.clear(); 93 } 94 } 95 if (failure != null) { 96 Assert.fail();; 97 } 98 } 99 }