Merge
This commit is contained in:
commit
ddc9107b92
@ -106,7 +106,7 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
|||||||
/**
|
/**
|
||||||
* Distinguished non-null value for representing null values.
|
* Distinguished non-null value for representing null values.
|
||||||
*/
|
*/
|
||||||
private static final Object NULL = new Object();
|
private static final Object NULL = new Integer(0);
|
||||||
|
|
||||||
private Object maskNull(Object value) {
|
private Object maskNull(Object value) {
|
||||||
return (value == null ? NULL : value);
|
return (value == null ? NULL : value);
|
||||||
@ -116,7 +116,7 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
|||||||
return (V) (value == NULL ? null : value);
|
return (V) (value == NULL ? null : value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0];
|
private static final Enum[] ZERO_LENGTH_ENUM_ARRAY = new Enum[0];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Creates an empty enum map with the specified key type.
|
* Creates an empty enum map with the specified key type.
|
||||||
@ -464,6 +464,7 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
|||||||
public Iterator<Map.Entry<K,V>> iterator() {
|
public Iterator<Map.Entry<K,V>> iterator() {
|
||||||
return new EntryIterator();
|
return new EntryIterator();
|
||||||
}
|
}
|
||||||
|
|
||||||
public boolean contains(Object o) {
|
public boolean contains(Object o) {
|
||||||
if (!(o instanceof Map.Entry))
|
if (!(o instanceof Map.Entry))
|
||||||
return false;
|
return false;
|
||||||
@ -552,70 +553,82 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
private class EntryIterator extends EnumMapIterator<Map.Entry<K,V>> {
|
||||||
* Since we don't use Entry objects, we use the Iterator itself as entry.
|
private Entry lastReturnedEntry = null;
|
||||||
*/
|
|
||||||
private class EntryIterator extends EnumMapIterator<Map.Entry<K,V>>
|
|
||||||
implements Map.Entry<K,V>
|
|
||||||
{
|
|
||||||
public Map.Entry<K,V> next() {
|
public Map.Entry<K,V> next() {
|
||||||
if (!hasNext())
|
if (!hasNext())
|
||||||
throw new NoSuchElementException();
|
throw new NoSuchElementException();
|
||||||
lastReturnedIndex = index++;
|
lastReturnedEntry = new Entry(index++);
|
||||||
return this;
|
return lastReturnedEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public K getKey() {
|
public void remove() {
|
||||||
checkLastReturnedIndexForEntryUse();
|
lastReturnedIndex =
|
||||||
return keyUniverse[lastReturnedIndex];
|
((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
|
||||||
|
super.remove();
|
||||||
|
lastReturnedEntry.index = lastReturnedIndex;
|
||||||
|
lastReturnedEntry = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public V getValue() {
|
private class Entry implements Map.Entry<K,V> {
|
||||||
checkLastReturnedIndexForEntryUse();
|
private int index;
|
||||||
return unmaskNull(vals[lastReturnedIndex]);
|
|
||||||
}
|
|
||||||
|
|
||||||
public V setValue(V value) {
|
private Entry(int index) {
|
||||||
checkLastReturnedIndexForEntryUse();
|
this.index = index;
|
||||||
V oldValue = unmaskNull(vals[lastReturnedIndex]);
|
}
|
||||||
vals[lastReturnedIndex] = maskNull(value);
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
public K getKey() {
|
||||||
if (lastReturnedIndex < 0)
|
checkIndexForEntryUse();
|
||||||
return o == this;
|
return keyUniverse[index];
|
||||||
|
}
|
||||||
|
|
||||||
if (!(o instanceof Map.Entry))
|
public V getValue() {
|
||||||
return false;
|
checkIndexForEntryUse();
|
||||||
Map.Entry e = (Map.Entry)o;
|
return unmaskNull(vals[index]);
|
||||||
V ourValue = unmaskNull(vals[lastReturnedIndex]);
|
}
|
||||||
Object hisValue = e.getValue();
|
|
||||||
return e.getKey() == keyUniverse[lastReturnedIndex] &&
|
|
||||||
(ourValue == hisValue ||
|
|
||||||
(ourValue != null && ourValue.equals(hisValue)));
|
|
||||||
}
|
|
||||||
|
|
||||||
public int hashCode() {
|
public V setValue(V value) {
|
||||||
if (lastReturnedIndex < 0)
|
checkIndexForEntryUse();
|
||||||
return super.hashCode();
|
V oldValue = unmaskNull(vals[index]);
|
||||||
|
vals[index] = maskNull(value);
|
||||||
|
return oldValue;
|
||||||
|
}
|
||||||
|
|
||||||
Object value = vals[lastReturnedIndex];
|
public boolean equals(Object o) {
|
||||||
return keyUniverse[lastReturnedIndex].hashCode()
|
if (index < 0)
|
||||||
^ (value == NULL ? 0 : value.hashCode());
|
return o == this;
|
||||||
}
|
|
||||||
|
|
||||||
public String toString() {
|
if (!(o instanceof Map.Entry))
|
||||||
if (lastReturnedIndex < 0)
|
return false;
|
||||||
return super.toString();
|
|
||||||
|
|
||||||
return keyUniverse[lastReturnedIndex] + "="
|
Map.Entry e = (Map.Entry)o;
|
||||||
+ unmaskNull(vals[lastReturnedIndex]);
|
V ourValue = unmaskNull(vals[index]);
|
||||||
}
|
Object hisValue = e.getValue();
|
||||||
|
return (e.getKey() == keyUniverse[index] &&
|
||||||
|
(ourValue == hisValue ||
|
||||||
|
(ourValue != null && ourValue.equals(hisValue))));
|
||||||
|
}
|
||||||
|
|
||||||
private void checkLastReturnedIndexForEntryUse() {
|
public int hashCode() {
|
||||||
if (lastReturnedIndex < 0)
|
if (index < 0)
|
||||||
throw new IllegalStateException("Entry was removed");
|
return super.hashCode();
|
||||||
|
|
||||||
|
return entryHashCode(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
if (index < 0)
|
||||||
|
return super.toString();
|
||||||
|
|
||||||
|
return keyUniverse[index] + "="
|
||||||
|
+ unmaskNull(vals[index]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkIndexForEntryUse() {
|
||||||
|
if (index < 0)
|
||||||
|
throw new IllegalStateException("Entry was removed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -631,10 +644,35 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
|||||||
* @return <tt>true</tt> if the specified object is equal to this map
|
* @return <tt>true</tt> if the specified object is equal to this map
|
||||||
*/
|
*/
|
||||||
public boolean equals(Object o) {
|
public boolean equals(Object o) {
|
||||||
if (!(o instanceof EnumMap))
|
if (this == o)
|
||||||
return super.equals(o);
|
return true;
|
||||||
|
if (o instanceof EnumMap)
|
||||||
|
return equals((EnumMap)o);
|
||||||
|
if (!(o instanceof Map))
|
||||||
|
return false;
|
||||||
|
|
||||||
EnumMap em = (EnumMap)o;
|
Map<K,V> m = (Map<K,V>)o;
|
||||||
|
if (size != m.size())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
for (int i = 0; i < keyUniverse.length; i++) {
|
||||||
|
if (null != vals[i]) {
|
||||||
|
K key = keyUniverse[i];
|
||||||
|
V value = unmaskNull(vals[i]);
|
||||||
|
if (null == value) {
|
||||||
|
if (!((null == m.get(key)) && m.containsKey(key)))
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
|
if (!value.equals(m.get(key)))
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
private boolean equals(EnumMap em) {
|
||||||
if (em.keyType != keyType)
|
if (em.keyType != keyType)
|
||||||
return size == 0 && em.size == 0;
|
return size == 0 && em.size == 0;
|
||||||
|
|
||||||
@ -649,6 +687,26 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the hash code value for this map. The hash code of a map is
|
||||||
|
* defined to be the sum of the hash codes of each entry in the map.
|
||||||
|
*/
|
||||||
|
public int hashCode() {
|
||||||
|
int h = 0;
|
||||||
|
|
||||||
|
for (int i = 0; i < keyUniverse.length; i++) {
|
||||||
|
if (null != vals[i]) {
|
||||||
|
h += entryHashCode(i);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return h;
|
||||||
|
}
|
||||||
|
|
||||||
|
private int entryHashCode(int index) {
|
||||||
|
return (keyUniverse[index].hashCode() ^ vals[index].hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a shallow copy of this enum map. (The values themselves
|
* Returns a shallow copy of this enum map. (The values themselves
|
||||||
* are not cloned.
|
* are not cloned.
|
||||||
@ -705,9 +763,13 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
|||||||
s.writeInt(size);
|
s.writeInt(size);
|
||||||
|
|
||||||
// Write out keys and values (alternating)
|
// Write out keys and values (alternating)
|
||||||
for (Map.Entry<K,V> e : entrySet()) {
|
int entriesToBeWritten = size;
|
||||||
s.writeObject(e.getKey());
|
for (int i = 0; entriesToBeWritten > 0; i++) {
|
||||||
s.writeObject(e.getValue());
|
if (null != vals[i]) {
|
||||||
|
s.writeObject(keyUniverse[i]);
|
||||||
|
s.writeObject(unmaskNull(vals[i]));
|
||||||
|
entriesToBeWritten--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
/*
|
/*
|
||||||
* Copyright (c) 2000, 2008, Oracle and/or its affiliates. All rights reserved.
|
* Copyright (c) 2000, 2011, Oracle and/or its affiliates. All rights reserved.
|
||||||
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
*
|
*
|
||||||
* This code is free software; you can redistribute it and/or modify it
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
@ -829,71 +829,82 @@ public class IdentityHashMap<K,V>
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Since we don't use Entry objects, we use the Iterator
|
|
||||||
* itself as an entry.
|
|
||||||
*/
|
|
||||||
private class EntryIterator
|
private class EntryIterator
|
||||||
extends IdentityHashMapIterator<Map.Entry<K,V>>
|
extends IdentityHashMapIterator<Map.Entry<K,V>>
|
||||||
implements Map.Entry<K,V>
|
|
||||||
{
|
{
|
||||||
|
private Entry lastReturnedEntry = null;
|
||||||
|
|
||||||
public Map.Entry<K,V> next() {
|
public Map.Entry<K,V> next() {
|
||||||
nextIndex();
|
lastReturnedEntry = new Entry(nextIndex());
|
||||||
return this;
|
return lastReturnedEntry;
|
||||||
}
|
}
|
||||||
|
|
||||||
public K getKey() {
|
public void remove() {
|
||||||
// Provide a better exception than out of bounds index
|
lastReturnedIndex =
|
||||||
if (lastReturnedIndex < 0)
|
((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
|
||||||
throw new IllegalStateException("Entry was removed");
|
super.remove();
|
||||||
|
lastReturnedEntry.index = lastReturnedIndex;
|
||||||
return (K) unmaskNull(traversalTable[lastReturnedIndex]);
|
lastReturnedEntry = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public V getValue() {
|
private class Entry implements Map.Entry<K,V> {
|
||||||
// Provide a better exception than out of bounds index
|
private int index;
|
||||||
if (lastReturnedIndex < 0)
|
|
||||||
throw new IllegalStateException("Entry was removed");
|
|
||||||
|
|
||||||
return (V) traversalTable[lastReturnedIndex+1];
|
private Entry(int index) {
|
||||||
}
|
this.index = index;
|
||||||
|
}
|
||||||
|
|
||||||
public V setValue(V value) {
|
public K getKey() {
|
||||||
// It would be mean-spirited to proceed here if remove() called
|
checkIndexForEntryUse();
|
||||||
if (lastReturnedIndex < 0)
|
return (K) unmaskNull(traversalTable[index]);
|
||||||
throw new IllegalStateException("Entry was removed");
|
}
|
||||||
V oldValue = (V) traversalTable[lastReturnedIndex+1];
|
|
||||||
traversalTable[lastReturnedIndex+1] = value;
|
|
||||||
// if shadowing, force into main table
|
|
||||||
if (traversalTable != IdentityHashMap.this.table)
|
|
||||||
put((K) traversalTable[lastReturnedIndex], value);
|
|
||||||
return oldValue;
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean equals(Object o) {
|
public V getValue() {
|
||||||
if (lastReturnedIndex < 0)
|
checkIndexForEntryUse();
|
||||||
return super.equals(o);
|
return (V) traversalTable[index+1];
|
||||||
|
}
|
||||||
|
|
||||||
if (!(o instanceof Map.Entry))
|
public V setValue(V value) {
|
||||||
return false;
|
checkIndexForEntryUse();
|
||||||
Map.Entry e = (Map.Entry)o;
|
V oldValue = (V) traversalTable[index+1];
|
||||||
return e.getKey() == getKey() &&
|
traversalTable[index+1] = value;
|
||||||
e.getValue() == getValue();
|
// if shadowing, force into main table
|
||||||
}
|
if (traversalTable != IdentityHashMap.this.table)
|
||||||
|
put((K) traversalTable[index], value);
|
||||||
|
return oldValue;
|
||||||
|
}
|
||||||
|
|
||||||
public int hashCode() {
|
public boolean equals(Object o) {
|
||||||
if (lastReturnedIndex < 0)
|
if (index < 0)
|
||||||
return super.hashCode();
|
return super.equals(o);
|
||||||
|
|
||||||
return System.identityHashCode(getKey()) ^
|
if (!(o instanceof Map.Entry))
|
||||||
System.identityHashCode(getValue());
|
return false;
|
||||||
}
|
Map.Entry e = (Map.Entry)o;
|
||||||
|
return (e.getKey() == unmaskNull(traversalTable[index]) &&
|
||||||
|
e.getValue() == traversalTable[index+1]);
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public int hashCode() {
|
||||||
if (lastReturnedIndex < 0)
|
if (lastReturnedIndex < 0)
|
||||||
return super.toString();
|
return super.hashCode();
|
||||||
|
|
||||||
return getKey() + "=" + getValue();
|
return (System.identityHashCode(unmaskNull(traversalTable[index])) ^
|
||||||
|
System.identityHashCode(traversalTable[index+1]));
|
||||||
|
}
|
||||||
|
|
||||||
|
public String toString() {
|
||||||
|
if (index < 0)
|
||||||
|
return super.toString();
|
||||||
|
|
||||||
|
return (unmaskNull(traversalTable[index]) + "="
|
||||||
|
+ traversalTable[index+1]);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkIndexForEntryUse() {
|
||||||
|
if (index < 0)
|
||||||
|
throw new IllegalStateException("Entry was removed");
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
60
jdk/test/java/util/EnumMap/DistinctEntrySetElements.java
Normal file
60
jdk/test/java/util/EnumMap/DistinctEntrySetElements.java
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Portions Copyright (c) 2011 IBM Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6312706
|
||||||
|
* @summary Sets from Map.entrySet() return distinct objects for each Entry
|
||||||
|
* @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class DistinctEntrySetElements {
|
||||||
|
static enum TestEnum { e00, e01, e02 }
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
final EnumMap<TestEnum, String> enumMap = new EnumMap<>(TestEnum.class);
|
||||||
|
|
||||||
|
for (TestEnum e : TestEnum.values()) {
|
||||||
|
enumMap.put(e, e.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
Set<Map.Entry<TestEnum, String>> entrySet = enumMap.entrySet();
|
||||||
|
HashSet<Map.Entry<TestEnum, String>> hashSet = new HashSet<>(entrySet);
|
||||||
|
|
||||||
|
if (false == hashSet.equals(entrySet)) {
|
||||||
|
throw new RuntimeException("Test FAILED: Sets are not equal.");
|
||||||
|
}
|
||||||
|
if (hashSet.hashCode() != entrySet.hashCode()) {
|
||||||
|
throw new RuntimeException("Test FAILED: Set's hashcodes are not equal.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,60 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Portions Copyright (c) 2011 IBM Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6312706
|
||||||
|
* @summary Iterator.remove() from Map.entrySet().iterator() invalidates returned Entry.
|
||||||
|
* @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.EnumMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class EntrySetIteratorRemoveInvalidatesEntry {
|
||||||
|
static enum TestEnum { e00, e01, e02 }
|
||||||
|
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
final EnumMap<TestEnum, String> enumMap = new EnumMap<>(TestEnum.class);
|
||||||
|
|
||||||
|
for (TestEnum e : TestEnum.values()) {
|
||||||
|
enumMap.put(e, e.name());
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator<Map.Entry<TestEnum, String>> entrySetIterator =
|
||||||
|
enumMap.entrySet().iterator();
|
||||||
|
Map.Entry<TestEnum, String> entry = entrySetIterator.next();
|
||||||
|
|
||||||
|
entrySetIterator.remove();
|
||||||
|
|
||||||
|
try {
|
||||||
|
entry.getKey();
|
||||||
|
throw new RuntimeException("Test FAILED: Entry not invalidated by removal.");
|
||||||
|
} catch (Exception e) { }
|
||||||
|
}
|
||||||
|
}
|
89
jdk/test/java/util/EnumMap/SimpleSerialization.java
Normal file
89
jdk/test/java/util/EnumMap/SimpleSerialization.java
Normal file
@ -0,0 +1,89 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Portions Copyright (c) 2011 IBM Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6312706
|
||||||
|
* @summary A serialized EnumMap can be successfully de-serialized.
|
||||||
|
* @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.io.ByteArrayInputStream;
|
||||||
|
import java.io.ByteArrayOutputStream;
|
||||||
|
import java.io.IOException;
|
||||||
|
import java.io.ObjectInputStream;
|
||||||
|
import java.io.ObjectOutputStream;
|
||||||
|
import java.io.PrintWriter;
|
||||||
|
import java.io.StringWriter;
|
||||||
|
import java.util.EnumMap;
|
||||||
|
|
||||||
|
public class SimpleSerialization {
|
||||||
|
private enum TestEnum { e00, e01, e02, e03, e04, e05, e06, e07 }
|
||||||
|
public static void main(final String[] args) throws Exception {
|
||||||
|
final EnumMap<TestEnum, String> enumMap = new EnumMap<>(TestEnum.class);
|
||||||
|
|
||||||
|
enumMap.put(TestEnum.e01, TestEnum.e01.name());
|
||||||
|
enumMap.put(TestEnum.e04, TestEnum.e04.name());
|
||||||
|
enumMap.put(TestEnum.e05, TestEnum.e05.name());
|
||||||
|
|
||||||
|
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||||
|
final ObjectOutputStream oos = new ObjectOutputStream(baos);
|
||||||
|
|
||||||
|
oos.writeObject(enumMap);
|
||||||
|
oos.close();
|
||||||
|
|
||||||
|
final byte[] data = baos.toByteArray();
|
||||||
|
final ByteArrayInputStream bais = new ByteArrayInputStream(data);
|
||||||
|
final ObjectInputStream ois = new ObjectInputStream(bais);
|
||||||
|
|
||||||
|
final Object deserializedObject = ois.readObject();
|
||||||
|
ois.close();
|
||||||
|
|
||||||
|
if (false == enumMap.equals(deserializedObject)) {
|
||||||
|
throw new RuntimeException(getFailureText(enumMap, deserializedObject));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static String getFailureText(final Object orig, final Object copy) {
|
||||||
|
final StringWriter sw = new StringWriter();
|
||||||
|
final PrintWriter pw = new PrintWriter(sw);
|
||||||
|
|
||||||
|
pw.println("Test FAILED: Deserialized object is not equal to the original object");
|
||||||
|
pw.print("\tOriginal: ");
|
||||||
|
printObject(pw, orig).println();
|
||||||
|
pw.print("\tCopy: ");
|
||||||
|
printObject(pw, copy).println();
|
||||||
|
|
||||||
|
pw.close();
|
||||||
|
return sw.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static PrintWriter printObject(final PrintWriter pw, final Object o) {
|
||||||
|
pw.printf("%s@%08x", o.getClass().getName(), System.identityHashCode(o));
|
||||||
|
return pw;
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,61 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Portions Copyright (c) 2011 IBM Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6312706
|
||||||
|
* @summary Sets from Map.entrySet() return distinct objects for each Entry
|
||||||
|
* @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class DistinctEntrySetElements {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
final IdentityHashMap<String, String> identityHashMap =
|
||||||
|
new IdentityHashMap<>();
|
||||||
|
|
||||||
|
identityHashMap.put("One", "Un");
|
||||||
|
identityHashMap.put("Two", "Deux");
|
||||||
|
identityHashMap.put("Three", "Trois");
|
||||||
|
|
||||||
|
Set<Map.Entry<String, String>> entrySet = identityHashMap.entrySet();
|
||||||
|
HashSet<Map.Entry<String, String>> hashSet = new HashSet<>(entrySet);
|
||||||
|
|
||||||
|
// NB: These comparisons are valid in this case because none of the
|
||||||
|
// keys put into 'identityHashMap' above are equal to any other.
|
||||||
|
if (false == hashSet.equals(entrySet)) {
|
||||||
|
throw new RuntimeException("Test FAILED: Sets are not equal.");
|
||||||
|
}
|
||||||
|
if (hashSet.hashCode() != entrySet.hashCode()) {
|
||||||
|
throw new RuntimeException("Test FAILED: Set's hashcodes are not equal.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Portions Copyright (c) 2011 IBM Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6312706
|
||||||
|
* @summary Iterator.remove() from Map.entrySet().iterator() invalidates returned Entry.
|
||||||
|
* @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
|
||||||
|
public class EntrySetIteratorRemoveInvalidatesEntry {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
final IdentityHashMap<String, String> identityHashMap =
|
||||||
|
new IdentityHashMap<>();
|
||||||
|
|
||||||
|
identityHashMap.put("One", "Un");
|
||||||
|
identityHashMap.put("Two", "Deux");
|
||||||
|
identityHashMap.put("Three", "Trois");
|
||||||
|
|
||||||
|
Iterator<Map.Entry<String, String>> entrySetIterator =
|
||||||
|
identityHashMap.entrySet().iterator();
|
||||||
|
Map.Entry<String, String> entry = entrySetIterator.next();
|
||||||
|
|
||||||
|
entrySetIterator.remove();
|
||||||
|
|
||||||
|
try {
|
||||||
|
entry.getKey();
|
||||||
|
throw new RuntimeException("Test FAILED: Entry not invalidated by removal.");
|
||||||
|
} catch (Exception e) { }
|
||||||
|
}
|
||||||
|
}
|
@ -282,7 +282,7 @@ public class Bug4168625Test extends RBTestFmwk {
|
|||||||
thread1.start(); //start thread 1
|
thread1.start(); //start thread 1
|
||||||
loader.waitForNotify(1); //wait for thread1 to do getBundle & block in loader
|
loader.waitForNotify(1); //wait for thread1 to do getBundle & block in loader
|
||||||
thread2.start(); //start second thread
|
thread2.start(); //start second thread
|
||||||
thread2.join(1000); //wait until thread2 blocks somewhere in getBundle
|
thread2.join(); //wait until thread2 terminates.
|
||||||
|
|
||||||
//Thread1 should be blocked inside getBundle at the class loader
|
//Thread1 should be blocked inside getBundle at the class loader
|
||||||
//Thread2 should have completed its getBundle call and terminated
|
//Thread2 should have completed its getBundle call and terminated
|
||||||
@ -292,7 +292,6 @@ public class Bug4168625Test extends RBTestFmwk {
|
|||||||
|
|
||||||
thread1.ping(); //continue thread1
|
thread1.ping(); //continue thread1
|
||||||
thread1.join();
|
thread1.join();
|
||||||
thread2.join();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -318,8 +317,7 @@ public class Bug4168625Test extends RBTestFmwk {
|
|||||||
loader.waitForNotify(3); //wait for thread1 to do getBundle(en) & block in loader
|
loader.waitForNotify(3); //wait for thread1 to do getBundle(en) & block in loader
|
||||||
causeResourceBundleCacheFlush(); //cause a cache flush
|
causeResourceBundleCacheFlush(); //cause a cache flush
|
||||||
thread1.ping(); //kick thread 1
|
thread1.ping(); //kick thread 1
|
||||||
thread1.ping(); //kick thread 1
|
thread1.join(); //wait until thread1 terminates
|
||||||
thread1.join(1000); //wait until thread2 blocks somewhere in getBundle
|
|
||||||
|
|
||||||
ResourceBundle bundle = (ResourceBundle)thread1.bundle;
|
ResourceBundle bundle = (ResourceBundle)thread1.bundle;
|
||||||
String s1 = bundle.getString("Bug4168625Resource3_en_US");
|
String s1 = bundle.getString("Bug4168625Resource3_en_US");
|
||||||
|
@ -0,0 +1,59 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2011 Oracle and/or its affiliates. All rights reserved.
|
||||||
|
* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
|
||||||
|
*
|
||||||
|
* This code is free software; you can redistribute it and/or modify it
|
||||||
|
* under the terms of the GNU General Public License version 2 only, as
|
||||||
|
* published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This code is distributed in the hope that it will be useful, but WITHOUT
|
||||||
|
* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
||||||
|
* version 2 for more details (a copy is included in the LICENSE file that
|
||||||
|
* accompanied this code).
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License version
|
||||||
|
* 2 along with this work; if not, write to the Free Software Foundation,
|
||||||
|
* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
*
|
||||||
|
* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
|
||||||
|
* or visit www.oracle.com if you need additional information or have any
|
||||||
|
* questions.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Portions Copyright (c) 2011 IBM Corporation
|
||||||
|
*/
|
||||||
|
|
||||||
|
/*
|
||||||
|
* @test
|
||||||
|
* @bug 6312706
|
||||||
|
* @summary Sets from Map.entrySet() return distinct objects for each Entry
|
||||||
|
* @author Neil Richards <neil.richards@ngmr.net>, <neil_richards@uk.ibm.com>
|
||||||
|
*/
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
public class DistinctEntrySetElements {
|
||||||
|
public static void main(String[] args) throws Exception {
|
||||||
|
final ConcurrentHashMap<String, String> concurrentHashMap =
|
||||||
|
new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
concurrentHashMap.put("One", "Un");
|
||||||
|
concurrentHashMap.put("Two", "Deux");
|
||||||
|
concurrentHashMap.put("Three", "Trois");
|
||||||
|
|
||||||
|
Set<Map.Entry<String, String>> entrySet = concurrentHashMap.entrySet();
|
||||||
|
HashSet<Map.Entry<String, String>> hashSet = new HashSet<>(entrySet);
|
||||||
|
|
||||||
|
if (false == hashSet.equals(entrySet)) {
|
||||||
|
throw new RuntimeException("Test FAILED: Sets are not equal.");
|
||||||
|
}
|
||||||
|
if (hashSet.hashCode() != entrySet.hashCode()) {
|
||||||
|
throw new RuntimeException("Test FAILED: Set's hashcodes are not equal.");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user