alvinalexander.com | career | drupal | java | mac | mysql | perl | scala | uml | unix  

Java example source code file (ImmutableMap.java)

This example Java source code file (ImmutableMap.java) is included in the alvinalexander.com "Java Source Code Warehouse" project. The intent of this project is to help you "Learn Java by Example" TM.

Learn more about this Java project at its project page.

Java - Java tags/keywords

annotation, builder, entry, enummap, immutablemap, immutableset, immutablesetmultimap, object, override, regularimmutablemap, suppresswarnings, unmodifiableiterator, util

The ImmutableMap.java Java example source code

/*
 * 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 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.List;
import java.util.Map;
import java.util.Map.Entry;

import javax.annotation.Nullable;

/**
 * GWT emulation of {@link 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<K, V> implements Map, Serializable {
  abstract static class IteratorBasedImmutableMap<K, V> extends ImmutableMap {
    abstract UnmodifiableIterator<Entry entryIterator();

    @Override
    ImmutableSet<Entry createEntrySet() {
      return new ImmutableMapEntrySet<K, V>() {
        @Override
        ImmutableMap<K, V> map() {
          return IteratorBasedImmutableMap.this;
        }

        @Override
        public UnmodifiableIterator<Entry iterator() {
          return entryIterator();
        }
      };
    }
  }

  ImmutableMap() {}

  public static <K, V> ImmutableMap of() {
    return ImmutableBiMap.of();
  }

  public static <K, V> ImmutableMap of(K k1, V v1) {
    return ImmutableBiMap.of(k1, v1);
  }

  public static <K, V> ImmutableMap of(K k1, V v1, K k2, V v2) {
    return new RegularImmutableMap<K, V>(entryOf(k1, v1), entryOf(k2, v2));
  }

  public static <K, V> ImmutableMap of(
      K k1, V v1, K k2, V v2, K k3, V v3) {
    return new RegularImmutableMap<K, V>(
        entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3));
  }

  public static <K, V> ImmutableMap of(
      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
    return new RegularImmutableMap<K, V>(
        entryOf(k1, v1), entryOf(k2, v2), entryOf(k3, v3), entryOf(k4, v4));
  }

  public static <K, V> 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<K, V>(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 <K, V> Builder builder() {
    return new Builder<K, V>();
  }

  static <K, V> Entry entryOf(K key, V value) {
    checkEntryNotNull(key, value);
    return Maps.immutableEntry(key, value);
  }

  public static class Builder<K, V> {
    final List<Entry entries;
    Comparator<? super V> valueComparator;

    public Builder() {
      this.entries = Lists.newArrayList();
    }

    Builder(int initCapacity) {
      this.entries = Lists.newArrayListWithCapacity(initCapacity);
    }

    public Builder<K, V> put(K key, V value) {
      entries.add(entryOf(key, value));
      return this;
    }

    public Builder<K, V> put(Entry entry) {
      if (entry instanceof ImmutableEntry) {
        checkNotNull(entry.getKey());
        checkNotNull(entry.getValue());
        @SuppressWarnings("unchecked") // all supported methods are covariant
        Entry<K, V> immutableEntry = (Entry) entry;
        entries.add(immutableEntry);
      } else {
        entries.add(entryOf((K) entry.getKey(), (V) entry.getValue()));
      }
      return this;
    }

    public Builder<K, V> putAll(Map map) {
      return putAll(map.entrySet());
    }

    public Builder<K, V> putAll(Iterable> entries) {
      for (Entry<? extends K, ? extends V> entry : entries) {
        put(entry);
      }
      return this;
    }

    public Builder<K, V> orderEntriesByValue(Comparator valueComparator) {
      checkState(this.valueComparator == null, "valueComparator was already set");
      this.valueComparator = checkNotNull(valueComparator, "valueComparator");
      return this;
    }

    public ImmutableMap<K, V> build() {
      if (valueComparator != null) {
        Collections.sort(
            entries,
            Ordering.from(valueComparator).onResultOf(Maps.<V>valueFunction()));
      }
      return fromEntryList(entries);
    }
  }

  static <K, V> ImmutableMap fromEntryList(
      Collection<? extends Entry entries) {
    int size = entries.size();
    switch (size) {
      case 0:
        return of();
      case 1:
        Entry<? extends K, ? extends V> entry = getOnlyElement(entries);
        return of((K) entry.getKey(), (V) entry.getValue());
      default:
        @SuppressWarnings("unchecked")
        Entry<K, V>[] entryArray
            = entries.toArray(new Entry[entries.size()]);
        return new RegularImmutableMap<K, V>(entryArray);
    }
  }

  public static <K, V> ImmutableMap copyOf(
      Map<? extends K, ? extends V> map) {
    if ((map instanceof ImmutableMap) && !(map instanceof ImmutableSortedMap)) {
      @SuppressWarnings("unchecked") // safe since map is not writable
      ImmutableMap<K, V> kvMap = (ImmutableMap) map;
      return kvMap;
    } else if (map instanceof EnumMap) {
      EnumMap<?, ?> enumMap = (EnumMap) map;
      for (Map.Entry<?, ?> entry : enumMap.entrySet()) {
        checkNotNull(entry.getKey());
        checkNotNull(entry.getValue());
      }
      @SuppressWarnings("unchecked")
      // immutable collections are safe for covariant casts
      ImmutableMap<K, V> result = ImmutableEnumMap.asImmutable(new EnumMap(enumMap));
      return result;
    }

    int size = map.size();
    switch (size) {
      case 0:
        return of();
      case 1:
        Entry<? extends K, ? extends V> entry
            = getOnlyElement(map.entrySet());
        return ImmutableMap.<K, V>of(entry.getKey(), entry.getValue());
      default:
        Map<K, V> orderPreservingCopy = Maps.newLinkedHashMap();
        for (Entry<? extends K, ? extends V> e : map.entrySet()) {
          orderPreservingCopy.put(
              checkNotNull(e.getKey()), checkNotNull(e.getValue()));
        }
        return new RegularImmutableMap<K, V>(orderPreservingCopy);
    }
  }

  public static <K, V> ImmutableMap copyOf(
      Iterable<? extends Entry entries) {
    if (entries instanceof Collection) {
      return fromEntryList(
          (Collection<? extends Entry) 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<? extends K, ? extends V> 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<Entry cachedEntrySet = null;

  public final ImmutableSet<Entry entrySet() {
    if (cachedEntrySet != null) {
      return cachedEntrySet;
    }
    return cachedEntrySet = createEntrySet();
  }

  abstract ImmutableSet<Entry createEntrySet();

  private transient ImmutableSet<K> cachedKeySet = null;

  public ImmutableSet<K> keySet() {
    if (cachedKeySet != null) {
      return cachedKeySet;
    }
    return cachedKeySet = createKeySet();
  }

  ImmutableSet<K> createKeySet() {
    return new ImmutableMapKeySet<K, V>(this);
  }

  UnmodifiableIterator<K> keyIterator() {
    final UnmodifiableIterator<Entry entryIterator = entrySet().iterator();
    return new UnmodifiableIterator<K>() {
      @Override public boolean hasNext() {
        return entryIterator.hasNext();
      }

      @Override public K next() {
        return entryIterator.next().getKey();
      }
    };
  }

  private transient ImmutableCollection<V> cachedValues = null;

  public ImmutableCollection<V> values() {
    if (cachedValues != null) {
      return cachedValues;
    }
    return cachedValues = createValues();
  }

  // cached so that this.multimapView().inverse() only computes inverse once
  private transient ImmutableSetMultimap<K, V> multimapView;

  public ImmutableSetMultimap<K, V> asMultimap() {
    ImmutableSetMultimap<K, V> result = multimapView;
    return (result == null)
        ? (multimapView = new ImmutableSetMultimap<K, V>(
            new MapViewOfValuesAsSingletonSets(), size(), null))
        : result;
  }

  final class MapViewOfValuesAsSingletonSets
      extends IteratorBasedImmutableMap<K, ImmutableSet {

    @Override public int size() {
      return ImmutableMap.this.size();
    }

    @Override public ImmutableSet<K> keySet() {
      return ImmutableMap.this.keySet();
    }

    @Override public boolean containsKey(@Nullable Object key) {
      return ImmutableMap.this.containsKey(key);
    }

    @Override public ImmutableSet<V> 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<Entry> entryIterator() {
      final Iterator<Entry backingIterator = ImmutableMap.this.entrySet().iterator();
      return new UnmodifiableIterator<Entry>() {
        @Override public boolean hasNext() {
          return backingIterator.hasNext();
        }

        @Override public Entry<K, ImmutableSet next() {
          final Entry<K, V> backingEntry = backingIterator.next();
          return new AbstractMapEntry<K, ImmutableSet() {
            @Override public K getKey() {
              return backingEntry.getKey();
            }

            @Override public ImmutableSet<V> getValue() {
              return ImmutableSet.of(backingEntry.getValue());
            }
          };
        }
      };
    }
  }

  ImmutableCollection<V> createValues() {
    return new ImmutableMapValues<K, V>(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);
  }
}

Other Java examples (source code examples)

Here is a short list of links related to this Java ImmutableMap.java source code file:

... this post is sponsored by my books ...

#1 New Release!

FP Best Seller

 

new blog posts

 

Copyright 1998-2021 Alvin Alexander, alvinalexander.com
All Rights Reserved.

A percentage of advertising revenue from
pages under the /java/jwarehouse URI on this website is
paid back to open source projects.