@Override public void clear() { parent.clear(); } }
@Override public BidiMap<V, K> inverseBidiMap() { if (inverseBidiMap == null) { inverseBidiMap = createBidiMap(reverseMap, normalMap, this); } return inverseBidiMap; }
/** * Constructor. * @param parent the parent map */ protected BidiOrderedMapIterator(final AbstractDualBidiMap<K, V> parent) { super(); this.parent = parent; iterator = new ArrayList<>(parent.entrySet()).listIterator(); }
/** * {@inheritDoc} * <p> * This implementation iterates over the elements of this bidi map, checking each element in * turn to see if it's contained in <code>coll</code>. If it's not contained, it's removed * from this bidi map. As a consequence, it is advised to use a collection type for * <code>coll</code> that provides a fast (e.g. O(1)) implementation of * {@link Collection#contains(Object)}. */ @Override public boolean retainAll(final Collection<?> coll) { if (parent.isEmpty()) { return false; } if (coll.isEmpty()) { parent.clear(); return true; } boolean modified = false; final Iterator<E> it = iterator(); while (it.hasNext()) { if (coll.contains(it.next()) == false) { it.remove(); modified = true; } } return modified; }
@Override public void putAll(final Map<? extends K, ? extends V> map) { for (final Map.Entry<? extends K, ? extends V> entry : map.entrySet()) { put(entry.getKey(), entry.getValue()); } }
@Override public SortedBidiMap<V, K> inverseBidiMap() { return (SortedBidiMap<V, K>) super.inverseBidiMap(); }
@Override public boolean removeAll(final Collection<?> coll) { if (parent.isEmpty() || coll.isEmpty()) { return false; } boolean modified = false; final Iterator<?> it = coll.iterator(); while (it.hasNext()) { modified |= remove(it.next()); } return modified; }
@Override public boolean remove(final Object obj) { if (obj instanceof Map.Entry == false) { return false; } final Map.Entry<?, ?> entry = (Map.Entry<?, ?>) obj; final Object key = entry.getKey(); if (parent.containsKey(key)) { final V value = parent.normalMap.get(key); if (value == null ? entry.getValue() == null : value.equals(entry.getValue())) { parent.normalMap.remove(key); parent.reverseMap.remove(value); return true; } } return false; } }
@Override public Iterator<K> iterator() { return parent.createKeySetIterator(super.iterator()); }
@Override public Iterator<V> iterator() { return parent.createValuesIterator(super.iterator()); }
@Override public Iterator<Map.Entry<K, V>> iterator() { return parent.createEntrySetIterator(super.iterator()); }
@Override public V setValue(final V value) { if (last == null) { throw new IllegalStateException( "Iterator setValue() can only be called after next() and before remove()"); } if (parent.reverseMap.containsKey(value) && parent.reverseMap.get(value) != last.getKey()) { throw new IllegalArgumentException( "Cannot use setValue() when the object being set is already in the map"); } return parent.put(last.getKey(), value); }
@Override public V setValue(final V value) { if (last == null) { throw new IllegalStateException( "Iterator setValue() can only be called after next() and before remove()"); } if (parent.reverseMap.containsKey(value) && parent.reverseMap.get(value) != last.getKey()) { throw new IllegalArgumentException( "Cannot use setValue() when the object being set is already in the map"); } final V oldValue = parent.put(last.getKey(), value); // Map.Entry specifies that the behavior is undefined when the backing map // has been modified (as we did with the put), so we also set the value // (especially needed for IBM JDK) last.setValue(value); return oldValue; }
@Override public void reset() { iterator = new ArrayList<>(parent.entrySet()).listIterator(); last = null; }
@Override public V setValue(final V value) { final K key = MapEntry.this.getKey(); if (parent.reverseMap.containsKey(value) && parent.reverseMap.get(value) != key) { throw new IllegalArgumentException( "Cannot use setValue() when the object being set is already in the map"); } parent.put(key, value); return super.setValue(value); } }