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.SortedMap;
21
22 import org.apache.commons.collections.Factory;
23 import org.apache.commons.collections.Transformer;
24
25 /**
26 * Decorates another <code>SortedMap</code> to create objects in the map on demand.
27 * <p>
28 * When the {@link #get(Object)} method is called with a key that does not
29 * exist in the map, the factory is used to create the object. The created
30 * object will be added to the map using the requested key.
31 * <p>
32 * For instance:
33 * <pre>
34 * Factory<Date> factory = new Factory<Date>() {
35 * public Date create() {
36 * return new Date();
37 * }
38 * }
39 * SortedMap<String, Date> lazy =
40 * LazySortedMap.lazySortedMap(new HashMap<String, Date>(), factory);
41 * Date date = lazy.get("NOW");
42 * </pre>
43 *
44 * After the above code is executed, <code>date</code> will refer to
45 * a new <code>Date</code> instance. Furthermore, that <code>Date</code>
46 * instance is mapped to the "NOW" key in the map.
47 * <p>
48 * <strong>Note that LazySortedMap is not synchronized and is not thread-safe.</strong>
49 * If you wish to use this map from multiple threads concurrently, you must use
50 * appropriate synchronization. The simplest approach is to wrap this map
51 * using {@link java.util.Collections#synchronizedSortedMap}. This class may throw
52 * exceptions when accessed by concurrent threads without synchronization.
53 * <p>
54 * This class is Serializable from Commons Collections 3.1.
55 *
56 * @since 3.0
57 * @version $Id: LazySortedMap.java 1436463 2013-01-21 16:35:01Z tn $
58 */
59 public class LazySortedMap<K,V> extends LazyMap<K,V> implements SortedMap<K,V> {
60
61 /** Serialization version */
62 private static final long serialVersionUID = 2715322183617658933L;
63
64 /**
65 * Factory method to create a lazily instantiated sorted map.
66 *
67 * @param <K> the key type
68 * @param <V> the value type
69 * @param map the map to decorate, must not be null
70 * @param factory the factory to use, must not be null
71 * @return a new lazy sorted map
72 * @throws IllegalArgumentException if map or factory is null
73 */
74 public static <K, V> LazySortedMap<K, V> lazySortedMap(final SortedMap<K, V> map,
75 final Factory<? extends V> factory) {
76 return new LazySortedMap<K,V>(map, factory);
77 }
78
79 /**
80 * Factory method to create a lazily instantiated sorted map.
81 *
82 * @param <K> the key type
83 * @param <V> the value type
84 * @param map the map to decorate, must not be null
85 * @param factory the factory to use, must not be null
86 * @return a new lazy sorted map
87 * @throws IllegalArgumentException if map or factory is null
88 */
89 public static <K, V> LazySortedMap<K, V> lazySortedMap(final SortedMap<K, V> map,
90 final Transformer<? super K, ? extends V> factory) {
91 return new LazySortedMap<K,V>(map, factory);
92 }
93
94 //-----------------------------------------------------------------------
95 /**
96 * Constructor that wraps (not copies).
97 *
98 * @param map the map to decorate, must not be null
99 * @param factory the factory to use, must not be null
100 * @throws IllegalArgumentException if map or factory is null
101 */
102 protected LazySortedMap(final SortedMap<K,V> map, final Factory<? extends V> factory) {
103 super(map, factory);
104 }
105
106 /**
107 * Constructor that wraps (not copies).
108 *
109 * @param map the map to decorate, must not be null
110 * @param factory the factory to use, must not be null
111 * @throws IllegalArgumentException if map or factory is null
112 */
113 protected LazySortedMap(final SortedMap<K,V> map, final Transformer<? super K, ? extends V> factory) {
114 super(map, factory);
115 }
116
117 //-----------------------------------------------------------------------
118 /**
119 * Gets the map being decorated.
120 *
121 * @return the decorated map
122 */
123 protected SortedMap<K,V> getSortedMap() {
124 return (SortedMap<K,V>) map;
125 }
126
127 //-----------------------------------------------------------------------
128 public K firstKey() {
129 return getSortedMap().firstKey();
130 }
131
132 public K lastKey() {
133 return getSortedMap().lastKey();
134 }
135
136 public Comparator<? super K> comparator() {
137 return getSortedMap().comparator();
138 }
139
140 public SortedMap<K,V> subMap(final K fromKey, final K toKey) {
141 final SortedMap<K,V> map = getSortedMap().subMap(fromKey, toKey);
142 return new LazySortedMap<K,V>(map, factory);
143 }
144
145 public SortedMap<K,V> headMap(final K toKey) {
146 final SortedMap<K,V> map = getSortedMap().headMap(toKey);
147 return new LazySortedMap<K,V>(map, factory);
148 }
149
150 public SortedMap<K,V> tailMap(final K fromKey) {
151 final SortedMap<K,V> map = getSortedMap().tailMap(fromKey);
152 return new LazySortedMap<K,V>(map, factory);
153 }
154
155 }