PredicatedSortedMap.java

  1. /*
  2.  * Licensed to the Apache Software Foundation (ASF) under one or more
  3.  * contributor license agreements.  See the NOTICE file distributed with
  4.  * this work for additional information regarding copyright ownership.
  5.  * The ASF licenses this file to You under the Apache License, Version 2.0
  6.  * (the "License"); you may not use this file except in compliance with
  7.  * the License.  You may obtain a copy of the License at
  8.  *
  9.  *      http://www.apache.org/licenses/LICENSE-2.0
  10.  *
  11.  * Unless required by applicable law or agreed to in writing, software
  12.  * distributed under the License is distributed on an "AS IS" BASIS,
  13.  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  14.  * See the License for the specific language governing permissions and
  15.  * limitations under the License.
  16.  */
  17. package org.apache.commons.collections4.map;

  18. import java.util.Comparator;
  19. import java.util.SortedMap;

  20. import org.apache.commons.collections4.Predicate;

  21. /**
  22.  * Decorates another {@code SortedMap} to validate that additions
  23.  * match a specified predicate.
  24.  * <p>
  25.  * This map exists to provide validation for the decorated map.
  26.  * It is normally created to decorate an empty map.
  27.  * If an object cannot be added to the map, an IllegalArgumentException is thrown.
  28.  * </p>
  29.  * <p>
  30.  * One usage would be to ensure that no null keys are added to the map.
  31.  * </p>
  32.  * <pre>
  33.  *   SortedMap map =
  34.  *     PredicatedSortedMap.predicatedSortedMap(new TreeMap(),
  35.  *                                             NotNullPredicate.notNullPredicate(),
  36.  *                                             null);
  37.  * </pre>
  38.  * <p>
  39.  * <strong>Note that PredicatedSortedMap is not synchronized and is not thread-safe.</strong>
  40.  * If you wish to use this map from multiple threads concurrently, you must use
  41.  * appropriate synchronization. The simplest approach is to wrap this map
  42.  * using {@link java.util.Collections#synchronizedSortedMap}. This class may throw
  43.  * exceptions when accessed by concurrent threads without synchronization.
  44.  * </p>
  45.  * <p>
  46.  * This class is Serializable from Commons Collections 3.1.
  47.  * </p>
  48.  *
  49.  * @param <K> the type of the keys in this map
  50.  * @param <V> the type of the values in this map
  51.  * @since 3.0
  52.  */
  53. public class PredicatedSortedMap<K, V> extends PredicatedMap<K, V> implements SortedMap<K, V> {

  54.     /** Serialization version */
  55.     private static final long serialVersionUID = 3359846175935304332L;

  56.     /**
  57.      * Factory method to create a predicated (validating) sorted map.
  58.      * <p>
  59.      * If there are any elements already in the list being decorated, they
  60.      * are validated.
  61.      * </p>
  62.      *
  63.      * @param <K>  the key type
  64.      * @param <V>  the value type
  65.      * @param map  the map to decorate, must not be null
  66.      * @param keyPredicate  the predicate to validate the keys, null means no check
  67.      * @param valuePredicate  the predicate to validate to values, null means no check
  68.      * @return a new predicated sorted map
  69.      * @throws NullPointerException if the map is null
  70.      * @since 4.0
  71.      */
  72.     public static <K, V> PredicatedSortedMap<K, V> predicatedSortedMap(final SortedMap<K, V> map,
  73.             final Predicate<? super K> keyPredicate, final Predicate<? super V> valuePredicate) {
  74.         return new PredicatedSortedMap<>(map, keyPredicate, valuePredicate);
  75.     }

  76.     /**
  77.      * Constructor that wraps (not copies).
  78.      *
  79.      * @param map  the map to decorate, must not be null
  80.      * @param keyPredicate  the predicate to validate the keys, null means no check
  81.      * @param valuePredicate  the predicate to validate to values, null means no check
  82.      * @throws NullPointerException if the map is null
  83.      */
  84.     protected PredicatedSortedMap(final SortedMap<K, V> map, final Predicate<? super K> keyPredicate,
  85.             final Predicate<? super V> valuePredicate) {
  86.         super(map, keyPredicate, valuePredicate);
  87.     }

  88.     @Override
  89.     public Comparator<? super K> comparator() {
  90.         return getSortedMap().comparator();
  91.     }

  92.     @Override
  93.     public K firstKey() {
  94.         return getSortedMap().firstKey();
  95.     }

  96.     /**
  97.      * Gets the map being decorated.
  98.      *
  99.      * @return the decorated map
  100.      */
  101.     protected SortedMap<K, V> getSortedMap() {
  102.         return (SortedMap<K, V>) map;
  103.     }

  104.     @Override
  105.     public SortedMap<K, V> headMap(final K toKey) {
  106.         final SortedMap<K, V> map = getSortedMap().headMap(toKey);
  107.         return new PredicatedSortedMap<>(map, keyPredicate, valuePredicate);
  108.     }

  109.     @Override
  110.     public K lastKey() {
  111.         return getSortedMap().lastKey();
  112.     }

  113.     @Override
  114.     public SortedMap<K, V> subMap(final K fromKey, final K toKey) {
  115.         final SortedMap<K, V> map = getSortedMap().subMap(fromKey, toKey);
  116.         return new PredicatedSortedMap<>(map, keyPredicate, valuePredicate);
  117.     }

  118.     @Override
  119.     public SortedMap<K, V> tailMap(final K fromKey) {
  120.         final SortedMap<K, V> map = getSortedMap().tailMap(fromKey);
  121.         return new PredicatedSortedMap<>(map, keyPredicate, valuePredicate);
  122.     }

  123. }