1/* 2 * Licensed to the Apache Software Foundation (ASF) under one or more 3 * contributor license agreements. See the NOTICE file distributed with 4 * this work for additional information regarding copyright ownership. 5 * The ASF licenses this file to You under the Apache License, Version 2.0 6 * (the "License"); you may not use this file except in compliance with 7 * the License. You may obtain a copy of the License at 8 * 9 * http://www.apache.org/licenses/LICENSE-2.0 10 * 11 * Unless required by applicable law or agreed to in writing, software 12 * distributed under the License is distributed on an "AS IS" BASIS, 13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14 * See the License for the specific language governing permissions and 15 * limitations under the License. 16 */ 17 18package org.apache.harmony.tests.java.util; 19 20import libcore.java.util.SpliteratorTester; 21import org.apache.harmony.testframework.serialization.SerializationTest; 22import org.apache.harmony.testframework.serialization.SerializationTest.SerializableAssert; 23import tests.support.Support_MapTest2; 24import java.io.Serializable; 25import java.util.AbstractMap; 26import java.util.ArrayList; 27import java.util.Arrays; 28import java.util.Collection; 29import java.util.Comparator; 30import java.util.ConcurrentModificationException; 31import java.util.HashMap; 32import java.util.HashSet; 33import java.util.IdentityHashMap; 34import java.util.Iterator; 35import java.util.Map; 36import java.util.Set; 37import java.util.TreeMap; 38import java.util.TreeSet; 39import java.util.function.BiFunction; 40 41public class IdentityHashMapTest extends junit.framework.TestCase { 42 private static final String ID = "hello"; 43 44 class MockMap extends AbstractMap { 45 public Set entrySet() { 46 return null; 47 } 48 public int size(){ 49 return 0; 50 } 51 } 52 /* 53 * TODO: change all the statements testing the keys and values with equals() 54 * method to check for reference equality instead 55 */ 56 57 IdentityHashMap hm; 58 59 final static int hmSize = 1000; 60 61 Object[] objArray; 62 63 Object[] objArray2; 64 65 /** 66 * java.util.IdentityHashMap#IdentityHashMap() 67 */ 68 public void test_Constructor() { 69 // Test for method java.util.IdentityHashMap() 70 new Support_MapTest2(new IdentityHashMap()).runTest(); 71 72 IdentityHashMap hm2 = new IdentityHashMap(); 73 assertEquals("Created incorrect IdentityHashMap", 0, hm2.size()); 74 } 75 76 /** 77 * java.util.IdentityHashMap#IdentityHashMap(int) 78 */ 79 public void test_ConstructorI() { 80 // Test for method java.util.IdentityHashMap(int) 81 IdentityHashMap hm2 = new IdentityHashMap(5); 82 assertEquals("Created incorrect IdentityHashMap", 0, hm2.size()); 83 try { 84 new IdentityHashMap(-1); 85 fail("Failed to throw IllegalArgumentException for initial capacity < 0"); 86 } catch (IllegalArgumentException e) { 87 //expected 88 } 89 90 IdentityHashMap empty = new IdentityHashMap(0); 91 assertNull("Empty IdentityHashMap access", empty.get("nothing")); 92 empty.put("something", "here"); 93 assertTrue("cannot get element", empty.get("something") == "here"); 94 } 95 96 /** 97 * java.util.IdentityHashMap#IdentityHashMap(java.util.Map) 98 */ 99 public void test_ConstructorLjava_util_Map() { 100 // Test for method java.util.IdentityHashMap(java.util.Map) 101 Map myMap = new TreeMap(); 102 for (int counter = 0; counter < hmSize; counter++) 103 myMap.put(objArray2[counter], objArray[counter]); 104 IdentityHashMap hm2 = new IdentityHashMap(myMap); 105 for (int counter = 0; counter < hmSize; counter++) 106 assertTrue("Failed to construct correct IdentityHashMap", hm 107 .get(objArray2[counter]) == hm2.get(objArray2[counter])); 108 109 Map mockMap = new MockMap(); 110 hm2 = new IdentityHashMap(mockMap); 111 assertEquals("Size should be 0", 0, hm2.size()); 112 113 try { 114 new IdentityHashMap(null); 115 fail("NullPointerException expected"); 116 } catch (NullPointerException e) { 117 //expected 118 } 119 } 120 121 /** 122 * java.util.IdentityHashMap#clear() 123 */ 124 public void test_clear() { 125 // Test for method void java.util.IdentityHashMap.clear() 126 hm.clear(); 127 assertEquals("Clear failed to reset size", 0, hm.size()); 128 for (int i = 0; i < hmSize; i++) 129 assertNull("Failed to clear all elements", 130 hm.get(objArray2[i])); 131 132 } 133 134 /** 135 * java.util.IdentityHashMap#clone() 136 */ 137 public void test_clone() { 138 // Test for method java.lang.Object java.util.IdentityHashMap.clone() 139 IdentityHashMap hm2 = (IdentityHashMap) hm.clone(); 140 assertTrue("Clone answered equivalent IdentityHashMap", hm2 != hm); 141 for (int counter = 0; counter < hmSize; counter++) 142 assertTrue("Clone answered unequal IdentityHashMap", hm 143 .get(objArray2[counter]) == hm2.get(objArray2[counter])); 144 145 IdentityHashMap map = new IdentityHashMap(); 146 map.put("key", "value"); 147 // get the keySet() and values() on the original Map 148 Set keys = map.keySet(); 149 Collection values = map.values(); 150 assertEquals("values() does not work", 151 "value", values.iterator().next()); 152 assertEquals("keySet() does not work", 153 "key", keys.iterator().next()); 154 AbstractMap map2 = (AbstractMap) map.clone(); 155 map2.put("key", "value2"); 156 Collection values2 = map2.values(); 157 assertTrue("values() is identical", values2 != values); 158 // values() and keySet() on the cloned() map should be different 159 assertEquals("values() was not cloned", 160 "value2", values2.iterator().next()); 161 map2.clear(); 162 map2.put("key2", "value3"); 163 Set key2 = map2.keySet(); 164 assertTrue("keySet() is identical", key2 != keys); 165 assertEquals("keySet() was not cloned", 166 "key2", key2.iterator().next()); 167 } 168 169 /** 170 * java.util.IdentityHashMap#containsKey(java.lang.Object) 171 */ 172 public void test_containsKeyLjava_lang_Object() { 173 // Test for method boolean 174 // java.util.IdentityHashMap.containsKey(java.lang.Object) 175 assertTrue("Returned false for valid key", hm 176 .containsKey(objArray2[23])); 177 assertTrue("Returned true for copy of valid key", !hm 178 .containsKey(new Integer(23).toString())); 179 assertTrue("Returned true for invalid key", !hm.containsKey("KKDKDKD")); 180 181 IdentityHashMap m = new IdentityHashMap(); 182 m.put(null, "test"); 183 assertTrue("Failed with null key", m.containsKey(null)); 184 assertTrue("Failed with missing key matching null hash", !m 185 .containsKey(new Integer(0))); 186 } 187 188 /** 189 * java.util.IdentityHashMap#containsValue(java.lang.Object) 190 */ 191 public void test_containsValueLjava_lang_Object() { 192 // Test for method boolean 193 // java.util.IdentityHashMap.containsValue(java.lang.Object) 194 assertTrue("Returned false for valid value", hm 195 .containsValue(objArray[19])); 196 assertTrue("Returned true for invalid valie", !hm 197 .containsValue(new Integer(-9))); 198 } 199 200 /** 201 * java.util.IdentityHashMap#entrySet() 202 */ 203 public void test_entrySet() { 204 // Test for method java.util.Set java.util.IdentityHashMap.entrySet() 205 Set s = hm.entrySet(); 206 Iterator i = s.iterator(); 207 assertTrue("Returned set of incorrect size", hm.size() == s.size()); 208 while (i.hasNext()) { 209 Map.Entry m = (Map.Entry) i.next(); 210 assertTrue("Returned incorrect entry set", hm.containsKey(m 211 .getKey()) 212 && hm.containsValue(m.getValue())); 213 } 214 } 215 216 /** 217 * java.util.IdentityHashMap#get(java.lang.Object) 218 */ 219 public void test_getLjava_lang_Object() { 220 // Test for method java.lang.Object 221 // java.util.IdentityHashMap.get(java.lang.Object) 222 assertNull("Get returned non-null for non existent key", 223 hm.get("T")); 224 hm.put("T", "HELLO"); 225 assertEquals("Get returned incorecct value for existing key", "HELLO", hm.get("T") 226 ); 227 228 IdentityHashMap m = new IdentityHashMap(); 229 m.put(null, "test"); 230 assertEquals("Failed with null key", "test", m.get(null)); 231 assertNull("Failed with missing key matching null hash", m 232 .get(new Integer(0))); 233 } 234 235 /** 236 * java.util.IdentityHashMap#isEmpty() 237 */ 238 public void test_isEmpty() { 239 // Test for method boolean java.util.IdentityHashMap.isEmpty() 240 assertTrue("Returned false for new map", new IdentityHashMap() 241 .isEmpty()); 242 assertTrue("Returned true for non-empty", !hm.isEmpty()); 243 } 244 245 /** 246 * java.util.IdentityHashMap#keySet() 247 */ 248 public void test_keySet() { 249 // Test for method java.util.Set java.util.IdentityHashMap.keySet() 250 Set s = hm.keySet(); 251 assertTrue("Returned set of incorrect size()", s.size() == hm.size()); 252 for (int i = 0; i < objArray.length; i++) { 253 assertTrue("Returned set does not contain all keys", s 254 .contains(objArray2[i])); 255 } 256 257 IdentityHashMap m = new IdentityHashMap(); 258 m.put(null, "test"); 259 assertTrue("Failed with null key", m.keySet().contains(null)); 260 assertNull("Failed with null key", m.keySet().iterator().next()); 261 262 Map map = new IdentityHashMap(101); 263 map.put(new Integer(1), "1"); 264 map.put(new Integer(102), "102"); 265 map.put(new Integer(203), "203"); 266 Iterator it = map.keySet().iterator(); 267 Integer remove1 = (Integer) it.next(); 268 it.hasNext(); 269 it.remove(); 270 Integer remove2 = (Integer) it.next(); 271 it.remove(); 272 ArrayList list = new ArrayList(Arrays.asList(new Integer[] { 273 new Integer(1), new Integer(102), new Integer(203) })); 274 list.remove(remove1); 275 list.remove(remove2); 276 assertTrue("Wrong result", it.next().equals(list.get(0))); 277 assertEquals("Wrong size", 1, map.size()); 278 assertTrue("Wrong contents", map.keySet().iterator().next().equals( 279 list.get(0))); 280 281 Map map2 = new IdentityHashMap(101); 282 map2.put(new Integer(1), "1"); 283 map2.put(new Integer(4), "4"); 284 Iterator it2 = map2.keySet().iterator(); 285 Integer remove3 = (Integer) it2.next(); 286 Integer next; 287 if (remove3.intValue() == 1) 288 next = new Integer(4); 289 else 290 next = new Integer(1); 291 it2.hasNext(); 292 it2.remove(); 293 assertTrue("Wrong result 2", it2.next().equals(next)); 294 assertEquals("Wrong size 2", 1, map2.size()); 295 assertTrue("Wrong contents 2", map2.keySet().iterator().next().equals( 296 next)); 297 } 298 299 /** 300 * java.util.IdentityHashMap#put(java.lang.Object, java.lang.Object) 301 */ 302 public void test_putLjava_lang_ObjectLjava_lang_Object() { 303 // Test for method java.lang.Object 304 // java.util.IdentityHashMap.put(java.lang.Object, java.lang.Object) 305 hm.put("KEY", "VALUE"); 306 assertEquals("Failed to install key/value pair", 307 "VALUE", hm.get("KEY")); 308 309 IdentityHashMap m = new IdentityHashMap(); 310 Short s0 = new Short((short) 0); 311 m.put(s0, "short"); 312 m.put(null, "test"); 313 Integer i0 = new Integer(0); 314 m.put(i0, "int"); 315 assertEquals("Failed adding to bucket containing null", 316 "short", m.get(s0)); 317 assertEquals("Failed adding to bucket containing null2", "int", m.get(i0) 318 ); 319 320 IdentityHashMap<Object, Object> map = new IdentityHashMap<Object, Object>(); 321 322 // Test null as a key. 323 Object value = "Some value"; 324 map.put(null, value); 325 assertSame("Assert 0: Failure getting null key", value, map.get(null)); 326 327 // Test null as a value 328 Object key = "Some key"; 329 map.put(key, null); 330 assertNull("Assert 1: Failure getting null value", map.get(key)); 331 } 332 333 /** 334 * java.util.IdentityHashMap#putAll(java.util.Map) 335 */ 336 public void test_putAllLjava_util_Map() { 337 // Test for method void java.util.IdentityHashMap.putAll(java.util.Map) 338 IdentityHashMap hm2 = new IdentityHashMap(); 339 hm2.putAll(hm); 340 for (int i = 0; i < 1000; i++) 341 assertTrue("Failed to clear all elements", hm2.get(objArray2[i]) 342 .equals((new Integer(i)))); 343 344 hm2 = new IdentityHashMap(); 345 Map mockMap = new MockMap(); 346 hm2.putAll(mockMap); 347 assertEquals("Size should be 0", 0, hm2.size()); 348 349 try { 350 hm2.putAll(null); 351 fail("NullPointerException expected"); 352 } catch (NullPointerException e) { 353 //expected 354 } 355 } 356 357 /** 358 * java.util.IdentityHashMap#remove(java.lang.Object) 359 */ 360 public void test_removeLjava_lang_Object() { 361 // Test for method java.lang.Object 362 // java.util.IdentityHashMap.remove(java.lang.Object) 363 int size = hm.size(); 364 Integer x = ((Integer) hm.remove(objArray2[9])); 365 assertTrue("Remove returned incorrect value", x.equals(new Integer(9))); 366 assertNull("Failed to remove given key", hm.get(objArray2[9])); 367 assertTrue("Failed to decrement size", hm.size() == (size - 1)); 368 assertNull("Remove of non-existent key returned non-null", hm 369 .remove("LCLCLC")); 370 371 IdentityHashMap m = new IdentityHashMap(); 372 m.put(null, "test"); 373 assertNull("Failed with same hash as null", 374 m.remove(objArray[0])); 375 assertEquals("Failed with null key", "test", m.remove(null)); 376 377 // Regression for HARMONY-37 378 IdentityHashMap<String, String> hashMap = new IdentityHashMap<String, String>(); 379 hashMap.remove("absent"); 380 assertEquals("Assert 0: Size is incorrect", 0, hashMap.size()); 381 382 hashMap.put("key", "value"); 383 hashMap.remove("key"); 384 assertEquals("Assert 1: After removing non-null element size is incorrect", 0, hashMap.size()); 385 386 hashMap.put(null, null); 387 assertEquals("Assert 2: adding literal null failed", 1, hashMap.size()); 388 hashMap.remove(null); 389 assertEquals("Assert 3: After removing null element size is incorrect", 0, hashMap.size()); 390 } 391 392 /** 393 * java.util.IdentityHashMap#size() 394 */ 395 public void test_size() { 396 // Test for method int java.util.IdentityHashMap.size() 397 assertEquals("Returned incorrect size, ", (objArray.length + 2), hm 398 .size()); 399 } 400 401 /** 402 * java.util.IdentityHashMap#equals(java.lang.Object) 403 */ 404 public void test_equalsLjava_lang_Object() { 405 IdentityHashMap mapOne = new IdentityHashMap(); 406 IdentityHashMap mapTwo = new IdentityHashMap(); 407 IdentityHashMap mapThree = new IdentityHashMap(); 408 IdentityHashMap mapFour = new IdentityHashMap(); 409 410 String one = "one"; 411 String alsoOne = new String(one); // use the new operator to ensure a 412 // new reference is constructed 413 String two = "two"; 414 String alsoTwo = new String(two); // use the new operator to ensure a 415 // new reference is constructed 416 417 mapOne.put(one, two); 418 mapFour.put(one, two); 419 420 // these two are not equal to the above two 421 mapTwo.put(alsoOne, two); 422 mapThree.put(one, alsoTwo); 423 424 assertEquals("failure of equality of IdentityHashMaps", mapOne, mapFour); 425 assertTrue("failure of non-equality of IdentityHashMaps one and two", 426 !mapOne.equals(mapTwo)); 427 assertTrue("failure of non-equality of IdentityHashMaps one and three", 428 !mapOne.equals(mapThree)); 429 assertTrue("failure of non-equality of IdentityHashMaps two and three", 430 !mapTwo.equals(mapThree)); 431 432 HashMap hashMapTwo = new HashMap(); 433 HashMap hashMapThree = new HashMap(); 434 hashMapTwo.put(alsoOne, two); 435 hashMapThree.put(one, alsoTwo); 436 437 assertTrue( 438 "failure of non-equality of IdentityHashMaps one and Hashmap two", 439 !mapOne.equals(hashMapTwo)); 440 assertTrue( 441 "failure of non-equality of IdentityHashMaps one and Hashmap three", 442 !mapOne.equals(hashMapThree)); 443 } 444 445 /** 446 * java.util.IdentityHashMap#Serialization() 447 */ 448 public void test_Serialization() throws Exception { 449 IdentityHashMap<String, String> map = new IdentityHashMap<String, String>(); 450 map.put(ID, "world"); 451 // BEGIN Android-added 452 // Regression test for null key in serialized IdentityHashMap (1178549) 453 // Together with this change the IdentityHashMap.golden.ser resource 454 // was replaced by a version that contains a map with a null key. 455 map.put(null, "null"); 456 // END Android-added 457 SerializationTest.verifySelf(map, comparator); 458 SerializationTest.verifyGolden(this, map, comparator); 459 } 460 461 /** 462 * Sets up the fixture, for example, open a network connection. This method 463 * is called before a test is executed. 464 */ 465 protected void setUp() { 466 objArray = new Object[hmSize]; 467 objArray2 = new Object[hmSize]; 468 for (int i = 0; i < objArray.length; i++) { 469 objArray[i] = new Integer(i); 470 // Android-changed: the containsKey test requires unique strings. 471 objArray2[i] = new String(objArray[i].toString()); 472 } 473 474 hm = new IdentityHashMap(); 475 for (int i = 0; i < objArray.length; i++) 476 hm.put(objArray2[i], objArray[i]); 477 hm.put("test", null); 478 hm.put(null, "test"); 479 } 480 481 /** 482 * Tears down the fixture, for example, close a network connection. This 483 * method is called after a test is executed. 484 */ 485 protected void tearDown() { 486 objArray = null; 487 objArray2 = null; 488 hm = null; 489 } 490 491 private static final SerializationTest.SerializableAssert comparator = new 492 SerializationTest.SerializableAssert() { 493 494 public void assertDeserialized(Serializable initial, Serializable deserialized) { 495 IdentityHashMap<String, String> initialMap = (IdentityHashMap<String, String>) initial; 496 IdentityHashMap<String, String> deseriaMap = (IdentityHashMap<String, String>) deserialized; 497 assertEquals("should be equal", initialMap.size(), deseriaMap.size()); 498 } 499 500 }; 501 502 /** 503 * java.util.IdentityHashMap#containsKey(java.lang.Object) 504 * java.util.IdentityHashMap#containsValue(java.lang.Object) 505 * java.util.IdentityHashMap#put(java.lang.Object, java.lang.Object) 506 * java.util.IdentityHashMap#get(java.lang.Object) 507 */ 508 public void test_null_Keys_and_Values() { 509 // tests with null keys and values 510 IdentityHashMap map = new IdentityHashMap(); 511 Object result; 512 513 // null key and null value 514 result = map.put(null, null); 515 assertTrue("testA can not find null key", map.containsKey(null)); 516 assertTrue("testA can not find null value", map.containsValue(null)); 517 assertNull("testA can not get null value for null key", 518 map.get(null)); 519 assertNull("testA put returned wrong value", result); 520 521 // null value 522 String value = "a value"; 523 result = map.put(null, value); 524 assertTrue("testB can not find null key", map.containsKey(null)); 525 assertTrue("testB can not find a value with null key", map 526 .containsValue(value)); 527 assertTrue("testB can not get value for null key", 528 map.get(null) == value); 529 assertNull("testB put returned wrong value", result); 530 531 // a null key 532 String key = "a key"; 533 result = map.put(key, null); 534 assertTrue("testC can not find a key with null value", map 535 .containsKey(key)); 536 assertTrue("testC can not find null value", map.containsValue(null)); 537 assertNull("testC can not get null value for key", map.get(key)); 538 assertNull("testC put returned wrong value", result); 539 540 // another null key 541 String anothervalue = "another value"; 542 result = map.put(null, anothervalue); 543 assertTrue("testD can not find null key", map.containsKey(null)); 544 assertTrue("testD can not find a value with null key", map 545 .containsValue(anothervalue)); 546 assertTrue("testD can not get value for null key", 547 map.get(null) == anothervalue); 548 assertTrue("testD put returned wrong value", result == value); 549 550 // remove a null key 551 result = map.remove(null); 552 assertTrue("testE remove returned wrong value", result == anothervalue); 553 assertTrue("testE should not find null key", !map.containsKey(null)); 554 assertTrue("testE should not find a value with null key", !map 555 .containsValue(anothervalue)); 556 assertNull("testE should not get value for null key", 557 map.get(null)); 558 } 559 560 /** 561 * java.util.IdentityHashMap#remove(java.lang.Object) 562 * java.util.IdentityHashMap#keySet() 563 */ 564 public void test_remove() { 565 IdentityHashMap map = new IdentityHashMap(); 566 map.put(null, null); 567 map.put("key1", "value1"); 568 map.put("key2", "value2"); 569 map.remove("key1"); 570 571 assertTrue("Did not remove key1", !map.containsKey("key1")); 572 assertTrue("Did not remove the value for key1", !map 573 .containsValue("value1")); 574 575 assertTrue("Modified key2", map.get("key2") != null 576 && map.get("key2") == "value2"); 577 assertNull("Modified null entry", map.get(null)); 578 } 579 580 /** 581 * java.util.IdentityHashMap#entrySet() 582 * java.util.IdentityHashMap#keySet() 583 * java.util.IdentityHashMap#values() 584 */ 585 public void test_sets() { 586 // tests with null keys and values 587 IdentityHashMap map = new IdentityHashMap(); 588 589 // null key and null value 590 map.put("key", "value"); 591 map.put(null, null); 592 map.put("a key", null); 593 map.put("another key", null); 594 595 Set keyset = map.keySet(); 596 Collection valueset = map.values(); 597 Set entries = map.entrySet(); 598 Iterator it = entries.iterator(); 599 while (it.hasNext()) { 600 Map.Entry entry = (Map.Entry) it.next(); 601 assertTrue("EntrySetIterator can not find entry ", entries 602 .contains(entry)); 603 604 assertTrue("entry key not found in map", map.containsKey(entry 605 .getKey())); 606 assertTrue("entry value not found in map", map.containsValue(entry 607 .getValue())); 608 609 assertTrue("entry key not found in the keyset", keyset 610 .contains(entry.getKey())); 611 assertTrue("entry value not found in the valueset", valueset 612 .contains(entry.getValue())); 613 } 614 } 615 616 /** 617 * java.util.IdentityHashMap#entrySet() 618 * java.util.IdentityHashMap#remove(java.lang.Object) 619 */ 620 public void test_entrySet_removeAll() { 621 IdentityHashMap map = new IdentityHashMap(); 622 for (int i = 0; i < 1000; i++) { 623 map.put(new Integer(i), new Integer(i)); 624 } 625 Set set = map.entrySet(); 626 627 set.removeAll(set); 628 assertEquals("did not remove all elements in the map", 0, map.size()); 629 assertTrue("did not remove all elements in the entryset", set.isEmpty()); 630 631 Iterator it = set.iterator(); 632 assertTrue("entrySet iterator still has elements", !it.hasNext()); 633 } 634 635 /** 636 * java.util.IdentityHashMap#keySet() 637 * java.util.IdentityHashMap#clear() 638 */ 639 public void test_keySet_clear() { 640 IdentityHashMap map = new IdentityHashMap(); 641 for (int i = 0; i < 1000; i++) { 642 map.put(new Integer(i), new Integer(i)); 643 } 644 Set set = map.keySet(); 645 set.clear(); 646 647 assertEquals("did not remove all elements in the map", 0, map.size()); 648 assertTrue("did not remove all elements in the keyset", set.isEmpty()); 649 650 Iterator it = set.iterator(); 651 assertTrue("keySet iterator still has elements", !it.hasNext()); 652 } 653 654 /** 655 * java.util.IdentityHashMap#values() 656 */ 657 public void test_values() { 658 659 IdentityHashMap map = new IdentityHashMap(); 660 for (int i = 0; i < 10; i++) { 661 map.put(new Integer(i), new Integer(i)); 662 } 663 664 Integer key = new Integer(20); 665 Integer value = new Integer(40); 666 map.put(key, value); 667 668 Collection vals = map.values(); 669 boolean result = vals.remove(key); 670 assertTrue("removed entries incorrectly", map.size() == 11 && !result); 671 assertTrue("removed key incorrectly", map.containsKey(key)); 672 assertTrue("removed value incorrectly", map.containsValue(value)); 673 674 result = vals.remove(value); 675 assertTrue("Did not remove entry as expected", map.size() == 10 676 && result); 677 assertTrue("Did not remove key as expected", !map.containsKey(key)); 678 assertTrue("Did not remove value as expected", !map 679 .containsValue(value)); 680 681 // put an equivalent key to a value 682 key = new Integer(1); 683 value = new Integer(100); 684 map.put(key, value); 685 686 result = vals.remove(key); 687 assertTrue("TestB. removed entries incorrectly", map.size() == 11 688 && !result); 689 assertTrue("TestB. removed key incorrectly", map.containsKey(key)); 690 assertTrue("TestB. removed value incorrectly", map.containsValue(value)); 691 692 result = vals.remove(value); 693 assertTrue("TestB. Did not remove entry as expected", map.size() == 10 694 && result); 695 assertTrue("TestB. Did not remove key as expected", !map 696 .containsKey(key)); 697 assertTrue("TestB. Did not remove value as expected", !map 698 .containsValue(value)); 699 700 vals.clear(); 701 assertEquals("Did not remove all entries as expected", 0, map.size()); 702 } 703 704 /** 705 * java.util.IdentityHashMap#keySet() 706 * java.util.IdentityHashMap#remove(java.lang.Object) 707 */ 708 public void test_keySet_removeAll() { 709 IdentityHashMap map = new IdentityHashMap(); 710 for (int i = 0; i < 1000; i++) { 711 map.put(new Integer(i), new Integer(i)); 712 } 713 Set set = map.keySet(); 714 set.removeAll(set); 715 716 assertEquals("did not remove all elements in the map", 0, map.size()); 717 assertTrue("did not remove all elements in the keyset", set.isEmpty()); 718 719 Iterator it = set.iterator(); 720 assertTrue("keySet iterator still has elements", !it.hasNext()); 721 } 722 723 /** 724 * java.util.IdentityHashMap#keySet() 725 */ 726 public void test_keySet_retainAll() { 727 IdentityHashMap map = new IdentityHashMap(); 728 for (int i = 0; i < 1000; i++) { 729 map.put(new Integer(i), new Integer(i)); 730 } 731 Set set = map.keySet(); 732 733 // retain all the elements 734 boolean result = set.retainAll(set); 735 assertTrue("retain all should return false", !result); 736 assertEquals("did not retain all", 1000, set.size()); 737 738 // send empty set to retainAll 739 result = set.retainAll(new TreeSet()); 740 assertTrue("retain all should return true", result); 741 assertEquals("did not remove all elements in the map", 0, map.size()); 742 assertTrue("did not remove all elements in the keyset", set.isEmpty()); 743 744 Iterator it = set.iterator(); 745 assertTrue("keySet iterator still has elements", !it.hasNext()); 746 } 747 748 /** 749 * java.util.IdentityHashMap#keySet() 750 * java.util.IdentityHashMap#remove(java.lang.Object) 751 */ 752 public void test_keyset_remove() { 753 IdentityHashMap map = new IdentityHashMap(); 754 755 Integer key = new Integer(21); 756 757 map.put(new Integer(1), null); 758 map.put(new Integer(11), null); 759 map.put(key, null); 760 map.put(new Integer(31), null); 761 map.put(new Integer(41), null); 762 map.put(new Integer(51), null); 763 map.put(new Integer(61), null); 764 map.put(new Integer(71), null); 765 map.put(new Integer(81), null); 766 map.put(new Integer(91), null); 767 768 Set set = map.keySet(); 769 770 Set newset = new HashSet(); 771 Iterator it = set.iterator(); 772 while (it.hasNext()) { 773 Object element = it.next(); 774 if (element == key) { 775 it.remove(); 776 } else 777 newset.add(element); 778 } 779 int size = newset.size(); 780 assertTrue("keyset and newset don't have same size", 781 newset.size() == size); 782 assertTrue("element is in newset ", !newset.contains(key)); 783 assertTrue("element not removed from keyset", !set.contains(key)); 784 assertTrue("element not removed from map", !map.containsKey(key)); 785 786 assertTrue("newset and keyset do not have same elements 1", newset 787 .equals(set)); 788 assertTrue("newset and keyset do not have same elements 2", set 789 .equals(newset)); 790 } 791 792 public void test_clone_scenario1() { 793 IdentityHashMap hashMap = new IdentityHashMap(); 794 assertEquals(0, hashMap.hashCode()); 795 Object cloneHashMap = hashMap.clone(); 796 ((IdentityHashMap) cloneHashMap).put("key", "value"); 797 assertEquals(0, hashMap.hashCode()); 798 assertTrue(0 != cloneHashMap.hashCode()); 799 } 800 801 public void test_clone_scenario2() { 802 IdentityHashMap hashMap = new IdentityHashMap(); 803 assertEquals(0, hashMap.hashCode()); 804 Object cloneHashMap = hashMap.clone(); 805 hashMap.put("key", "value"); 806 assertEquals(1, hashMap.size()); 807 assertEquals(0, ((IdentityHashMap) cloneHashMap).size()); 808 assertEquals("value", hashMap.get("key")); 809 assertNull(((IdentityHashMap) cloneHashMap).get("key")); 810 assertTrue(0 != hashMap.hashCode()); 811 assertEquals(0, cloneHashMap.hashCode()); 812 } 813 814 public void test_clone_scenario3() { 815 IdentityHashMap hashMap = new IdentityHashMap(); 816 assertEquals(0, hashMap.hashCode()); 817 hashMap.put("key", "value"); 818 Object cloneHashMap = hashMap.clone(); 819 assertEquals(1, hashMap.size()); 820 assertEquals(1, ((IdentityHashMap) cloneHashMap).size()); 821 assertEquals("value", hashMap.get("key")); 822 assertEquals("value", ((IdentityHashMap) cloneHashMap).get("key")); 823 assertEquals(hashMap.hashCode(), cloneHashMap.hashCode()); 824 } 825 826 public void test_clone_scenario4() { 827 IdentityHashMap hashMap = new IdentityHashMap(); 828 Object cloneHashMap = hashMap.clone(); 829 assertNull(((IdentityHashMap) cloneHashMap).get((Object) null)); 830 hashMap.put((Object) null, cloneHashMap); 831 assertNull(((IdentityHashMap) cloneHashMap).get((Object) null)); 832 assertEquals(cloneHashMap, hashMap.get((Object) null)); 833 } 834 835 public void test_clone_scenario5() throws Exception { 836 IdentityHashMap hashMap = new IdentityHashMap(); 837 Object cloneHashMap = hashMap.clone(); 838 assertNull(hashMap.remove((Object) null)); 839 ((IdentityHashMap) cloneHashMap).put((Object) null, cloneHashMap); 840 assertNull(hashMap.remove((Object) null)); 841 assertEquals(cloneHashMap, ((IdentityHashMap) cloneHashMap) 842 .get((Object) null)); 843 } 844 845 /* 846 * Regression test for HARMONY-6419 847 */ 848 public void test_underlyingMap() { 849 IdentityHashMap<String, String> ihm = new IdentityHashMap<String, String>(); 850 String key = "key"; 851 String value = "value"; 852 ihm.put(key, value); 853 854 Set<Map.Entry<String, String>> set = ihm.entrySet(); 855 assertEquals(1, set.size()); 856 857 Map.Entry<String, String> entry = set.iterator().next(); 858 859 String newValue = "newvalue"; 860 entry.setValue(newValue); 861 assertSame(newValue, ihm.get(key)); 862 } 863 864 public void test_forEach() throws Exception { 865 IdentityHashMap<String, String> map = new IdentityHashMap<>(); 866 map.put("one", "1"); 867 map.put("two", "2"); 868 map.put("three", "3"); 869 870 IdentityHashMap<String, String> output = new IdentityHashMap<>(); 871 map.forEach((k, v) -> output.put(k,v)); 872 assertEquals(map, output); 873 874 HashSet<String> setOutput = new HashSet<>(); 875 map.keySet().forEach((k) -> setOutput.add(k)); 876 assertEquals(map.keySet(), setOutput); 877 878 setOutput.clear(); 879 map.values().forEach((v) -> setOutput.add(v)); 880 assertEquals(new HashSet<>(map.values()), setOutput); 881 882 HashSet<Map.Entry<String,String>> entrySetOutput = new HashSet<>(); 883 map.entrySet().forEach((v) -> entrySetOutput.add(v)); 884 assertEquals(map.entrySet(), entrySetOutput); 885 } 886 887 888 public void test_forEach_NPE() throws Exception { 889 IdentityHashMap<String, String> map = new IdentityHashMap<>(); 890 try { 891 map.forEach(null); 892 fail(); 893 } catch(NullPointerException expected) {} 894 895 try { 896 map.keySet().forEach(null); 897 fail(); 898 } catch(NullPointerException expected) {} 899 900 try { 901 map.values().forEach(null); 902 fail(); 903 } catch(NullPointerException expected) {} 904 905 try { 906 map.entrySet().forEach(null); 907 fail(); 908 } catch(NullPointerException expected) {} 909 } 910 911 public void test_forEach_CME() throws Exception { 912 IdentityHashMap<String, String> map = new IdentityHashMap<>(); 913 map.put("one", "1"); 914 map.put("two", "2"); 915 map.put("three", "3"); 916 917 IdentityHashMap<String, String> outputMap = new IdentityHashMap<>(); 918 try { 919 map.forEach(new java.util.function.BiConsumer<String, String>() { 920 @Override 921 public void accept(String k, String v) { 922 outputMap.put(k, v); 923 map.put("foo1", v); 924 } 925 }); 926 fail(); 927 } catch(ConcurrentModificationException expected) {} 928 // We should get a CME and DO NOT continue forEach evaluation 929 assertEquals(1, outputMap.size()); 930 931 outputMap.clear(); 932 try { 933 map.keySet().forEach(new java.util.function.Consumer<String>() { 934 @Override 935 public void accept(String k) { 936 outputMap.put(k, "foo"); 937 map.put("foo2", "boo"); 938 } 939 }); 940 fail(); 941 } catch(ConcurrentModificationException expected) {} 942 // We should get a CME and DO NOT continue forEach evaluation 943 assertEquals(1, outputMap.size()); 944 945 outputMap.clear(); 946 try { 947 map.values().forEach(new java.util.function.Consumer<String>() { 948 @Override 949 public void accept(String k) { 950 outputMap.put(k, "foo"); 951 map.put("foo3", "boo"); 952 } 953 }); 954 fail(); 955 } catch(ConcurrentModificationException expected) {} 956 // We should get a CME and DO NOT continue forEach evaluation 957 assertEquals(1, outputMap.size()); 958 959 outputMap.clear(); 960 try { 961 map.entrySet().forEach(new java.util.function.Consumer<Map.Entry<String,String>>() { 962 @Override 963 public void accept(Map.Entry<String,String> k) { 964 outputMap.put(k.getKey(), "foo"); 965 map.put("foo4", "boo"); 966 } 967 }); 968 fail(); 969 } catch(ConcurrentModificationException expected) {} 970 // We should get a CME and DO NOT continue forEach evaluation 971 assertEquals(1, outputMap.size()); 972 } 973 974 public void test_spliterator_keySet() { 975 IdentityHashMap<String, String> hashMap = new IdentityHashMap<>(); 976 hashMap.put("a", "1"); 977 hashMap.put("b", "2"); 978 hashMap.put("c", "3"); 979 hashMap.put("d", "4"); 980 hashMap.put("e", "5"); 981 hashMap.put("f", "6"); 982 hashMap.put("g", "7"); 983 hashMap.put("h", "8"); 984 hashMap.put("i", "9"); 985 hashMap.put("j", "10"); 986 hashMap.put("k", "11"); 987 hashMap.put("l", "12"); 988 hashMap.put("m", "13"); 989 hashMap.put("n", "14"); 990 hashMap.put("o", "15"); 991 hashMap.put("p", "16"); 992 993 Set<String> keys = hashMap.keySet(); 994 ArrayList<String> expectedKeys = new ArrayList<>(keys); 995 996 SpliteratorTester.runBasicIterationTests(keys.spliterator(), expectedKeys); 997 SpliteratorTester.runBasicSplitTests(keys, expectedKeys); 998 SpliteratorTester.testSpliteratorNPE(keys.spliterator()); 999 SpliteratorTester.assertSupportsTrySplit(keys); 1000 } 1001 1002 public void test_spliterator_valueSet() { 1003 IdentityHashMap<String, String> hashMap = new IdentityHashMap<>(); 1004 hashMap.put("a", "1"); 1005 hashMap.put("b", "2"); 1006 hashMap.put("c", "3"); 1007 hashMap.put("d", "4"); 1008 hashMap.put("e", "5"); 1009 hashMap.put("f", "6"); 1010 hashMap.put("g", "7"); 1011 hashMap.put("h", "8"); 1012 hashMap.put("i", "9"); 1013 hashMap.put("j", "10"); 1014 hashMap.put("k", "11"); 1015 hashMap.put("l", "12"); 1016 hashMap.put("m", "13"); 1017 hashMap.put("n", "14"); 1018 hashMap.put("o", "15"); 1019 hashMap.put("p", "16"); 1020 1021 Collection<String> values = hashMap.values(); 1022 ArrayList<String> expectedValues = new ArrayList<>(values); 1023 1024 SpliteratorTester.runBasicIterationTests(values.spliterator(), expectedValues); 1025 SpliteratorTester.runBasicSplitTests(values, expectedValues); 1026 SpliteratorTester.testSpliteratorNPE(values.spliterator()); 1027 SpliteratorTester.assertSupportsTrySplit(values); 1028 } 1029 1030 public void test_spliterator_entrySet() { 1031 IdentityHashMap<String, String> hashMap = new IdentityHashMap<>(); 1032 hashMap.put("a", "1"); 1033 hashMap.put("b", "2"); 1034 hashMap.put("c", "3"); 1035 hashMap.put("d", "4"); 1036 hashMap.put("e", "5"); 1037 hashMap.put("f", "6"); 1038 hashMap.put("g", "7"); 1039 hashMap.put("h", "8"); 1040 hashMap.put("i", "9"); 1041 hashMap.put("j", "10"); 1042 hashMap.put("k", "11"); 1043 hashMap.put("l", "12"); 1044 hashMap.put("m", "13"); 1045 hashMap.put("n", "14"); 1046 hashMap.put("o", "15"); 1047 hashMap.put("p", "16"); 1048 1049 Set<Map.Entry<String, String>> values = hashMap.entrySet(); 1050 ArrayList<Map.Entry<String, String>> expectedValues = new ArrayList<>(values); 1051 1052 Comparator<Map.Entry<String, String>> comparator = 1053 (a, b) -> (a.getKey().compareTo(b.getKey())); 1054 1055 SpliteratorTester.runBasicIterationTests(values.spliterator(), expectedValues); 1056 SpliteratorTester.runBasicSplitTests(values, expectedValues, comparator); 1057 SpliteratorTester.testSpliteratorNPE(values.spliterator()); 1058 SpliteratorTester.assertSupportsTrySplit(values); 1059 } 1060 1061 public void test_replaceAll() { 1062 IdentityHashMap<String, String> map = new IdentityHashMap<>(); 1063 String key1 = "key1"; 1064 String key2 = "key2"; 1065 String key3 = "key3"; 1066 1067 map.put(key1, "1"); 1068 map.put(key2, "2"); 1069 map.put(key3, "3"); 1070 1071 map.replaceAll((k, v) -> k + v); 1072 1073 assertEquals("key11", map.get(key1)); 1074 assertEquals("key22", map.get(key2)); 1075 assertEquals("key33", map.get(key3)); 1076 assertEquals(3, map.size()); 1077 1078 try { 1079 map.replaceAll(new BiFunction<String, String, String>() { 1080 @Override 1081 public String apply(String s, String s2) { 1082 map.put("key4", "4"); 1083 return ""; 1084 } 1085 }); 1086 fail(); 1087 } catch (ConcurrentModificationException expected) {} 1088 } 1089 1090 1091 // comparator for IdentityHashMap objects 1092 private static final SerializableAssert COMPARATOR = new SerializableAssert() { 1093 public void assertDeserialized(Serializable initial, 1094 Serializable deserialized) { 1095 1096 IdentityHashMap init = (IdentityHashMap) initial; 1097 IdentityHashMap desr = (IdentityHashMap) deserialized; 1098 1099 assertEquals("Size", init.size(), desr.size()); 1100 } 1101 }; 1102} 1103