View Javadoc

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.collections.map;
18  
19  import java.util.Comparator;
20  import java.util.Map;
21  import java.util.SortedMap;
22  
23  import org.apache.commons.collections.Transformer;
24  
25  /**
26   * Decorates another <code>SortedMap </code> to transform objects that are added.
27   * <p>
28   * The Map put methods and Map.Entry setValue method are affected by this class.
29   * Thus objects must be removed or searched for using their transformed form.
30   * For example, if the transformation converts Strings to Integers, you must
31   * use the Integer form to remove objects.
32   * <p>
33   * <strong>Note that TransformedSortedMap is not synchronized and is not thread-safe.</strong>
34   * If you wish to use this map from multiple threads concurrently, you must use
35   * appropriate synchronization. The simplest approach is to wrap this map
36   * using {@link java.util.Collections#synchronizedSortedMap}. This class may throw 
37   * exceptions when accessed by concurrent threads without synchronization.
38   * <p>
39   * This class is Serializable from Commons Collections 3.1.
40   *
41   * @since 3.0
42   * @version $Id: TransformedSortedMap.java 1435824 2013-01-20 11:41:17Z tn $
43   */
44  public class TransformedSortedMap<K, V>
45          extends TransformedMap<K, V>
46          implements SortedMap<K, V> {
47  
48      /** Serialization version */
49      private static final long serialVersionUID = -8751771676410385778L;
50      
51      /**
52       * Factory method to create a transforming sorted map.
53       * <p>
54       * If there are any elements already in the map being decorated, they are NOT transformed.
55       * Contrast this with {@link #transformedSortedMap(SortedMap, Transformer, Transformer)}.
56       * 
57       * @param <K>  the key type
58       * @param <V>  the value type
59       * @param map  the map to decorate, must not be null
60       * @param keyTransformer  the predicate to validate the keys, null means no transformation
61       * @param valueTransformer  the predicate to validate to values, null means no transformation
62       * @return a new transformed sorted map
63       * @throws IllegalArgumentException if the map is null
64       */
65      public static <K, V> TransformedSortedMap<K, V> transformingSortedMap(final SortedMap<K, V> map,
66              final Transformer<? super K, ? extends K> keyTransformer,
67              final Transformer<? super V, ? extends V> valueTransformer) {
68          return new TransformedSortedMap<K, V>(map, keyTransformer, valueTransformer);
69      }
70  
71      /**
72       * Factory method to create a transforming sorted map that will transform
73       * existing contents of the specified map.
74       * <p>
75       * If there are any elements already in the map being decorated, they
76       * will be transformed by this method.
77       * Contrast this with {@link #transformingSortedMap(SortedMap, Transformer, Transformer)}.
78       * 
79       * @param <K>  the key type
80       * @param <V>  the value type
81       * @param map  the map to decorate, must not be null
82       * @param keyTransformer  the transformer to use for key conversion, null means no transformation
83       * @param valueTransformer  the transformer to use for value conversion, null means no transformation
84       * @return a new transformed sorted map
85       * @throws IllegalArgumentException if map is null
86       * @since 3.2
87       */
88      public static <K, V> TransformedSortedMap<K, V> transformedSortedMap(final SortedMap<K, V> map,
89              final Transformer<? super K, ? extends K> keyTransformer,
90              final Transformer<? super V, ? extends V> valueTransformer) {
91  
92          final TransformedSortedMap<K, V> decorated =
93                  new TransformedSortedMap<K, V>(map, keyTransformer, valueTransformer);
94          if (map.size() > 0) {
95              final Map<K, V> transformed = decorated.transformMap(map);
96              decorated.clear();
97              decorated.decorated().putAll(transformed);  // avoids double transformation
98          }
99          return decorated;
100     }
101 
102     //-----------------------------------------------------------------------
103     /**
104      * Constructor that wraps (not copies).
105      * <p>
106      * If there are any elements already in the collection being decorated, they
107      * are NOT transformed.</p>
108      * 
109      * @param map  the map to decorate, must not be null
110      * @param keyTransformer  the predicate to validate the keys, null means no transformation
111      * @param valueTransformer  the predicate to validate to values, null means no transformation
112      * @throws IllegalArgumentException if the map is null
113      */
114     protected TransformedSortedMap(final SortedMap<K, V> map,
115             final Transformer<? super K, ? extends K> keyTransformer,
116             final Transformer<? super V, ? extends V> valueTransformer) {
117         super(map, keyTransformer, valueTransformer);
118     }
119 
120     //-----------------------------------------------------------------------
121     /**
122      * Gets the map being decorated.
123      * 
124      * @return the decorated map
125      */
126     protected SortedMap<K, V> getSortedMap() {
127         return (SortedMap<K, V>) map;
128     }
129 
130     //-----------------------------------------------------------------------
131     public K firstKey() {
132         return getSortedMap().firstKey();
133     }
134 
135     public K lastKey() {
136         return getSortedMap().lastKey();
137     }
138 
139     public Comparator<? super K> comparator() {
140         return getSortedMap().comparator();
141     }
142 
143     public SortedMap<K, V> subMap(final K fromKey, final K toKey) {
144         final SortedMap<K, V> map = getSortedMap().subMap(fromKey, toKey);
145         return new TransformedSortedMap<K, V>(map, keyTransformer, valueTransformer);
146     }
147 
148     public SortedMap<K, V> headMap(final K toKey) {
149         final SortedMap<K, V> map = getSortedMap().headMap(toKey);
150         return new TransformedSortedMap<K, V>(map, keyTransformer, valueTransformer);
151     }
152 
153     public SortedMap<K, V> tailMap(final K fromKey) {
154         final SortedMap<K, V> map = getSortedMap().tailMap(fromKey);
155         return new TransformedSortedMap<K, V>(map, keyTransformer, valueTransformer);
156     }
157 
158 }