Package com.google.gimlet.collect

Source Code of com.google.gimlet.collect.DefaultingMaps$ZeronaryFunction

/**
* Copyright (C) 2011 Google Inc.
*
* 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.gimlet.collect;

import com.google.common.base.Function;
import com.google.common.collect.ImmutableMap;
import com.google.common.collect.Lists;
import com.google.common.collect.MapMaker;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;

import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.concurrent.atomic.AtomicLong;

/**
* Provides convenience methods to create maps that use a default value when
* no value exists for a given key.
*
* @author ffaber@gmail.com (Fred Faber)
*/
public final class DefaultingMaps {
  private DefaultingMaps() { }

  private static abstract class ZeronaryFunction<T>
      implements Function<Object, T> {

    @Override
    public final T apply(Object from) {
      return create();
    }

    /** Creates something without needing any input arguments. */
    abstract T create();
  }

  private static final Function CREATE_ARRAY_LIST =
      new ZeronaryFunction<List>() {
        @Override
        List<?> create() {
          return Lists.newArrayList();
        }
      };

  /** Returns a map that uses an {@code ArrayList} as a default value. */
  @SuppressWarnings({ "unchecked" })
  public static <K, V> Map<K, List<V>> newListValuedMap() {
    return new MapMaker().makeComputingMap(
        (Function<K, List<V>>) CREATE_ARRAY_LIST);
  }

  /**
   * Converts the map into a defaulting map that uses an {@code ArrayList} as a
   * default value. Updates made to the original map, after this has been called
   * will not been seen by the returned map.
   */
  public static <K, V> Map<K, List<V>> newListValuedMap(
      Map<K, List<V>> originalMap) {
    Map<K, List<V>> newMap = newListValuedMap();
    newMap.putAll(originalMap);
    return newMap;
  }

  private static final Function CREATE_MAP =
      new ZeronaryFunction() {
        @Override
        Object create() {
          return Maps.newHashMap();
        }
      };

  /**
   * Returns a "double-keyed" map that allows one to have an empty map as a
   * default value for the outer map.
   */
  @SuppressWarnings({"unchecked"})
  public static <K1, K2, V> Map<K1, Map<K2, V>>
  newDoubleKeyedValueMap() {
    return new MapMaker().makeComputingMap(
        (Function<K1, Map<K2, V>>) CREATE_MAP);
  }

  /**
   * Returns a "double-keyed" map that uses the given defaulting function to set
   * values.
   */
  @SuppressWarnings({"unchecked"})
  public static <K1, K2, V> Map<K1, Map<K2, V>>
  newDoubleKeyedDefaultingValueMap(final Function<K2, V> defaultingFunction) {
    return new MapMaker().makeComputingMap(
        new Function<K1, Map<K2, V>>() {
          @Override
          public Map<K2, V> apply(K1 obj) {
            return new MapMaker().makeComputingMap(defaultingFunction);
          }
        });
  }

  private static final Function CREATE_LIST_VALUED_MAP =
      new ZeronaryFunction() {
        @Override
        Object create() {
          return newListValuedMap();
        }
      };

  /**
   * Returns a "double-keyed" map that uses a {@code ArrayList} as a default
   * value.
   */
  @SuppressWarnings({ "unchecked" })
  public static <K1, K2, V> Map<K1, Map<K2, List<V>>>
  newDoubleKeyedListValuedMap() {
    return new MapMaker().makeComputingMap(
        (Function<K1, Map<K2, List<V>>>) CREATE_LIST_VALUED_MAP);
  }

  private static final Function CREATE_DOUBLE_LIST_VALUED_MAP =
      new ZeronaryFunction() {
        @Override
        Object create() {
          return newDoubleKeyedListValuedMap();
        }
      };

  /**
   * Returns a "triple-keyed map" that uses a {@code ArrayList} as a default
   * value.
   */
  @SuppressWarnings({ "unchecked" })
  public static <K1, K2, K3, V> Map<K1, Map<K2, Map<K3, List<V>>>>
  newTripleKeyedListValuedMap() {
    return new MapMaker().makeComputingMap(
        (Function<K1, Map<K2, Map<K3, List<V>>>>)
            CREATE_DOUBLE_LIST_VALUED_MAP);
  }

  private static final Function CREATE_HASH_SET =
      new ZeronaryFunction<Set<?>>() {
        @Override Set<?> create() {
          return Sets.newHashSet();
        }
      };

  /** Returns a map that uses a {@code HashSet} as a default value. */
  @SuppressWarnings({ "unchecked" })
  public static <K, V> Map<K, Set<V>> newSetValuedMap() {
    return new MapMaker().makeComputingMap(
        (Function<K, Set<V>>) CREATE_HASH_SET);
  }

  @SuppressWarnings({ "unchecked" })
  public static <K> Map<K, AtomicLong> newAtomicLongValueMap() {
    return new MapMaker().makeComputingMap(
          new Function<K, AtomicLong>() {
            @Override
            public AtomicLong apply(K from) {
              return new AtomicLong(0L);
            }
          }
      );
  }

  @SuppressWarnings({ "unchecked" })
  public static <K> Map<K, AtomicInteger> newAtomicIntValuedMap() {
    return new MapMaker().makeComputingMap(
          new Function<K, AtomicInteger>() {
            @Override
            public AtomicInteger apply(K from) {
              return new AtomicInteger(0);
            }
          }
      );
  }

  public static <K> Map<K, AtomicBoolean> newAtomicBooleanValuedMap(
      final Boolean initialDefaultValue) {
    return new MapMaker().makeComputingMap(
          new Function<K, AtomicBoolean>() {
            @Override
            public AtomicBoolean apply(K from) {
              return new AtomicBoolean(initialDefaultValue);
            }
          }
      );
  }

  private static final Function CREATE_EXISTING_UNIQUE_KEY_MAP =
      new ZeronaryFunction() {
        @Override
        Object create() {
          return GimletMaps.newExistingUniqueKeyMap();
        }
      };

  /**
   * Returns a "double-keyed" map that allows one to have an empty map as a
   * default value for the outer map.  The inner maps that are returned are
   * "unique-key" maps, which follow the contract of
   * {@link GimletMaps#newExistingUniqueKeyMap()}.
   */
  @SuppressWarnings({"unchecked"})
  public static <K1, K2, V> Map<K1, Map<K2, V>>
  newExistingUniqueKeyMapValuedMap() {
    return new MapMaker().makeComputingMap(
        (Function<K1, Map<K2, V>>) CREATE_EXISTING_UNIQUE_KEY_MAP);
  }

  /**
   * Takes a set of keys, and puts them as keys into a immutable map with an
   * empty list as the value for the key. This list is mutable so that more
   * elements can be added to it.
   */
  @SuppressWarnings({"unchecked"})
  public static <K, V> ImmutableMap<K, List<V>> newSeededListValuedMap(
      Set<K> keys) {
    return newSeededMap(keys, CREATE_ARRAY_LIST);
  }

  /**
   * Takes a set of keys, and puts them as keys into a immutable map using the
   * provided function to create as the value for the key.
   */
  public static <K, V> ImmutableMap<K, V> newSeededMap(
      Set<K> keys, Function<K, V> function) {
    ImmutableMap.Builder<K, V> mapBuilder =
        ImmutableMap.builder();
    for (K key : keys) {
      mapBuilder.put(key, function.apply(key));
    }
    return mapBuilder.build();
  }
}
TOP

Related Classes of com.google.gimlet.collect.DefaultingMaps$ZeronaryFunction

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.