• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 }