Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.google.common.collect.super.com.google.common.collect.ImmutableMap Maven / Gradle / Ivy
Go to download
Guava is a suite of core and expanded libraries that include
utility classes, google's collections, io classes, and much
much more.
This project includes GWT-friendly sources.
/*
* Copyright (C) 2009 The Guava Authors
*
* 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 com.google.common.collect;
import static com.google.common.base.Preconditions.checkNotNull;
import static com.google.common.base.Preconditions.checkState;
import static com.google.common.collect.CollectPreconditions.checkEntryNotNull;
import static com.google.common.collect.Iterables.getOnlyElement;
import com.google.common.annotations.Beta;
import java.io.Serializable;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Spliterator;
import java.util.function.BinaryOperator;
import java.util.function.Function;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import org.checkerframework.checker.nullness.qual.Nullable;
/**
* GWT emulation of {@link com.google.common.collect.ImmutableMap}. For non sorted maps, it is a
* thin wrapper around {@link java.util.Collections#emptyMap()}, {@link
* Collections#singletonMap(Object, Object)} and {@link java.util.LinkedHashMap} for empty,
* singleton and regular maps respectively. For sorted maps, it's a thin wrapper around {@link
* java.util.TreeMap}.
*
* @see ImmutableSortedMap
* @author Hayward Chan
*/
public abstract class ImmutableMap implements Map, Serializable {
static final ImmutableMap EMPTY = new RegularImmutableMap();
abstract static class IteratorBasedImmutableMap extends ImmutableMap {
abstract UnmodifiableIterator> entryIterator();
@Override
ImmutableSet> createEntrySet() {
return new ImmutableMapEntrySet() {
@Override
ImmutableMap map() {
return IteratorBasedImmutableMap.this;
}
@Override
public UnmodifiableIterator> iterator() {
return entryIterator();
}
};
}
}
ImmutableMap() {}
@Beta
public static Collector> toImmutableMap(
Function keyFunction,
Function valueFunction) {
return CollectCollectors.toImmutableMap(keyFunction, valueFunction);
}
@Beta
public static Collector> toImmutableMap(
Function keyFunction,
Function valueFunction,
BinaryOperator mergeFunction) {
checkNotNull(keyFunction);
checkNotNull(valueFunction);
checkNotNull(mergeFunction);
return Collectors.collectingAndThen(
Collectors.toMap(keyFunction, valueFunction, mergeFunction, LinkedHashMap::new),
ImmutableMap::copyOf);
}
public static ImmutableMap of() {
return (ImmutableMap) EMPTY;
}
public static ImmutableMap of(K k1, V v1) {
return ImmutableBiMap.of(k1, v1);
}
public static ImmutableMap of(K k1, V v1, K k2, V v2) {
return new RegularImmutableMap(entryOf(k1, v1), entryOf(k2, v2));
}
public static ImmutableMap of(K k1, V v1, K k2, V v2, K k3, V v3) {
return new RegularImmutableMap(entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3));
}
public static ImmutableMap of(K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
return new RegularImmutableMap(
entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4));
}
public static ImmutableMap of(
K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
return new RegularImmutableMap(
entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4), entryOf(k5, v5));
}
// looking for of() with > 5 entries? Use the builder instead.
public static Builder builder() {
return new Builder();
}
public static Builder builderWithExpectedSize(int expectedSize) {
return new Builder(expectedSize);
}
static Entry entryOf(K key, V value) {
checkEntryNotNull(key, value);
return Maps.immutableEntry(key, value);
}
public static class Builder {
final List> entries;
Comparator valueComparator;
public Builder() {
this.entries = Lists.newArrayList();
}
Builder(int initCapacity) {
this.entries = Lists.newArrayListWithCapacity(initCapacity);
}
public Builder put(K key, V value) {
entries.add(entryOf(key, value));
return this;
}
public Builder put(Entry entry) {
if (entry instanceof ImmutableEntry) {
checkNotNull(entry.getKey());
checkNotNull(entry.getValue());
@SuppressWarnings("unchecked") // all supported methods are covariant
Entry immutableEntry = (Entry) entry;
entries.add(immutableEntry);
} else {
entries.add(entryOf((K) entry.getKey(), (V) entry.getValue()));
}
return this;
}
public Builder putAll(Map map) {
return putAll(map.entrySet());
}
public Builder putAll(Iterable> entries) {
for (Entry entry : entries) {
put(entry);
}
return this;
}
public Builder orderEntriesByValue(Comparator valueComparator) {
checkState(this.valueComparator == null, "valueComparator was already set");
this.valueComparator = checkNotNull(valueComparator, "valueComparator");
return this;
}
Builder combine(Builder other) {
checkNotNull(other);
entries.addAll(other.entries);
return this;
}
public ImmutableMap build() {
if (valueComparator != null) {
Collections.sort(
entries, Ordering.from(valueComparator).onResultOf(Maps.valueFunction()));
}
return fromEntryList(entries);
}
ImmutableMap buildJdkBacked() {
return build();
}
}
static ImmutableMap fromEntryList(
Collection> entries) {
int size = entries.size();
switch (size) {
case 0:
return of();
case 1:
Entry entry = getOnlyElement(entries);
return of((K) entry.getKey(), (V) entry.getValue());
default:
@SuppressWarnings("unchecked")
Entry[] entryArray = entries.toArray(new Entry[entries.size()]);
return new RegularImmutableMap(entryArray);
}
}
public static ImmutableMap copyOf(Map map) {
if ((map instanceof ImmutableMap) && !(map instanceof ImmutableSortedMap)) {
@SuppressWarnings("unchecked") // safe since map is not writable
ImmutableMap kvMap = (ImmutableMap) map;
return kvMap;
} else if (map instanceof EnumMap) {
EnumMap enumMap = (EnumMap) map;
for (Entry entry : enumMap.entrySet()) {
checkNotNull(entry.getKey());
checkNotNull(entry.getValue());
}
@SuppressWarnings("unchecked")
// immutable collections are safe for covariant casts
ImmutableMap result = ImmutableEnumMap.asImmutable(new EnumMap(enumMap));
return result;
}
int size = map.size();
switch (size) {
case 0:
return of();
case 1:
Entry entry = getOnlyElement(map.entrySet());
return ImmutableMap.of(entry.getKey(), entry.getValue());
default:
Map orderPreservingCopy = Maps.newLinkedHashMap();
for (Entry e : map.entrySet()) {
orderPreservingCopy.put(checkNotNull(e.getKey()), checkNotNull(e.getValue()));
}
return new RegularImmutableMap(orderPreservingCopy);
}
}
public static ImmutableMap copyOf(
Iterable> entries) {
if (entries instanceof Collection) {
return fromEntryList((Collection>) entries);
} else {
return fromEntryList(Lists.newArrayList(entries.iterator()));
}
}
abstract boolean isPartialView();
public final V put(K k, V v) {
throw new UnsupportedOperationException();
}
public final V remove(Object o) {
throw new UnsupportedOperationException();
}
public final void putAll(Map map) {
throw new UnsupportedOperationException();
}
public final void clear() {
throw new UnsupportedOperationException();
}
@Override
public boolean isEmpty() {
return size() == 0;
}
@Override
public boolean containsKey(@Nullable Object key) {
return get(key) != null;
}
@Override
public boolean containsValue(@Nullable Object value) {
return values().contains(value);
}
private transient ImmutableSet> cachedEntrySet = null;
public final ImmutableSet> entrySet() {
if (cachedEntrySet != null) {
return cachedEntrySet;
}
return cachedEntrySet = createEntrySet();
}
abstract ImmutableSet> createEntrySet();
private transient ImmutableSet cachedKeySet = null;
public ImmutableSet keySet() {
if (cachedKeySet != null) {
return cachedKeySet;
}
return cachedKeySet = createKeySet();
}
ImmutableSet createKeySet() {
return new ImmutableMapKeySet(this);
}
UnmodifiableIterator keyIterator() {
final UnmodifiableIterator> entryIterator = entrySet().iterator();
return new UnmodifiableIterator() {
@Override
public boolean hasNext() {
return entryIterator.hasNext();
}
@Override
public K next() {
return entryIterator.next().getKey();
}
};
}
Spliterator keySpliterator() {
return CollectSpliterators.map(entrySet().spliterator(), Entry::getKey);
}
private transient ImmutableCollection cachedValues = null;
public ImmutableCollection values() {
if (cachedValues != null) {
return cachedValues;
}
return cachedValues = createValues();
}
// cached so that this.multimapView().inverse() only computes inverse once
private transient ImmutableSetMultimap multimapView;
public ImmutableSetMultimap asMultimap() {
ImmutableSetMultimap result = multimapView;
return (result == null)
? (multimapView =
new ImmutableSetMultimap(new MapViewOfValuesAsSingletonSets(), size(), null))
: result;
}
final class MapViewOfValuesAsSingletonSets extends IteratorBasedImmutableMap> {
@Override
public int size() {
return ImmutableMap.this.size();
}
@Override
public ImmutableSet keySet() {
return ImmutableMap.this.keySet();
}
@Override
public boolean containsKey(@Nullable Object key) {
return ImmutableMap.this.containsKey(key);
}
@Override
public ImmutableSet get(@Nullable Object key) {
V outerValue = ImmutableMap.this.get(key);
return (outerValue == null) ? null : ImmutableSet.of(outerValue);
}
@Override
boolean isPartialView() {
return ImmutableMap.this.isPartialView();
}
@Override
public int hashCode() {
// ImmutableSet.of(value).hashCode() == value.hashCode(), so the hashes are the same
return ImmutableMap.this.hashCode();
}
@Override
UnmodifiableIterator>> entryIterator() {
final Iterator> backingIterator = ImmutableMap.this.entrySet().iterator();
return new UnmodifiableIterator>>() {
@Override
public boolean hasNext() {
return backingIterator.hasNext();
}
@Override
public Entry> next() {
final Entry backingEntry = backingIterator.next();
return new AbstractMapEntry>() {
@Override
public K getKey() {
return backingEntry.getKey();
}
@Override
public ImmutableSet getValue() {
return ImmutableSet.of(backingEntry.getValue());
}
};
}
};
}
}
ImmutableCollection createValues() {
return new ImmutableMapValues(this);
}
@Override
public boolean equals(@Nullable Object object) {
return Maps.equalsImpl(this, object);
}
@Override
public int hashCode() {
// not caching hash code since it could change if map values are mutable
// in a way that modifies their hash codes
return entrySet().hashCode();
}
@Override
public String toString() {
return Maps.toStringImpl(this);
}
}