All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.google.common.collect.MultimapBuilder Maven / Gradle / Ivy

Go to download

This artifact provides a single jar that contains all classes required to use remote EJB and JMS, including all dependencies. It is intended for use by those not using maven, maven users should just import the EJB and JMS BOM's instead (shaded JAR's cause lots of problems with maven, as it is very easy to inadvertently end up with different versions on classes on the class path).

There is a newer version: 34.0.0.Final
Show newest version
/*
 * Copyright (C) 2013 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.collect.CollectPreconditions.checkNonnegative;

import com.google.common.annotations.GwtCompatible;
import com.google.common.base.Supplier;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Comparator;
import java.util.EnumMap;
import java.util.EnumSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.SortedSet;
import java.util.TreeMap;
import java.util.TreeSet;
import org.checkerframework.checker.nullness.qual.Nullable;

/**
 * A builder for a multimap implementation that allows customization of the backing map and value
 * collection implementations used in a particular multimap.
 *
 * 

This can be used to easily configure multimap data structure implementations not provided * explicitly in {@code com.google.common.collect}, for example: * *

{@code
 * ListMultimap treeListMultimap =
 *     MultimapBuilder.treeKeys().arrayListValues().build();
 * SetMultimap hashEnumMultimap =
 *     MultimapBuilder.hashKeys().enumSetValues(MyEnum.class).build();
 * }
* *

{@code MultimapBuilder} instances are immutable. Invoking a configuration method has no effect * on the receiving instance; you must store and use the new builder instance it returns instead. * *

The generated multimaps are serializable if the key and value types are serializable, unless * stated otherwise in one of the configuration methods. * * @author Louis Wasserman * @param An upper bound on the key type of the generated multimap. * @param An upper bound on the value type of the generated multimap. * @since 16.0 */ @GwtCompatible @ElementTypesAreNonnullByDefault public abstract class MultimapBuilder { /* * Leaving K and V as upper bounds rather than the actual key and value types allows type * parameters to be left implicit more often. CacheBuilder uses the same technique. */ private MultimapBuilder() {} private static final int DEFAULT_EXPECTED_KEYS = 8; /** Uses a hash table to map keys to value collections. */ public static MultimapBuilderWithKeys<@Nullable Object> hashKeys() { return hashKeys(DEFAULT_EXPECTED_KEYS); } /** * Uses a hash table to map keys to value collections, initialized to expect the specified number * of keys. * * @throws IllegalArgumentException if {@code expectedKeys < 0} */ public static MultimapBuilderWithKeys<@Nullable Object> hashKeys(int expectedKeys) { checkNonnegative(expectedKeys, "expectedKeys"); return new MultimapBuilderWithKeys<@Nullable Object>() { @Override Map> createMap() { return Platform.newHashMapWithExpectedSize(expectedKeys); } }; } /** * Uses a hash table to map keys to value collections. * *

The collections returned by {@link Multimap#keySet()}, {@link Multimap#keys()}, and {@link * Multimap#asMap()} will iterate through the keys in the order that they were first added to the * multimap, save that if all values associated with a key are removed and then the key is added * back into the multimap, that key will come last in the key iteration order. */ public static MultimapBuilderWithKeys<@Nullable Object> linkedHashKeys() { return linkedHashKeys(DEFAULT_EXPECTED_KEYS); } /** * Uses an hash table to map keys to value collections, initialized to expect the specified number * of keys. * *

The collections returned by {@link Multimap#keySet()}, {@link Multimap#keys()}, and {@link * Multimap#asMap()} will iterate through the keys in the order that they were first added to the * multimap, save that if all values associated with a key are removed and then the key is added * back into the multimap, that key will come last in the key iteration order. */ public static MultimapBuilderWithKeys<@Nullable Object> linkedHashKeys(int expectedKeys) { checkNonnegative(expectedKeys, "expectedKeys"); return new MultimapBuilderWithKeys<@Nullable Object>() { @Override Map> createMap() { return Platform.newLinkedHashMapWithExpectedSize(expectedKeys); } }; } /** * Uses a naturally-ordered {@link TreeMap} to map keys to value collections. * *

The collections returned by {@link Multimap#keySet()}, {@link Multimap#keys()}, and {@link * Multimap#asMap()} will iterate through the keys in sorted order. * *

For all multimaps generated by the resulting builder, the {@link Multimap#keySet()} can be * safely cast to a {@link java.util.SortedSet}, and the {@link Multimap#asMap()} can safely be * cast to a {@link java.util.SortedMap}. */ @SuppressWarnings("rawtypes") public static MultimapBuilderWithKeys treeKeys() { return treeKeys(Ordering.natural()); } /** * Uses a {@link TreeMap} sorted by the specified comparator to map keys to value collections. * *

The collections returned by {@link Multimap#keySet()}, {@link Multimap#keys()}, and {@link * Multimap#asMap()} will iterate through the keys in sorted order. * *

For all multimaps generated by the resulting builder, the {@link Multimap#keySet()} can be * safely cast to a {@link java.util.SortedSet}, and the {@link Multimap#asMap()} can safely be * cast to a {@link java.util.SortedMap}. * *

Multimaps generated by the resulting builder will not be serializable if {@code comparator} * is not serializable. */ public static MultimapBuilderWithKeys treeKeys( Comparator comparator) { checkNotNull(comparator); return new MultimapBuilderWithKeys() { @Override Map> createMap() { return new TreeMap<>(comparator); } }; } /** * Uses an {@link EnumMap} to map keys to value collections. * * @since 16.0 */ public static > MultimapBuilderWithKeys enumKeys(Class keyClass) { checkNotNull(keyClass); return new MultimapBuilderWithKeys() { @SuppressWarnings("unchecked") @Override Map> createMap() { // K must actually be K0, since enums are effectively final // (their subclasses are inaccessible) return (Map>) new EnumMap>(keyClass); } }; } private static final class ArrayListSupplier implements Supplier>, Serializable { private final int expectedValuesPerKey; ArrayListSupplier(int expectedValuesPerKey) { this.expectedValuesPerKey = checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); } @Override public List get() { return new ArrayList<>(expectedValuesPerKey); } } private enum LinkedListSupplier implements Supplier> { INSTANCE; public static Supplier> instance() { // Each call generates a fresh LinkedList, which can serve as a List for any V. @SuppressWarnings({"rawtypes", "unchecked"}) Supplier> result = (Supplier) INSTANCE; return result; } @Override public List get() { return new LinkedList<>(); } } private static final class HashSetSupplier implements Supplier>, Serializable { private final int expectedValuesPerKey; HashSetSupplier(int expectedValuesPerKey) { this.expectedValuesPerKey = checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); } @Override public Set get() { return Platform.newHashSetWithExpectedSize(expectedValuesPerKey); } } private static final class LinkedHashSetSupplier implements Supplier>, Serializable { private final int expectedValuesPerKey; LinkedHashSetSupplier(int expectedValuesPerKey) { this.expectedValuesPerKey = checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); } @Override public Set get() { return Platform.newLinkedHashSetWithExpectedSize(expectedValuesPerKey); } } private static final class TreeSetSupplier implements Supplier>, Serializable { private final Comparator comparator; TreeSetSupplier(Comparator comparator) { this.comparator = checkNotNull(comparator); } @Override public SortedSet get() { return new TreeSet<>(comparator); } } private static final class EnumSetSupplier> implements Supplier>, Serializable { private final Class clazz; EnumSetSupplier(Class clazz) { this.clazz = checkNotNull(clazz); } @Override public Set get() { return EnumSet.noneOf(clazz); } } /** * An intermediate stage in a {@link MultimapBuilder} in which the key-value collection map * implementation has been specified, but the value collection implementation has not. * * @param The upper bound on the key type of the generated multimap. * @since 16.0 */ public abstract static class MultimapBuilderWithKeys { private static final int DEFAULT_EXPECTED_VALUES_PER_KEY = 2; MultimapBuilderWithKeys() {} abstract Map> createMap(); /** Uses an {@link ArrayList} to store value collections. */ public ListMultimapBuilder arrayListValues() { return arrayListValues(DEFAULT_EXPECTED_VALUES_PER_KEY); } /** * Uses an {@link ArrayList} to store value collections, initialized to expect the specified * number of values per key. * * @throws IllegalArgumentException if {@code expectedValuesPerKey < 0} */ public ListMultimapBuilder arrayListValues(int expectedValuesPerKey) { checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); return new ListMultimapBuilder() { @Override public ListMultimap build() { return Multimaps.newListMultimap( MultimapBuilderWithKeys.this.createMap(), new ArrayListSupplier(expectedValuesPerKey)); } }; } /** Uses a {@link LinkedList} to store value collections. */ public ListMultimapBuilder linkedListValues() { return new ListMultimapBuilder() { @Override public ListMultimap build() { return Multimaps.newListMultimap( MultimapBuilderWithKeys.this.createMap(), LinkedListSupplier.instance()); } }; } /** Uses a hash-based {@code Set} to store value collections. */ public SetMultimapBuilder hashSetValues() { return hashSetValues(DEFAULT_EXPECTED_VALUES_PER_KEY); } /** * Uses a hash-based {@code Set} to store value collections, initialized to expect the specified * number of values per key. * * @throws IllegalArgumentException if {@code expectedValuesPerKey < 0} */ public SetMultimapBuilder hashSetValues(int expectedValuesPerKey) { checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); return new SetMultimapBuilder() { @Override public SetMultimap build() { return Multimaps.newSetMultimap( MultimapBuilderWithKeys.this.createMap(), new HashSetSupplier(expectedValuesPerKey)); } }; } /** Uses an insertion-ordered hash-based {@code Set} to store value collections. */ public SetMultimapBuilder linkedHashSetValues() { return linkedHashSetValues(DEFAULT_EXPECTED_VALUES_PER_KEY); } /** * Uses an insertion-ordered hash-based {@code Set} to store value collections, initialized to * expect the specified number of values per key. * * @throws IllegalArgumentException if {@code expectedValuesPerKey < 0} */ public SetMultimapBuilder linkedHashSetValues(int expectedValuesPerKey) { checkNonnegative(expectedValuesPerKey, "expectedValuesPerKey"); return new SetMultimapBuilder() { @Override public SetMultimap build() { return Multimaps.newSetMultimap( MultimapBuilderWithKeys.this.createMap(), new LinkedHashSetSupplier(expectedValuesPerKey)); } }; } /** Uses a naturally-ordered {@link TreeSet} to store value collections. */ @SuppressWarnings("rawtypes") public SortedSetMultimapBuilder treeSetValues() { return treeSetValues(Ordering.natural()); } /** * Uses a {@link TreeSet} ordered by the specified comparator to store value collections. * *

Multimaps generated by the resulting builder will not be serializable if {@code * comparator} is not serializable. */ public SortedSetMultimapBuilder treeSetValues( Comparator comparator) { checkNotNull(comparator, "comparator"); return new SortedSetMultimapBuilder() { @Override public SortedSetMultimap build() { return Multimaps.newSortedSetMultimap( MultimapBuilderWithKeys.this.createMap(), new TreeSetSupplier(comparator)); } }; } /** Uses an {@link EnumSet} to store value collections. */ public > SetMultimapBuilder enumSetValues(Class valueClass) { checkNotNull(valueClass, "valueClass"); return new SetMultimapBuilder() { @Override public SetMultimap build() { // V must actually be V0, since enums are effectively final // (their subclasses are inaccessible) @SuppressWarnings({"unchecked", "rawtypes"}) Supplier> factory = (Supplier) new EnumSetSupplier(valueClass); return Multimaps.newSetMultimap(MultimapBuilderWithKeys.this.createMap(), factory); } }; } } /** Returns a new, empty {@code Multimap} with the specified implementation. */ public abstract Multimap build(); /** * Returns a {@code Multimap} with the specified implementation, initialized with the entries of * {@code multimap}. */ public Multimap build( Multimap multimap) { Multimap result = build(); result.putAll(multimap); return result; } /** * A specialization of {@link MultimapBuilder} that generates {@link ListMultimap} instances. * * @since 16.0 */ public abstract static class ListMultimapBuilder< K0 extends @Nullable Object, V0 extends @Nullable Object> extends MultimapBuilder { ListMultimapBuilder() {} @Override public abstract ListMultimap build(); @Override public ListMultimap build( Multimap multimap) { return (ListMultimap) super.build(multimap); } } /** * A specialization of {@link MultimapBuilder} that generates {@link SetMultimap} instances. * * @since 16.0 */ public abstract static class SetMultimapBuilder< K0 extends @Nullable Object, V0 extends @Nullable Object> extends MultimapBuilder { SetMultimapBuilder() {} @Override public abstract SetMultimap build(); @Override public SetMultimap build( Multimap multimap) { return (SetMultimap) super.build(multimap); } } /** * A specialization of {@link MultimapBuilder} that generates {@link SortedSetMultimap} instances. * * @since 16.0 */ public abstract static class SortedSetMultimapBuilder< K0 extends @Nullable Object, V0 extends @Nullable Object> extends SetMultimapBuilder { SortedSetMultimapBuilder() {} @Override public abstract SortedSetMultimap build(); @Override public SortedSetMultimap build( Multimap multimap) { return (SortedSetMultimap) super.build(multimap); } } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy