
org.javersion.util.AbstractHashMap Maven / Gradle / Ivy
The newest version!
/*
* Copyright 2013 Samppa Saarela
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.javersion.util;
import static com.google.common.collect.Iterators.transform;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;
import org.javersion.util.AbstractHashMap.EntryNode;
import com.google.common.base.Function;
public abstract class AbstractHashMap>
extends AbstractHashTrie, AbstractHashMap>
implements Iterable> {
@SuppressWarnings("rawtypes")
private static final Function TO_ENTRY = (Object input) -> toEntry((Map.Entry) input);
public This assoc(K key, V value) {
return assoc(new EntryNode(key, value));
}
private This assoc(java.util.Map.Entry extends K, ? extends V> entry) {
return merge(entry, null);
}
public This assocAll(Map extends K, ? extends V> map) {
return mergeAll(map, null);
}
public This assocAll(Iterable> entries) {
return mergeAll(entries, null);
}
public This merge(K key, V value, Merger> merger) {
return doMerge(new EntryNode(key, value), merger);
}
public This merge(Map.Entry extends K, ? extends V> entry, Merger> merger) {
return doMerge(toEntry(entry), merger);
}
@SuppressWarnings("unchecked")
protected This doMerge(EntryNode entry, Merger> merger) {
final UpdateContext> updateContext = updateContext(1, merger);
return (This) doAdd(updateContext, entry);
}
@SuppressWarnings("unchecked")
public This mergeAll(Map extends K, ? extends V> map, Merger> merger) {
final UpdateContext> updateContext = updateContext(map.size(), merger);
return (This) doAddAll(updateContext, transform(map.entrySet().iterator(), TO_ENTRY));
}
@SuppressWarnings("unchecked")
public This mergeAll(Iterable> entries, Merger> merger) {
final UpdateContext> updateContext = updateContext(32, merger);
return (This) doAddAll(updateContext, transform(entries.iterator(), TO_ENTRY));
}
protected UpdateContext> updateContext(int expectedSize, Merger> merger) {
return new UpdateContext<>(expectedSize, merger);
}
public This dissoc(Object key) {
return dissoc(key, null);
}
@SuppressWarnings("unchecked")
public This dissoc(Object key, Merger> merger) {
final UpdateContext> updateContext = updateContext(1, merger);
return (This) doRemove(updateContext, key);
}
public V get(Object key) {
EntryNode entry = root().find(key);
return entry != null ? entry.getValue() : null;
}
public boolean containsKey(Object key) {
return root().find(key) != null;
}
public Iterator> iterator() {
return transform(doIterator(), Map.Entry.class::cast);
}
@SuppressWarnings("unchecked")
protected static EntryNode toEntry(Map.Entry extends K, ? extends V> entry) {
if (entry instanceof EntryNode) {
return (EntryNode) entry;
} else {
return new EntryNode<>(entry.getKey(), entry.getValue());
}
}
public static final class EntryNode extends AbstractHashTrie.EntryNode> implements Map.Entry {
final V value;
public EntryNode(K key, V value) {
super(key);
this.value = value;
}
@Override
public K getKey() {
return key;
}
@Override
public V getValue() {
return value;
}
@Override
public V setValue(V value) {
throw new UnsupportedOperationException();
}
public String toString() {
return "" + key + ": " + value;
}
@Override
public Node> assocInternal(final UpdateContext super EntryNode> currentContext, final int shift, final int hash, final EntryNode newEntry) {
if (Objects.equals(key, newEntry.key)) {
if (Objects.equals(value, newEntry.value)) {
return this;
}
return currentContext.merge(this, newEntry) ? newEntry : this;
}
return split(currentContext, shift, hash, newEntry);
}
}
static class EntrySpliterator extends NodeSpliterator, K, EntryNode> {
public EntrySpliterator(Node> node, int sizeEstimate, boolean immutable) {
super(node, sizeEstimate, DISTINCT | (immutable ? IMMUTABLE : 0));
}
private EntrySpliterator(Node>[] array, int pos, int limit, int sizeEstimate, boolean immutable) {
super(array, pos, limit, sizeEstimate, DISTINCT | (immutable ? IMMUTABLE : 0));
}
@Override
protected NodeSpliterator, K, EntryNode> newSubSpliterator(Node>[] array, int pos, int limit, int sizeEstimate) {
return new EntrySpliterator<>(array, pos, limit, sizeEstimate, hasCharacteristics(IMMUTABLE));
}
@Override
protected Map.Entry apply(EntryNode entry) {
return entry;
}
}
static class KeySpliterator extends NodeSpliterator> {
public KeySpliterator(Node> node, int sizeEstimate, boolean immutable) {
super(node, sizeEstimate, DISTINCT | (immutable ? IMMUTABLE : 0));
}
private KeySpliterator(Node>[] array, int pos, int limit, int sizeEstimate, boolean immutable) {
super(array, pos, limit, sizeEstimate, DISTINCT | (immutable ? IMMUTABLE : 0));
}
@Override
protected NodeSpliterator> newSubSpliterator(Node>[] array, int pos, int limit, int sizeEstimate) {
return new KeySpliterator<>(array, pos, limit, sizeEstimate, hasCharacteristics(IMMUTABLE));
}
@Override
protected K apply(EntryNode entry) {
return entry.getKey();
}
}
static class ValueSpliterator extends NodeSpliterator> {
public ValueSpliterator(Node> node, int sizeEstimate, boolean immutable) {
super(node, sizeEstimate, (immutable ? IMMUTABLE : 0));
}
private ValueSpliterator(Node>[] array, int pos, int limit, int sizeEstimate, boolean immutable) {
super(array, pos, limit, sizeEstimate, (immutable ? IMMUTABLE : 0));
}
@Override
protected NodeSpliterator> newSubSpliterator(Node>[] array, int pos, int limit, int sizeEstimate) {
return new ValueSpliterator<>(array, pos, limit, sizeEstimate, hasCharacteristics(IMMUTABLE));
}
@Override
protected V apply(EntryNode entry) {
return entry.getValue();
}
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy