mirror of
https://github.com/openjdk/jdk.git
synced 2026-02-01 05:58:29 +00:00
221 lines
6.4 KiB
Java
221 lines
6.4 KiB
Java
/*
|
|
* Copyright (c) 2015, 2018, 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. Oracle designates this
|
|
* particular file as subject to the "Classpath" exception as provided
|
|
* by Oracle in the LICENSE file that accompanied this code.
|
|
*
|
|
* 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.
|
|
*/
|
|
|
|
package sun.awt;
|
|
|
|
import java.lang.ref.Reference;
|
|
import java.lang.ref.ReferenceQueue;
|
|
import java.lang.ref.WeakReference;
|
|
import java.util.*;
|
|
|
|
// A weak key reference hash map that uses System.identityHashCode() and "=="
|
|
// instead of hashCode() and equals(Object)
|
|
class WeakIdentityHashMap<K, V> implements Map<K, V> {
|
|
private final Map<WeakKey<K>, V> map;
|
|
private final transient ReferenceQueue<K> queue = new ReferenceQueue<K>();
|
|
|
|
/**
|
|
* Constructs a new, empty identity hash map with a default initial
|
|
* size (16).
|
|
*/
|
|
public WeakIdentityHashMap() {
|
|
map = new HashMap<>(16);
|
|
}
|
|
|
|
/**
|
|
* Constructs a new, empty identity map with the specified initial size.
|
|
*/
|
|
public WeakIdentityHashMap(int initialSize) {
|
|
map = new HashMap<>(initialSize);
|
|
}
|
|
|
|
private Map<WeakKey<K>, V> getMap() {
|
|
for(Reference<? extends K> ref; (ref = this.queue.poll()) != null;) {
|
|
map.remove(ref);
|
|
}
|
|
return map;
|
|
}
|
|
|
|
@Override
|
|
public int size() {
|
|
return getMap().size();
|
|
}
|
|
|
|
@Override
|
|
public boolean isEmpty() {
|
|
return getMap().isEmpty();
|
|
}
|
|
|
|
@Override
|
|
public boolean containsKey(Object key) {
|
|
return getMap().containsKey(new WeakKey<>(key, null));
|
|
}
|
|
|
|
@Override
|
|
public boolean containsValue(Object value) {
|
|
return getMap().containsValue(value);
|
|
}
|
|
|
|
@Override
|
|
public V get(Object key) {
|
|
return getMap().get(new WeakKey<>(key, null));
|
|
}
|
|
|
|
@Override
|
|
public V put(K key, V value) {
|
|
return getMap().put(new WeakKey<K>(key, queue), value);
|
|
}
|
|
|
|
@Override
|
|
public V remove(Object key) {
|
|
return getMap().remove(new WeakKey<>(key, null));
|
|
}
|
|
|
|
@Override
|
|
public void putAll(Map<? extends K, ? extends V> m) {
|
|
for (Entry<? extends K, ? extends V> entry : m.entrySet()) {
|
|
put(entry.getKey(), entry.getValue());
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public void clear() {
|
|
getMap().clear();
|
|
}
|
|
|
|
@Override
|
|
public Set<K> keySet() {
|
|
return new AbstractSet<K>() {
|
|
@Override
|
|
public Iterator<K> iterator() {
|
|
return new Iterator<K>() {
|
|
private K next;
|
|
Iterator<WeakKey<K>> iterator = getMap().keySet().iterator();
|
|
|
|
@Override
|
|
public boolean hasNext() {
|
|
while (iterator.hasNext()) {
|
|
if ((next = iterator.next().get()) != null) {
|
|
return true;
|
|
}
|
|
}
|
|
return false;
|
|
}
|
|
|
|
@Override
|
|
public K next() {
|
|
if(next == null && !hasNext()) {
|
|
throw new NoSuchElementException();
|
|
}
|
|
K ret = next;
|
|
next = null;
|
|
return ret;
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override
|
|
public int size() {
|
|
return getMap().keySet().size();
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override
|
|
public Collection<V> values() {
|
|
return getMap().values();
|
|
}
|
|
|
|
@Override
|
|
public Set<Entry<K, V>> entrySet() {
|
|
return new AbstractSet<Entry<K, V>>() {
|
|
@Override
|
|
public Iterator<Entry<K, V>> iterator() {
|
|
final Iterator<Entry<WeakKey<K>, V>> iterator = getMap().entrySet().iterator();
|
|
return new Iterator<Entry<K, V>>() {
|
|
@Override
|
|
public boolean hasNext() {
|
|
return iterator.hasNext();
|
|
}
|
|
|
|
@Override
|
|
public Entry<K, V> next() {
|
|
return new Entry<K, V>() {
|
|
Entry<WeakKey<K>, V> entry = iterator.next();
|
|
|
|
@Override
|
|
public K getKey() {
|
|
return entry.getKey().get();
|
|
}
|
|
|
|
@Override
|
|
public V getValue() {
|
|
return entry.getValue();
|
|
}
|
|
|
|
@Override
|
|
public V setValue(V value) {
|
|
return null;
|
|
}
|
|
};
|
|
}
|
|
};
|
|
}
|
|
|
|
@Override
|
|
public int size() {
|
|
return getMap().entrySet().size();
|
|
}
|
|
};
|
|
}
|
|
|
|
private static class WeakKey<K> extends WeakReference<K> {
|
|
private final int hash;
|
|
|
|
WeakKey(K key, ReferenceQueue <K> q) {
|
|
super(key, q);
|
|
hash = System.identityHashCode(key);
|
|
}
|
|
|
|
@Override
|
|
public boolean equals(Object o) {
|
|
if(this == o) {
|
|
return true;
|
|
} else if( o instanceof WeakKey ) {
|
|
return get() == ((WeakKey)o).get();
|
|
} else {
|
|
return false;
|
|
}
|
|
}
|
|
|
|
@Override
|
|
public int hashCode() {
|
|
return hash;
|
|
}
|
|
}
|
|
|
|
|
|
}
|