Start line:  
End line:  

Snippet Preview

Snippet HTML Code

Stack Overflow Questions
  /*
   * Copyright (C) 2008 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 java.util.List;
 import java.util.Map;
 import java.util.Set;
 
An immutable Multimap. Does not permit null keys or values.

Unlike Multimaps.unmodifiableMultimap(com.google.common.collect.Multimap), which is a view of a separate multimap which can still change, an instance of ImmutableMultimap contains its own data and will never change. ImmutableMultimap is convenient for public static final multimaps ("constant multimaps") and also lets you easily make a "defensive copy" of a multimap provided to your class by a caller.

Note: Although this class is not final, it cannot be subclassed as it has no public or protected constructors. Thus, instances of this class are guaranteed to be immutable.

In addition to methods defined by Multimap, an inverse() method is also supported.

See the Guava User Guide article on immutable collections.

Author(s):
Jared Levy
Since:
2.0 (imported from Google Collections Library)
 
 @GwtCompatible(emulated = true)
 public abstract class ImmutableMultimap<K, V>
     implements Multimap<K, V>, Serializable {

  
Returns an empty multimap.
 
   public static <K, V> ImmutableMultimap<K, V> of() {
     return ImmutableListMultimap.of();
   }

  
Returns an immutable multimap containing a single entry.
 
   public static <K, V> ImmutableMultimap<K, V> of(K k1, V v1) {
     return ImmutableListMultimap.of(k1v1);
   }

  
Returns an immutable multimap containing the given entries, in order.
 
   public static <K, V> ImmutableMultimap<K, V> of(K k1, V v1, K k2, V v2) {
     return ImmutableListMultimap.of(k1v1k2v2);
   }

  
Returns an immutable multimap containing the given entries, in order.
 
   public static <K, V> ImmutableMultimap<K, V> of(
       K k1, V v1, K k2, V v2, K k3, V v3) {
     return ImmutableListMultimap.of(k1v1k2v2k3v3);
   }

  
Returns an immutable multimap containing the given entries, in order.
 
   public static <K, V> ImmutableMultimap<K, V> of(
      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4) {
    return ImmutableListMultimap.of(k1v1k2v2k3v3k4v4);
  }

  
Returns an immutable multimap containing the given entries, in order.
  public static <K, V> ImmutableMultimap<K, V> of(
      K k1, V v1, K k2, V v2, K k3, V v3, K k4, V v4, K k5, V v5) {
    return ImmutableListMultimap.of(k1v1k2v2k3v3k4v4k5v5);
  }
  // looking for of() with > 5 entries? Use the builder instead.

  
Returns a new builder. The generated builder is equivalent to the builder created by the ImmutableMultimap.Builder constructor.
  public static <K, V> Builder<K, V> builder() {
    return new Builder<K, V>();
  }

  
Multimap for ImmutableMultimap.Builder that maintains key and value orderings, allows duplicate values, and performs better than LinkedListMultimap.
  private static class BuilderMultimap<K, V> extends AbstractMultimap<K, V> {
    BuilderMultimap() {
      super(new LinkedHashMap<K, Collection<V>>());
    }
      return Lists.newArrayList();
    }
    private static final long serialVersionUID = 0;
  }

  
A builder for creating immutable multimap instances, especially public static final multimaps ("constant multimaps"). Example:
   static final Multimap<String, Integer> STRING_TO_INTEGER_MULTIMAP =
       new ImmutableMultimap.Builder<String, Integer>()
           .put("one", 1)
           .putAll("several", 1, 2, 3)
           .putAll("many", 1, 2, 3, 4, 5)
           .build();
Builder instances can be reused; it is safe to call build() multiple times to build multiple multimaps in series. Each multimap contains the key-value mappings in the previously created multimaps.

Since:
2.0 (imported from Google Collections Library)
  public static class Builder<K, V> {
    Multimap<K, V> builderMultimap = new BuilderMultimap<K, V>();
    Comparator<? super K> keyComparator;
    Comparator<? super V> valueComparator;

    
Creates a new builder. The returned builder is equivalent to the builder generated by ImmutableMultimap.builder().
    public Builder() {}

    
Adds a key-value mapping to the built multimap.
    public Builder<K, V> put(K key, V value) {
      .put(checkNotNull(key), checkNotNull(value));
      return this;
    }

    
Adds an entry to the built multimap.

Since:
11.0
    public Builder<K, V> put(Entry<? extends K, ? extends V> entry) {
      .put(
          checkNotNull(entry.getKey()), checkNotNull(entry.getValue()));
      return this;
    }

    
Stores a collection of values with the same key in the built multimap.

Throws:
java.lang.NullPointerException if key, values, or any element in values is null. The builder is left in an invalid state.
    public Builder<K, V> putAll(K keyIterable<? extends V> values) {
      Collection<V> valueList = .get(checkNotNull(key));
      for (V value : values) {
        valueList.add(checkNotNull(value));
      }
      return this;
    }

    
Stores an array of values with the same key in the built multimap.

Throws:
java.lang.NullPointerException if the key or any value is null. The builder is left in an invalid state.
    public Builder<K, V> putAll(K key, V... values) {
      return putAll(key, Arrays.asList(values));
    }

    
Stores another multimap's entries in the built multimap. The generated multimap's key and value orderings correspond to the iteration ordering of the multimap.asMap() view, with new keys and values following any existing keys and values.

Throws:
java.lang.NullPointerException if any key or value in multimap is null. The builder is left in an invalid state.
    public Builder<K, V> putAll(Multimap<? extends K, ? extends V> multimap) {
      for (Entry<? extends K, ? extends Collection<? extends V>> entry
          : multimap.asMap().entrySet()) {
        putAll(entry.getKey(), entry.getValue());
      }
      return this;
    }

    
Specifies the ordering of the generated multimap's keys.

Since:
8.0
    @Beta
    public Builder<K, V> orderKeysBy(Comparator<? super K> keyComparator) {
      this. = checkNotNull(keyComparator);
      return this;
    }

    
Specifies the ordering of the generated multimap's values for each key.

Since:
8.0
    @Beta
    public Builder<K, V> orderValuesBy(Comparator<? super V> valueComparator) {
      this. = checkNotNull(valueComparator);
      return this;
    }

    
Returns a newly-created immutable multimap.
    public ImmutableMultimap<K, V> build() {
      if ( != null) {
        for (Collection<V> values : .asMap().values()) {
          List<V> list = (List <V>) values;
          Collections.sort(list);
        }
      }
      if ( != null) {
        Multimap<K, V> sortedCopy = new BuilderMultimap<K, V>();
        List<Map.Entry<K, Collection<V>>> entries = Lists.newArrayList(
            .asMap().entrySet());
        Collections.sort(
            entries,
            Ordering.from().onResultOf(new Function<Entry<K, Collection<V>>, K>() {
              @Override
              public K apply(Entry<K, Collection<V>> entry) {
                return entry.getKey();
              }
            }));
        for (Map.Entry<K, Collection<V>> entry : entries) {
          sortedCopy.putAll(entry.getKey(), entry.getValue());
        }
         = sortedCopy;
      }
      return copyOf();
    }
  }

  
Returns an immutable multimap containing the same mappings as multimap. The generated multimap's key and value orderings correspond to the iteration ordering of the multimap.asMap() view.

Despite the method name, this method attempts to avoid actually copying the data when it is safe to do so. The exact circumstances under which a copy will or will not be performed are undocumented and subject to change.

Throws:
java.lang.NullPointerException if any key or value in multimap is null
  public static <K, V> ImmutableMultimap<K, V> copyOf(
      Multimap<? extends K, ? extends V> multimap) {
    if (multimap instanceof ImmutableMultimap) {
      @SuppressWarnings("unchecked"// safe since multimap is not writable
      ImmutableMultimap<K, V> kvMultimap
          = (ImmutableMultimap<K, V>) multimap;
      if (!kvMultimap.isPartialView()) {
        return kvMultimap;
      }
    }
    return ImmutableListMultimap.copyOf(multimap);
  }
  final transient ImmutableMap<K, ? extends ImmutableCollection<V>> map;
  final transient int size;
  // These constants allow the deserialization code to set final fields. This
  // holder class makes sure they are not initialized unless an instance is
  // deserialized.
  @GwtIncompatible("java serialization is not supported")
  static class FieldSettersHolder {
        MAP_FIELD_SETTER = Serialization.getFieldSetter(
        ImmutableMultimap.class"map");
        SIZE_FIELD_SETTER = Serialization.getFieldSetter(
        ImmutableMultimap.class"size");
  }
      int size) {
    this. = map;
    this. = size;
  }
  // mutators (not supported)

  
Guaranteed to throw an exception and leave the multimap unmodified.

  public ImmutableCollection<V> removeAll(Object key) {
    throw new UnsupportedOperationException();
  }

  
Guaranteed to throw an exception and leave the multimap unmodified.

  public ImmutableCollection<V> replaceValues(K key,
      Iterable<? extends V> values) {
    throw new UnsupportedOperationException();
  }

  
Guaranteed to throw an exception and leave the multimap unmodified.

  public void clear() {
    throw new UnsupportedOperationException();
  }

  
Returns an immutable collection of the values for the given key. If no mappings in the multimap have the provided key, an empty immutable collection is returned. The values are in the same order as the parameters used to build this multimap.
  public abstract ImmutableCollection<V> get(K key);

  
Returns an immutable multimap which is the inverse of this one. For every key-value mapping in the original, the result will have a mapping with key and value reversed.

Since:
11.0
  @Beta
  public abstract ImmutableMultimap<V, K> inverse();

  
Guaranteed to throw an exception and leave the multimap unmodified.

  public boolean put(K key, V value) {
    throw new UnsupportedOperationException();
  }

  
Guaranteed to throw an exception and leave the multimap unmodified.

  public boolean putAll(K keyIterable<? extends V> values) {
    throw new UnsupportedOperationException();
  }

  
Guaranteed to throw an exception and leave the multimap unmodified.

  public boolean putAll(Multimap<? extends K, ? extends V> multimap) {
    throw new UnsupportedOperationException();
  }

  
Guaranteed to throw an exception and leave the multimap unmodified.

  public boolean remove(Object keyObject value) {
    throw new UnsupportedOperationException();
  }
  boolean isPartialView() {
    return .isPartialView();
  }
  // accessors
  public boolean containsEntry(@Nullable Object key, @Nullable Object value) {
    Collection<V> values = .get(key);
    return values != null && values.contains(value);
  }
  public boolean containsKey(@Nullable Object key) {
    return .containsKey(key);
  }
  public boolean containsValue(@Nullable Object value) {
    for (Collection<V> valueCollection : .values()) {
      if (valueCollection.contains(value)) {
        return true;
      }
    }
    return false;
  }
  public boolean isEmpty() {
    return  == 0;
  }
  public int size() {
    return ;
  }
  @Override public boolean equals(@Nullable Object object) {
    if (object instanceof Multimap) {
      Multimap<?, ?> that = (Multimap<?, ?>) object;
      return this..equals(that.asMap());
    }
    return false;
  }
  @Override public int hashCode() {
    return .hashCode();
  }
  @Override public String toString() {
    return .toString();
  }
  // views

  
Returns an immutable set of the distinct keys in this multimap. These keys are ordered according to when they first appeared during the construction of this multimap.
  public ImmutableSet<K> keySet() {
    return .keySet();
  }

  
Returns an immutable map that associates each key with its corresponding values in the multimap.
  @SuppressWarnings("unchecked"// a widening cast
  public ImmutableMap<K, Collection<V>> asMap() {
    return (ImmutableMap;
  }
  private transient ImmutableCollection<Entry<K, V>> entries;

  
Returns an immutable collection of all key-value pairs in the multimap. Its iterator traverses the values for the first key, the values for the second key, and so on.
  public ImmutableCollection<Entry<K, V>> entries() {
    ImmutableCollection<Entry<K, V>> result = ;
    return (result == null)
        ? ( = new EntryCollection<K, V>(this)) : result;
  }
  private static class EntryCollection<K, V>
      extends ImmutableCollection<Entry<K, V>> {
    final ImmutableMultimap<K, V> multimap;
    EntryCollection(ImmutableMultimap<K, V> multimap) {
      this. = multimap;
    }
    @Override public UnmodifiableIterator<Entry<K, V>> iterator() {
      final Iterator<? extends Entry<K, ? extends ImmutableCollection<V>>>
          mapIterator = this...entrySet().iterator();
      return new UnmodifiableIterator<Entry<K, V>>() {
        K key;
        Iterator<V> valueIterator;
        @Override
        public boolean hasNext() {
          return ( != null && .hasNext())
              || mapIterator.hasNext();
        }
        @Override
        public Entry<K, V> next() {
          if ( == null || !.hasNext()) {
            Entry<K, ? extends ImmutableCollection<V>> entry
                = mapIterator.next();
             = entry.getKey();
             = entry.getValue().iterator();
          }
          return Maps.immutableEntry(.next());
        }
      };
    }
    @Override boolean isPartialView() {
      return .isPartialView();
    }
    @Override
    public int size() {
      return .size();
    }
    @Override public boolean contains(Object object) {
      if (object instanceof Entry) {
        Entry<?, ?> entry = (Entry<?, ?>) object;
        return .containsEntry(entry.getKey(), entry.getValue());
      }
      return false;
    }
    private static final long serialVersionUID = 0;
  }
  private transient ImmutableMultiset<K> keys;

  
Returns a collection, which may contain duplicates, of all keys. The number of times a key appears in the returned multiset equals the number of mappings the key has in the multimap. Duplicate keys appear consecutively in the multiset's iteration order.
  public ImmutableMultiset<K> keys() {
    ImmutableMultiset<K> result = ;
    return (result == null) ? ( = createKeys()) : result;
  }
  private ImmutableMultiset<K> createKeys() {
    return new Keys();
  }
  @SuppressWarnings("serial"// Uses writeReplace, not default serialization
  class Keys extends ImmutableMultiset<K> {
    @Override
    public boolean contains(@Nullable Object object) {
      return containsKey(object);
    }
    @Override
    public int count(@Nullable Object element) {
      Collection<V> values = .get(element);
      return (values == null) ? 0 : values.size();
    }
    @Override
    public Set<K> elementSet() {
      return keySet();
    }
    @Override
    public int size() {
      return ImmutableMultimap.this.size();
    }
    @Override
      return new KeysEntrySet();
    }
    private class KeysEntrySet extends ImmutableMultiset<K>.EntrySet {
      @Override
      public int size() {
        return keySet().size();
      }
      @Override
      public UnmodifiableIterator<Entry<K>> iterator() {
        return asList().iterator();
      }
      @Override
      ImmutableList<Entry<K>> createAsList() {
        final ImmutableList<? extends Map.Entry<K, ? extends Collection<V>>> mapEntries =
            .entrySet().asList();
        return new ImmutableAsList<Entry<K>>() {
          @Override
          public Entry<K> get(int index) {
            Map.Entry<K, ? extends Collection<V>> entry = mapEntries.get(index);
            return Multisets.immutableEntry(entry.getKey(), entry.getValue().size());
          }
          @Override
          ImmutableCollection<Entry<K>> delegateCollection() {
            return KeysEntrySet.this;
          }
        };
      }
    }
    @Override
    boolean isPartialView() {
      return true;
    }
  }
  private transient ImmutableCollection<V> values;

  
Returns an immutable collection of the values in this multimap. Its iterator traverses the values for the first key, the values for the second key, and so on.
  public ImmutableCollection<V> values() {
    ImmutableCollection<V> result = ;
    return (result == null) ? ( = new Values<V>(this)) : result;
  }
  private static class Values<V> extends ImmutableCollection<V> {
    final ImmutableMultimap<?, V> multimap;
    Values(ImmutableMultimap<?, V> multimap) {
      this. = multimap;
    }
    @Override public UnmodifiableIterator<V> iterator() {
      return Maps.valueIterator(.entries().iterator());
    }
    @Override
    public int size() {
      return .size();
    }
    @Override boolean isPartialView() {
      return true;
    }
    private static final long serialVersionUID = 0;
  }
  private static final long serialVersionUID = 0;
New to GrepCode? Check out our FAQ X