mirror of
https://github.com/corda/corda.git
synced 2025-01-01 10:46:46 +00:00
sketch of serialization/deserialization code (broken)
This commit is contained in:
parent
d3931b4853
commit
92ba1880d8
@ -2,9 +2,11 @@ package java.io;
|
|||||||
|
|
||||||
public class ObjectInputStream extends InputStream {
|
public class ObjectInputStream extends InputStream {
|
||||||
private final InputStream in;
|
private final InputStream in;
|
||||||
|
private final Reader r;
|
||||||
|
|
||||||
public ObjectInputStream(InputStream in) {
|
public ObjectInputStream(InputStream in) {
|
||||||
this.in = in;
|
this.in = in;
|
||||||
|
this.r = new PushbackReader(new InputStreamReader(in));
|
||||||
}
|
}
|
||||||
|
|
||||||
public int read() throws IOException {
|
public int read() throws IOException {
|
||||||
@ -18,4 +20,257 @@ public class ObjectInputStream extends InputStream {
|
|||||||
public void close() throws IOException {
|
public void close() throws IOException {
|
||||||
in.close();
|
in.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Object readObject() throws IOException {
|
||||||
|
return readObject(new HashMap());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean readBoolean() throws IOException {
|
||||||
|
read('z');
|
||||||
|
return readLongToken() != 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
public byte readByte() throws IOException {
|
||||||
|
read('b');
|
||||||
|
return (byte) readLongToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public char readChar() throws IOException {
|
||||||
|
read('c');
|
||||||
|
return (char) readLongToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public short readShort() throws IOException {
|
||||||
|
read('s');
|
||||||
|
return (short) readLongToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int readInt() throws IOException {
|
||||||
|
read('i');
|
||||||
|
return (int) readLongToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public long readLong() throws IOException {
|
||||||
|
read('j');
|
||||||
|
return readLongToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public float readFloat() throws IOException {
|
||||||
|
read('f');
|
||||||
|
return (float) readDoubleToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
public double readDouble() throws IOException {
|
||||||
|
read('d');
|
||||||
|
return readDoubleToken();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void skipSpace() throws IOException {
|
||||||
|
int c;
|
||||||
|
while ((c = r.read()) != -1 && Character.isSpace((char) c));
|
||||||
|
if (c != -1) {
|
||||||
|
r.unread(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void read(char v) throws IOException {
|
||||||
|
skipSpace();
|
||||||
|
|
||||||
|
int c = r.read();
|
||||||
|
if (c != v) {
|
||||||
|
if (c == -1) {
|
||||||
|
throw new EOFException();
|
||||||
|
} else {
|
||||||
|
throw new StreamCorruptedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private String readStringToken() throws IOException {
|
||||||
|
skipSpace();
|
||||||
|
|
||||||
|
StringBuilder sb = new StringBuilder();
|
||||||
|
int c;
|
||||||
|
while ((c = r.read()) != -1 && ! Character.isSpace((char) c)) {
|
||||||
|
sb.append((char) c);
|
||||||
|
}
|
||||||
|
if (c != -1) {
|
||||||
|
r.unread(c);
|
||||||
|
}
|
||||||
|
return sb.toString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private long readLongToken() throws IOException {
|
||||||
|
return Long.parseLong(readStringToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
private double readDoubleToken() throws IOException {
|
||||||
|
return Double.parseDouble(readStringToken());
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object readObject(HashMap<Integer, Object> map) throws IOException {
|
||||||
|
skipSpace();
|
||||||
|
switch (r.read()) {
|
||||||
|
case 'a':
|
||||||
|
return deserializeArray(map);
|
||||||
|
case 'l':
|
||||||
|
return deserialize(map);
|
||||||
|
case 'n':
|
||||||
|
return null;
|
||||||
|
case -1:
|
||||||
|
throw new EOFException();
|
||||||
|
default:
|
||||||
|
throw new StreamCorruptedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object deserializeArray(HashMap<Integer, Object> map)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
read('(');
|
||||||
|
int id = (int) readLongToken();
|
||||||
|
Class c = Class.forName(readStringToken());
|
||||||
|
int length = (int) readLongToken();
|
||||||
|
Object o = Array.newInstance(c.getComponentType(), length);
|
||||||
|
|
||||||
|
map.put(id, o);
|
||||||
|
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
skipSpace();
|
||||||
|
|
||||||
|
switch (r.read()) {
|
||||||
|
case 'a':
|
||||||
|
Array.set(o, i, deserializeArray(map));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
Array.set(o, i, deserialize(map));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'r':
|
||||||
|
Array.set(o, i, map.get((int) readLongToken()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
Array.set(o, i, null);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'z':
|
||||||
|
f.setBoolean(o, readLongToken() != 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
f.setByte(o, (byte) readLongToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
f.setChar(o, (char) readLongToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
f.setShort(o, (short) readLongToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
f.setInt(o, (int) readLongToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'j':
|
||||||
|
f.setLong(o, readLongToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
f.setFloat(o, (float) readDoubleToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
f.setDouble(o, readDoubleToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
throw new EOFException();
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new StreamCorruptedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
read(')');
|
||||||
|
}
|
||||||
|
|
||||||
|
private Object deserialize(HashMap<Integer, Object> map)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
read('(');
|
||||||
|
int id = (int) readLongToken();
|
||||||
|
Class c = Class.forName(readStringToken());
|
||||||
|
Object o = c.newInstance();
|
||||||
|
|
||||||
|
map.put(id, o);
|
||||||
|
|
||||||
|
for (Field f: c.getFields()) {
|
||||||
|
int modifiers = f.getModifiers();
|
||||||
|
if ((modifiers & (Modifier.TRANSIENT | Modifier.STATIC)) == 0) {
|
||||||
|
skipSpace();
|
||||||
|
|
||||||
|
switch (r.read()) {
|
||||||
|
case 'a':
|
||||||
|
Array.set(o, i, deserializeArray(map));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'l':
|
||||||
|
Array.set(o, i, deserialize(map));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'r':
|
||||||
|
Array.set(o, i, map.get((int) readLongToken()));
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'n':
|
||||||
|
Array.set(o, i, null);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'z':
|
||||||
|
Array.setBoolean(o, i, readLongToken() != 0);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'b':
|
||||||
|
Array.setByte(o, i, (byte) readLongToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'c':
|
||||||
|
Array.setChar(o, i, (char) readLongToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 's':
|
||||||
|
Array.setShort(o, i, (short) readLongToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'i':
|
||||||
|
Array.setInt(o, i, (int) readLongToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'j':
|
||||||
|
Array.setLong(o, i, readLongToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'f':
|
||||||
|
Array.setFloat(o, i, (float) readDoubleToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 'd':
|
||||||
|
Array.setDouble(o, i, readDoubleToken());
|
||||||
|
break;
|
||||||
|
|
||||||
|
case -1:
|
||||||
|
throw new EOFException();
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new StreamCorruptedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
read(')');
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,12 @@
|
|||||||
package java.io;
|
package java.io;
|
||||||
|
|
||||||
|
import java.util.IdentityHashMap;
|
||||||
|
|
||||||
public class ObjectOutputStream extends OutputStream {
|
public class ObjectOutputStream extends OutputStream {
|
||||||
private final OutputStream out;
|
private final PrintStream out;
|
||||||
|
|
||||||
public ObjectOutputStream(OutputStream out) {
|
public ObjectOutputStream(OutputStream out) {
|
||||||
this.out = out;
|
this.out = new PrintStream(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void write(int c) throws IOException {
|
public void write(int c) throws IOException {
|
||||||
@ -23,4 +25,156 @@ public class ObjectOutputStream extends OutputStream {
|
|||||||
out.close();
|
out.close();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void writeObject(Object o) throws IOException {
|
||||||
|
writeObject(o, new IdentityHashMap(), 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeBoolean(boolean v) {
|
||||||
|
out.print("z");
|
||||||
|
out.print((v ? 1 : 0));
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeByte(byte v) {
|
||||||
|
out.print("b");
|
||||||
|
out.print((int) v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeChar(char v) {
|
||||||
|
out.print("c");
|
||||||
|
out.print((int) v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeShort(short v) {
|
||||||
|
out.print("s");
|
||||||
|
out.print((int) v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeInt(int v) {
|
||||||
|
out.print("i");
|
||||||
|
out.print(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeLong(long v) {
|
||||||
|
out.print("j");
|
||||||
|
out.print(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeFloat(float v) {
|
||||||
|
out.print("f");
|
||||||
|
out.print(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void writeDouble(double v) {
|
||||||
|
out.print("d");
|
||||||
|
out.print(v);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void writeObject(Object o, IdentityHashMap<Object, Integer> map,
|
||||||
|
int nextId)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
if (o == null) {
|
||||||
|
out.print("n");
|
||||||
|
} else {
|
||||||
|
Integer id = map.get(new Identity(o));
|
||||||
|
if (id == null) {
|
||||||
|
map.put(new Identity(o), nextId);
|
||||||
|
|
||||||
|
Class c = o.getClass();
|
||||||
|
if (c.isArray()) {
|
||||||
|
serializeArray(o, map, nextId);
|
||||||
|
} else if (Serializable.class.isAssignableFrom(c)) {
|
||||||
|
serialize(o, map, nextId);
|
||||||
|
} else {
|
||||||
|
throw new NotSerializableException(c.getName());
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
out.print("r");
|
||||||
|
out.print(id.intValue());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void serializeArray(Object o, IdentityHashMap<Object, Integer> map,
|
||||||
|
int nextId)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
Class c = o.getClass();
|
||||||
|
Class t = c.getComponentType();
|
||||||
|
int length = Array.getLength(o);
|
||||||
|
|
||||||
|
out.print("a(");
|
||||||
|
out.print(nextId++);
|
||||||
|
out.print(" ");
|
||||||
|
out.print(c.getName());
|
||||||
|
out.print(" ");
|
||||||
|
out.print(length);
|
||||||
|
|
||||||
|
for (int i = 0; i < length; ++i) {
|
||||||
|
out.print(" ");
|
||||||
|
if (t.equals(boolean.class)) {
|
||||||
|
writeBoolean(Array.getBoolean(o));
|
||||||
|
} else if (t.equals(byte.class)) {
|
||||||
|
writeByte(Array.getByte(o));
|
||||||
|
} else if (t.equals(char.class)) {
|
||||||
|
writeChar(Array.getChar(o));
|
||||||
|
} else if (t.equals(short.class)) {
|
||||||
|
writeShort(Array.getShort(o));
|
||||||
|
} else if (t.equals(int.class)) {
|
||||||
|
writeInt(Array.getInt(o));
|
||||||
|
} else if (t.equals(long.class)) {
|
||||||
|
writeLong(Array.getLong(o));
|
||||||
|
} else if (t.equals(float.class)) {
|
||||||
|
writeFloat(Array.getFloat(o));
|
||||||
|
} else if (t.equals(double.class)) {
|
||||||
|
writeDouble(Array.getDouble(o));
|
||||||
|
} else {
|
||||||
|
writeObject(Array.get(o), map, nextId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.print(")");
|
||||||
|
}
|
||||||
|
|
||||||
|
private void serialize(Object o, IdentityHashMap<Object, Integer> map,
|
||||||
|
int nextId)
|
||||||
|
throws IOException
|
||||||
|
{
|
||||||
|
Class c = o.getClass();
|
||||||
|
|
||||||
|
out.print("l(");
|
||||||
|
out.print(nextId++);
|
||||||
|
out.print(" ");
|
||||||
|
out.print(c.getName());
|
||||||
|
|
||||||
|
for (Field f: c.getFields()) {
|
||||||
|
int modifiers = f.getModifiers();
|
||||||
|
if ((modifiers & (Modifier.TRANSIENT | Modifier.STATIC)) == 0) {
|
||||||
|
out.print(" ");
|
||||||
|
Class t = f.getType();
|
||||||
|
if (t.equals(boolean.class)) {
|
||||||
|
writeBoolean(f.getBoolean(o));
|
||||||
|
} else if (t.equals(byte.class)) {
|
||||||
|
writeByte(f.getByte(o));
|
||||||
|
} else if (t.equals(char.class)) {
|
||||||
|
writeChar(f.getChar(o));
|
||||||
|
} else if (t.equals(short.class)) {
|
||||||
|
writeShort(f.getShort(o));
|
||||||
|
} else if (t.equals(int.class)) {
|
||||||
|
writeInt(f.getInt(o));
|
||||||
|
} else if (t.equals(long.class)) {
|
||||||
|
writeLong(f.getLong(o));
|
||||||
|
} else if (t.equals(float.class)) {
|
||||||
|
writeFloat(f.getFloat(o));
|
||||||
|
} else if (t.equals(double.class)) {
|
||||||
|
writeDouble(f.getDouble(o));
|
||||||
|
} else {
|
||||||
|
writeObject(f.get(o), map, nextId);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.print(")");
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -3,17 +3,17 @@ package java.util;
|
|||||||
public class HashMap<K, V> implements Map<K, V> {
|
public class HashMap<K, V> implements Map<K, V> {
|
||||||
private int size;
|
private int size;
|
||||||
private Cell[] array;
|
private Cell[] array;
|
||||||
private final CellFactory factory;
|
private final Helper helper;
|
||||||
|
|
||||||
HashMap(int capacity, CellFactory<K, V> factory) {
|
HashMap(int capacity, Helper<K, V> helper) {
|
||||||
if (capacity > 0) {
|
if (capacity > 0) {
|
||||||
array = new Cell[nextPowerOfTwo(capacity)];
|
array = new Cell[nextPowerOfTwo(capacity)];
|
||||||
}
|
}
|
||||||
this.factory = factory;
|
this.helper = helper;
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap(int capacity) {
|
public HashMap(int capacity) {
|
||||||
this(capacity, new MyCellFactory());
|
this(capacity, new MyHelper());
|
||||||
}
|
}
|
||||||
|
|
||||||
public HashMap() {
|
public HashMap() {
|
||||||
@ -30,14 +30,6 @@ public class HashMap<K, V> implements Map<K, V> {
|
|||||||
return size;
|
return size;
|
||||||
}
|
}
|
||||||
|
|
||||||
private static int hash(Object a) {
|
|
||||||
return (a == null ? 0 : a.hashCode());
|
|
||||||
}
|
|
||||||
|
|
||||||
private static boolean equal(Object a, Object b) {
|
|
||||||
return (a == null && b == null) || (a != null && a.equals(b));
|
|
||||||
}
|
|
||||||
|
|
||||||
private void resize() {
|
private void resize() {
|
||||||
if (array == null || size >= array.length * 2) {
|
if (array == null || size >= array.length * 2) {
|
||||||
resize(array == null ? 16 : array.length * 2);
|
resize(array == null ? 16 : array.length * 2);
|
||||||
@ -115,7 +107,7 @@ public class HashMap<K, V> implements Map<K, V> {
|
|||||||
private Cell<K, V> putCell(K key, V value) {
|
private Cell<K, V> putCell(K key, V value) {
|
||||||
Cell<K, V> c = find(key);
|
Cell<K, V> c = find(key);
|
||||||
if (c == null) {
|
if (c == null) {
|
||||||
insert(factory.make(key, value, null));
|
insert(helper.make(key, value, null));
|
||||||
} else {
|
} else {
|
||||||
V old = c.getValue();
|
V old = c.getValue();
|
||||||
c.setValue(value);
|
c.setValue(value);
|
||||||
@ -196,11 +188,15 @@ public class HashMap<K, V> implements Map<K, V> {
|
|||||||
public void setNext(HashMap.Cell<K, V> next);
|
public void setNext(HashMap.Cell<K, V> next);
|
||||||
}
|
}
|
||||||
|
|
||||||
interface CellFactory<K, V> {
|
interface Helper<K, V> {
|
||||||
public Cell<K, V> make(K key, V value, Cell<K, V> next);
|
public Cell<K, V> make(K key, V value, Cell<K, V> next);
|
||||||
|
|
||||||
|
public int hash(K key);
|
||||||
|
|
||||||
|
public boolean equal(K a, K b);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MyCell<K, V> implements Cell<K, V> {
|
private class MyCell<K, V> implements Cell<K, V> {
|
||||||
public final K key;
|
public final K key;
|
||||||
public V value;
|
public V value;
|
||||||
public Cell<K, V> next;
|
public Cell<K, V> next;
|
||||||
@ -232,14 +228,22 @@ public class HashMap<K, V> implements Map<K, V> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public int hashCode() {
|
public int hashCode() {
|
||||||
return (key == null ? 0 : key.hashCode());
|
return helper.hash(key);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MyCellFactory<K, V> implements CellFactory<K, V> {
|
static class MyHelper<K, V> implements Helper<K, V> {
|
||||||
public Cell<K, V> make(K key, V value, Cell<K, V> next) {
|
public Cell<K, V> make(K key, V value, Cell<K, V> next) {
|
||||||
return new MyCell(key, value, next);
|
return new MyCell(key, value, next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int hash(K a) {
|
||||||
|
return (a == null ? 0 : a.hashCode());
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equal(K a, K b) {
|
||||||
|
return (a == null && b == null) || (a != null && a.equals(b));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class EntrySet implements Set<Entry<K, V>> {
|
private class EntrySet implements Set<Entry<K, V>> {
|
||||||
|
65
classpath/java/util/IdentityHashMap.java
Normal file
65
classpath/java/util/IdentityHashMap.java
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package java.util;
|
||||||
|
|
||||||
|
public class IdentityHashMap<K, V> implements Map<K, V> {
|
||||||
|
private final HashMap<K, V> map;
|
||||||
|
|
||||||
|
public IdentityHashMap(int capacity) {
|
||||||
|
map = new HashMap(capacity, new MyHelper());
|
||||||
|
}
|
||||||
|
|
||||||
|
public IdentityHashMap() {
|
||||||
|
this(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return map.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsKey(K key) {
|
||||||
|
return map.containsKey(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean containsValue(V value) {
|
||||||
|
return map.containsValue(value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public V get(K key) {
|
||||||
|
return map.get(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public V put(K key, V value) {
|
||||||
|
return map.put(key, value);
|
||||||
|
}
|
||||||
|
|
||||||
|
public V remove(K key) {
|
||||||
|
return map.remove(key);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void clear() {
|
||||||
|
map.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<Entry<K, V>> entrySet() {
|
||||||
|
return map.entrySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<K> keySet() {
|
||||||
|
return map.keySet();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Collection<V> values() {
|
||||||
|
return map.values();
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class MyHelper<K, V>
|
||||||
|
extends HashMap.MyHelper<K, V>
|
||||||
|
{
|
||||||
|
public int hash(K a) {
|
||||||
|
return (a == null ? 0 : System.identityHashCode(a));
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equal(K a, K b) {
|
||||||
|
return a == b;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ public class WeakHashMap<K, V> implements Map<K, V> {
|
|||||||
private final ReferenceQueue queue;
|
private final ReferenceQueue queue;
|
||||||
|
|
||||||
public WeakHashMap(int capacity) {
|
public WeakHashMap(int capacity) {
|
||||||
map = new HashMap(capacity, new MyCellFactory());
|
map = new HashMap(capacity, new MyHelper());
|
||||||
queue = new ReferenceQueue();
|
queue = new ReferenceQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -111,8 +111,8 @@ public class WeakHashMap<K, V> implements Map<K, V> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private static class MyCellFactory<K, V>
|
private static class MyHelper<K, V>
|
||||||
implements HashMap.CellFactory<K, V>
|
extends HashMap.MyHelper<K, V>
|
||||||
{
|
{
|
||||||
public HashMap.Cell<K, V> make(K key, V value, HashMap.Cell<K, V> next) {
|
public HashMap.Cell<K, V> make(K key, V value, HashMap.Cell<K, V> next) {
|
||||||
return new MyCell(key, value, next);
|
return new MyCell(key, value, next);
|
||||||
|
Loading…
Reference in New Issue
Block a user