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