/* * Copyright (c) 2014 the original author or 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 io.werval.util; import java.util.Comparator; import java.util.HashMap; import java.util.IdentityHashMap; import java.util.LinkedHashMap; import java.util.List; import java.util.Map; import java.util.TreeMap; import java.util.WeakHashMap; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentSkipListMap; /** * Maps Utilities. * * @navassoc 1 create * MapBuilder */ public final class Maps { /** * Map Builder. * * @param <M> Map parameterized type * @param <K> Key parameterized type * @param <V> Value parameterized type * * @navassoc 1 create * Map */ public interface MapBuilder<M extends Map<K, V>, K, V> { /** * Associates the specified value with the specified key in this map. * * If the map previously contained a mapping for the key, the old value is replaced by the specified value. * * @param key The key * @param value The value * * @return The builder for fluent usage */ MapBuilder<M, K, V> put( K key, V value ); /** * Build the Map. * * @return The built MapĀ· */ M toMap(); } /** * MultiValueMap Builder. * * @param <M> Map parameterized type * @param <K> Key parameterized type * @param <V> Value parameterized type * * @navassoc 1 create * MultiValueMap */ public interface MultiValueMapBuilder<M extends Map<K, List<V>>, K, V> extends MapBuilder<M, K, List<V>> { /** * Associates the specified values with the specified key in this map. * * If the map previously contained a mapping for the key, the old values are replaced by the specified values. * * @param key The key * @param values The List of values * * @return The builder for fluent usage */ @Override MultiValueMapBuilder<M, K, V> put( K key, List<V> values ); /** * Add the specified values to the List associated with the specified key in this map. * * @param key The key * @param value A value * @param moreValues More values * * @return The builder for fluent usage */ MultiValueMapBuilder<M, K, V> add( K key, V value, V... moreValues ); } /** * Create a Map Builder starting with an empty HashMap. * * @param <K> Key parameterized type * @param <V> Value parameterized type * @param kClass Key Class * @param vClass Value Class * * @return The Map Builder started with an empty HashMap. */ public static <K, V> MapBuilder<HashMap<K, V>, K, V> newHashMap( Class<? super K> kClass, Class<? super V> vClass ) { return fromMap( new HashMap<K, V>() ); } /** * Create a Map Builder starting with an empty LinkedHashMap. * * @param <K> Key parameterized type * @param <V> Value parameterized type * @param kClass Key Class * @param vClass Value Class * * @return The Map Builder started with an empty LinkedHashMap. */ public static <K, V> MapBuilder<LinkedHashMap<K, V>, K, V> newLinkedHashMap( Class<? super K> kClass, Class<? super V> vClass ) { return fromMap( new LinkedHashMap<K, V>() ); } /** * Create a Map Builder starting with an empty ConcurrentHashMap. * * @param <K> Key parameterized type * @param <V> Value parameterized type * @param kClass Key Class * @param vClass Value Class * * @return The Map Builder started with an empty ConcurrentHashMap. */ public static <K, V> MapBuilder<ConcurrentHashMap<K, V>, K, V> newConcurrentHashMap( Class<? super K> kClass, Class<? super V> vClass ) { return fromMap( new ConcurrentHashMap<K, V>() ); } /** * Create a Map Builder starting with an empty ConcurrentSkipListMap. * * @param <K> Key parameterized type * @param <V> Value parameterized type * @param kClass Key Class * @param vClass Value Class * * @return The Map Builder started with an empty ConcurrentSkipListMap. */ public static <K, V> MapBuilder<ConcurrentSkipListMap<K, V>, K, V> newConcurrentSkipListMap( Class<? super K> kClass, Class<? super V> vClass ) { return fromMap( new ConcurrentSkipListMap<K, V>() ); } /** * Create a Map Builder starting with an empty ConcurrentSkipListMap. * * @param <K> Key parameterized type * @param <V> Value parameterized type * @param kClass Key Class * @param vClass Value Class * @param comparator The comparator that will be used to order this map. * If null, the natural ordering of the keys will be used. * * @return The Map Builder started with an empty ConcurrentSkipListMap. */ public static <K, V> MapBuilder<ConcurrentSkipListMap<K, V>, K, V> newConcurrentSkipListMap( Class<? super K> kClass, Class<? super V> vClass, Comparator<? super K> comparator ) { return fromMap( new ConcurrentSkipListMap<K, V>( comparator ) ); } /** * Create a Map Builder starting with an empty IdentityHashMap. * * @param <K> Key parameterized type * @param <V> Value parameterized type * @param kClass Key Class * @param vClass Value Class * * @return The Map Builder started with an empty IdentityHashMap. */ public static <K, V> MapBuilder<IdentityHashMap<K, V>, K, V> newIdentityHashMap( Class<? super K> kClass, Class<? super V> vClass ) { return fromMap( new IdentityHashMap<K, V>() ); } /** * Create a Map Builder starting with an empty WeakHashMap. * * @param <K> Key parameterized type * @param <V> Value parameterized type * @param kClass Key Class * @param vClass Value Class * * @return The Map Builder started with an empty WeakHashMap. */ public static <K, V> MapBuilder<WeakHashMap<K, V>, K, V> newWeakHashMap( Class<? super K> kClass, Class<? super V> vClass ) { return fromMap( new WeakHashMap<K, V>() ); } /** * Create a Map Builder starting with an empty TreeMap. * * @param <K> Key parameterized type * @param <V> Value parameterized type * @param kClass Key Class * @param vClass Value Class * * @return The Map Builder started with an empty TreeMap. */ public static <K, V> MapBuilder<TreeMap<K, V>, K, V> newTreeMap( Class<? super K> kClass, Class<? super V> vClass ) { return fromMap( new TreeMap<K, V>() ); } /** * Create a Map Builder starting with an empty TreeMap. * * @param <K> Key parameterized type * @param <V> Value parameterized type * @param kClass Key Class * @param vClass Value Class * @param comparator The comparator that will be used to order this map. * If null, the natural ordering of the keys will be used. * * @return The Map Builder started with an empty TreeMap. */ public static <K, V> MapBuilder<TreeMap<K, V>, K, V> newTreeMap( Class<? super K> kClass, Class<? super V> vClass, Comparator<? super K> comparator ) { return fromMap( new TreeMap<K, V>( comparator ) ); } /** * Create a MultiValueMap Builder starting with an empty LinkedMultiValueMap. * * @param <K> Key parameterized type * @param <V> Value parameterized type * @param kClass Key Class * @param vClass Value Class * * @return The MultiValueMap Builder started with an empty LinkedMultiValueMap */ public static <K, V> MultiValueMapBuilder<LinkedMultiValueMap<K, V>, K, V> newLinkedMultiValueMap( Class<? super K> kClass, Class<? super V> vClass ) { return fromMap( new LinkedMultiValueMap<K, V>() ); } /** * Create a MultiValueMap Builder starting with an empty TreeMultiValueMap. * * @param <K> Key parameterized type * @param <V> Value parameterized type * @param kClass Key Class * @param vClass Value Class * * @return The MultiValueMap Builder started with an empty TreeMultiValueMap */ public static <K, V> MultiValueMapBuilder<TreeMultiValueMap<K, V>, K, V> newTreeMultiValueMap( Class<? super K> kClass, Class<? super V> vClass ) { return fromMap( new TreeMultiValueMap<K, V>() ); } /** * Create a Map Builder starting with a given Map. * * @param <M> Map parameterized type * @param <K> Key parameterized type * @param <V> Value parameterized type * * @param map The Map the Builder will use * * @return The Map Builder started with the given Map */ public static <M extends Map<K, V>, K, V> MapBuilder<M, K, V> fromMap( M map ) { return new MapBuilderImpl<>( map ); } /** * Create a MultiValueMap Builder starting with a given MultiValueMap. * * @param <M> Map parameterized type * @param <K> Key parameterized type * @param <V> Value parameterized type * @param map The MultiValueMap the Builder will use * * @return The MultiValueMap Builder started with the given MultiValueMap */ public static <M extends MultiValueMap<K, V>, K, V> MultiValueMapBuilder<M, K, V> fromMap( M map ) { return new MultiValueMapBuilderImpl<>( map ); } private static class MapBuilderImpl<M extends Map<K, V>, K, V> implements MapBuilder<M, K, V> { protected final M map; private MapBuilderImpl( M map ) { this.map = map; } @Override public MapBuilder<M, K, V> put( K key, V value ) { map.put( key, value ); return this; } @Override public M toMap() { return map; } } private static final class MultiValueMapBuilderImpl<M extends MultiValueMap<K, V>, K, V> extends MapBuilderImpl<M, K, List<V>> implements MultiValueMapBuilder<M, K, V> { private MultiValueMapBuilderImpl( M map ) { super( map ); } @Override public MultiValueMapBuilder<M, K, V> add( K key, V value, V... moreValues ) { map.add( key, value, moreValues ); return this; } @Override public MultiValueMapBuilder<M, K, V> put( K key, List<V> values ) { map.put( key, values ); return this; } @Override public M toMap() { return map; } } /** * Returns an unmodifiable view of the specified MultiValueMap. * * @param <K> Parameterized type of the MultiValueMap keys * @param <V> Parameterized type of the MultiValueMap values * @param mvmap The MultiValueMap for which an unmodifiable view is to be returned. * * @return An unmodifiable view of the specified MultiValueMap. */ public static <K, V> MultiValueMap<K, V> unmodifiableMultiValueMap( MultiValueMap<? extends K, ? extends V> mvmap ) { return new UnmodifiableMultiValueMap<>( mvmap ); } private Maps() { } }