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.
|
||||
*/
|
||||
private static final Object NULL = new Object();
|
||||
private static final Object NULL = new Integer(0);
|
||||
|
||||
private Object maskNull(Object 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);
|
||||
}
|
||||
|
||||
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.
|
||||
@ -464,6 +464,7 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
||||
public Iterator<Map.Entry<K,V>> iterator() {
|
||||
return new EntryIterator();
|
||||
}
|
||||
|
||||
public boolean contains(Object o) {
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
@ -552,70 +553,82 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Since we don't use Entry objects, we use the Iterator itself as entry.
|
||||
*/
|
||||
private class EntryIterator extends EnumMapIterator<Map.Entry<K,V>>
|
||||
implements Map.Entry<K,V>
|
||||
{
|
||||
private class EntryIterator extends EnumMapIterator<Map.Entry<K,V>> {
|
||||
private Entry lastReturnedEntry = null;
|
||||
|
||||
public Map.Entry<K,V> next() {
|
||||
if (!hasNext())
|
||||
throw new NoSuchElementException();
|
||||
lastReturnedIndex = index++;
|
||||
return this;
|
||||
lastReturnedEntry = new Entry(index++);
|
||||
return lastReturnedEntry;
|
||||
}
|
||||
|
||||
public K getKey() {
|
||||
checkLastReturnedIndexForEntryUse();
|
||||
return keyUniverse[lastReturnedIndex];
|
||||
public void remove() {
|
||||
lastReturnedIndex =
|
||||
((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
|
||||
super.remove();
|
||||
lastReturnedEntry.index = lastReturnedIndex;
|
||||
lastReturnedEntry = null;
|
||||
}
|
||||
|
||||
public V getValue() {
|
||||
checkLastReturnedIndexForEntryUse();
|
||||
return unmaskNull(vals[lastReturnedIndex]);
|
||||
}
|
||||
private class Entry implements Map.Entry<K,V> {
|
||||
private int index;
|
||||
|
||||
public V setValue(V value) {
|
||||
checkLastReturnedIndexForEntryUse();
|
||||
V oldValue = unmaskNull(vals[lastReturnedIndex]);
|
||||
vals[lastReturnedIndex] = maskNull(value);
|
||||
return oldValue;
|
||||
}
|
||||
private Entry(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (lastReturnedIndex < 0)
|
||||
return o == this;
|
||||
public K getKey() {
|
||||
checkIndexForEntryUse();
|
||||
return keyUniverse[index];
|
||||
}
|
||||
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry e = (Map.Entry)o;
|
||||
V ourValue = unmaskNull(vals[lastReturnedIndex]);
|
||||
Object hisValue = e.getValue();
|
||||
return e.getKey() == keyUniverse[lastReturnedIndex] &&
|
||||
(ourValue == hisValue ||
|
||||
(ourValue != null && ourValue.equals(hisValue)));
|
||||
}
|
||||
public V getValue() {
|
||||
checkIndexForEntryUse();
|
||||
return unmaskNull(vals[index]);
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (lastReturnedIndex < 0)
|
||||
return super.hashCode();
|
||||
public V setValue(V value) {
|
||||
checkIndexForEntryUse();
|
||||
V oldValue = unmaskNull(vals[index]);
|
||||
vals[index] = maskNull(value);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
Object value = vals[lastReturnedIndex];
|
||||
return keyUniverse[lastReturnedIndex].hashCode()
|
||||
^ (value == NULL ? 0 : value.hashCode());
|
||||
}
|
||||
public boolean equals(Object o) {
|
||||
if (index < 0)
|
||||
return o == this;
|
||||
|
||||
public String toString() {
|
||||
if (lastReturnedIndex < 0)
|
||||
return super.toString();
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
|
||||
return keyUniverse[lastReturnedIndex] + "="
|
||||
+ unmaskNull(vals[lastReturnedIndex]);
|
||||
}
|
||||
Map.Entry e = (Map.Entry)o;
|
||||
V ourValue = unmaskNull(vals[index]);
|
||||
Object hisValue = e.getValue();
|
||||
return (e.getKey() == keyUniverse[index] &&
|
||||
(ourValue == hisValue ||
|
||||
(ourValue != null && ourValue.equals(hisValue))));
|
||||
}
|
||||
|
||||
private void checkLastReturnedIndexForEntryUse() {
|
||||
if (lastReturnedIndex < 0)
|
||||
throw new IllegalStateException("Entry was removed");
|
||||
public int hashCode() {
|
||||
if (index < 0)
|
||||
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
|
||||
*/
|
||||
public boolean equals(Object o) {
|
||||
if (!(o instanceof EnumMap))
|
||||
return super.equals(o);
|
||||
if (this == 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)
|
||||
return size == 0 && em.size == 0;
|
||||
|
||||
@ -649,6 +687,26 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
||||
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
|
||||
* are not cloned.
|
||||
@ -705,9 +763,13 @@ public class EnumMap<K extends Enum<K>, V> extends AbstractMap<K, V>
|
||||
s.writeInt(size);
|
||||
|
||||
// Write out keys and values (alternating)
|
||||
for (Map.Entry<K,V> e : entrySet()) {
|
||||
s.writeObject(e.getKey());
|
||||
s.writeObject(e.getValue());
|
||||
int entriesToBeWritten = size;
|
||||
for (int i = 0; entriesToBeWritten > 0; i++) {
|
||||
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.
|
||||
*
|
||||
* 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
|
||||
extends IdentityHashMapIterator<Map.Entry<K,V>>
|
||||
implements Map.Entry<K,V>
|
||||
{
|
||||
private Entry lastReturnedEntry = null;
|
||||
|
||||
public Map.Entry<K,V> next() {
|
||||
nextIndex();
|
||||
return this;
|
||||
lastReturnedEntry = new Entry(nextIndex());
|
||||
return lastReturnedEntry;
|
||||
}
|
||||
|
||||
public K getKey() {
|
||||
// Provide a better exception than out of bounds index
|
||||
if (lastReturnedIndex < 0)
|
||||
throw new IllegalStateException("Entry was removed");
|
||||
|
||||
return (K) unmaskNull(traversalTable[lastReturnedIndex]);
|
||||
public void remove() {
|
||||
lastReturnedIndex =
|
||||
((null == lastReturnedEntry) ? -1 : lastReturnedEntry.index);
|
||||
super.remove();
|
||||
lastReturnedEntry.index = lastReturnedIndex;
|
||||
lastReturnedEntry = null;
|
||||
}
|
||||
|
||||
public V getValue() {
|
||||
// Provide a better exception than out of bounds index
|
||||
if (lastReturnedIndex < 0)
|
||||
throw new IllegalStateException("Entry was removed");
|
||||
private class Entry implements Map.Entry<K,V> {
|
||||
private int index;
|
||||
|
||||
return (V) traversalTable[lastReturnedIndex+1];
|
||||
}
|
||||
private Entry(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public V setValue(V value) {
|
||||
// It would be mean-spirited to proceed here if remove() called
|
||||
if (lastReturnedIndex < 0)
|
||||
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 K getKey() {
|
||||
checkIndexForEntryUse();
|
||||
return (K) unmaskNull(traversalTable[index]);
|
||||
}
|
||||
|
||||
public boolean equals(Object o) {
|
||||
if (lastReturnedIndex < 0)
|
||||
return super.equals(o);
|
||||
public V getValue() {
|
||||
checkIndexForEntryUse();
|
||||
return (V) traversalTable[index+1];
|
||||
}
|
||||
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry e = (Map.Entry)o;
|
||||
return e.getKey() == getKey() &&
|
||||
e.getValue() == getValue();
|
||||
}
|
||||
public V setValue(V value) {
|
||||
checkIndexForEntryUse();
|
||||
V oldValue = (V) traversalTable[index+1];
|
||||
traversalTable[index+1] = value;
|
||||
// if shadowing, force into main table
|
||||
if (traversalTable != IdentityHashMap.this.table)
|
||||
put((K) traversalTable[index], value);
|
||||
return oldValue;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
if (lastReturnedIndex < 0)
|
||||
return super.hashCode();
|
||||
public boolean equals(Object o) {
|
||||
if (index < 0)
|
||||
return super.equals(o);
|
||||
|
||||
return System.identityHashCode(getKey()) ^
|
||||
System.identityHashCode(getValue());
|
||||
}
|
||||
if (!(o instanceof Map.Entry))
|
||||
return false;
|
||||
Map.Entry e = (Map.Entry)o;
|
||||
return (e.getKey() == unmaskNull(traversalTable[index]) &&
|
||||
e.getValue() == traversalTable[index+1]);
|
||||
}
|
||||
|
||||
public String toString() {
|
||||
if (lastReturnedIndex < 0)
|
||||
return super.toString();
|
||||
public int hashCode() {
|
||||
if (lastReturnedIndex < 0)
|
||||
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
|
||||
loader.waitForNotify(1); //wait for thread1 to do getBundle & block in loader
|
||||
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
|
||||
//Thread2 should have completed its getBundle call and terminated
|
||||
@ -292,7 +292,6 @@ public class Bug4168625Test extends RBTestFmwk {
|
||||
|
||||
thread1.ping(); //continue thread1
|
||||
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
|
||||
causeResourceBundleCacheFlush(); //cause a cache flush
|
||||
thread1.ping(); //kick thread 1
|
||||
thread1.ping(); //kick thread 1
|
||||
thread1.join(1000); //wait until thread2 blocks somewhere in getBundle
|
||||
thread1.join(); //wait until thread1 terminates
|
||||
|
||||
ResourceBundle bundle = (ResourceBundle)thread1.bundle;
|
||||
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