/** * Compares this map entry to another. * <p> * This implementation uses <code>isEqualKey</code> and * <code>isEqualValue</code> on the main map for comparison. * * @param obj the other map entry to compare to * @return true if equal, false if not */ @Override public boolean equals(final Object obj) { if (obj == this) { return true; } if (obj instanceof Map.Entry == false) { return false; } final Map.Entry<?, ?> entry = (Map.Entry<?, ?>)obj; final Object entryKey = entry.getKey(); // convert to hard reference final Object entryValue = entry.getValue(); // convert to hard reference if (entryKey == null || entryValue == null) { return false; } // compare using map methods, aiding identity subclass // note that key is direct access and value is via method return parent.isEqualKey(entryKey, key) && parent.isEqualValue(entryValue, getValue()); }
protected ReferenceEntry<K, V> nextEntry() { checkMod(); if (nextNull() && !hasNext()) { throw new NoSuchElementException(); } previous = entry; entry = entry.next(); currentKey = nextKey; currentValue = nextValue; nextKey = null; nextValue = null; return previous; }
/** * Purges the specified reference. * * @param ref the reference to purge */ protected void purge(final Reference<?> ref) { // The hashCode of the reference is the hashCode of the // mapping key, even if the reference refers to the // mapping value... final int hash = ref.hashCode(); final int index = hashIndex(hash, data.length); HashEntry<K, V> previous = null; HashEntry<K, V> entry = data[index]; while (entry != null) { if (((ReferenceEntry<K, V>) entry).purge(ref)) { if (previous == null) { data[index] = entry.next; } else { previous.next = entry.next; } this.size--; return; } previous = entry; entry = entry.next; } }
public boolean hasNext() { checkMod(); while (nextNull()) { ReferenceEntry<K, V> e = entry; int i = index; while (e == null && i > 0) { i--; e = (ReferenceEntry<K, V>) parent.data[i]; } entry = e; index = i; if (e == null) { currentKey = null; currentValue = null; return false; } nextKey = e.getKey(); nextValue = e.getValue(); if (nextNull()) { entry = entry.next(); } } return true; }
/** * Creates a new entry object for the ReferenceMap. * * @param parent the parent map * @param next the next entry in the hash bucket * @param hashCode the hash code of the key * @param key the key * @param value the value */ public ReferenceEntry(final AbstractReferenceMap<K, V> parent, final HashEntry<K, V> next, final int hashCode, final K key, final V value) { super(next, hashCode, null, null); this.parent = parent; this.key = toReference(parent.keyType, key, hashCode); this.value = toReference(parent.valueType, value, hashCode); // the key hashCode is passed in deliberately }
/** * Creates a ReferenceEntry instead of a HashEntry. * * @param next the next entry in sequence * @param hashCode the hash code to use * @param key the key to store * @param value the value to store * @return the newly created entry */ @Override protected ReferenceEntry<K, V> createEntry(final HashEntry<K, V> next, final int hashCode, final K key, final V value) { return new ReferenceEntry<>(this, next, hashCode, key, value); }
/** * Sets the value of the entry. * * @param obj the object to store * @return the previous value */ @Override @SuppressWarnings("unchecked") public V setValue(final V obj) { final V old = getValue(); if (parent.valueType != ReferenceStrength.HARD) { ((Reference<V>) value).clear(); } value = toReference(parent.valueType, obj, hashCode); return old; }
@Override public V next() { return nextEntry().getValue(); } }
@Override public K next() { return nextEntry().getKey(); }
@Override public K next() { return nextEntry().getKey(); } }