001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.commons.collections4.map; 018 019import java.util.Comparator; 020import java.util.SortedMap; 021 022import org.apache.commons.collections4.Factory; 023import org.apache.commons.collections4.Transformer; 024 025/** 026 * Decorates another <code>SortedMap</code> to create objects in the map on demand. 027 * <p> 028 * When the {@link #get(Object)} method is called with a key that does not 029 * exist in the map, the factory is used to create the object. The created 030 * object will be added to the map using the requested key. 031 * <p> 032 * For instance: 033 * <pre> 034 * Factory<Date> factory = new Factory<Date>() { 035 * public Date create() { 036 * return new Date(); 037 * } 038 * } 039 * SortedMap<String, Date> lazy = 040 * LazySortedMap.lazySortedMap(new HashMap<String, Date>(), factory); 041 * Date date = lazy.get("NOW"); 042 * </pre> 043 * 044 * After the above code is executed, <code>date</code> will refer to 045 * a new <code>Date</code> instance. Furthermore, that <code>Date</code> 046 * instance is mapped to the "NOW" key in the map. 047 * <p> 048 * <strong>Note that LazySortedMap is not synchronized and is not thread-safe.</strong> 049 * If you wish to use this map from multiple threads concurrently, you must use 050 * appropriate synchronization. The simplest approach is to wrap this map 051 * using {@link java.util.Collections#synchronizedSortedMap}. This class may throw 052 * exceptions when accessed by concurrent threads without synchronization. 053 * <p> 054 * This class is Serializable from Commons Collections 3.1. 055 * 056 * @param <K> the type of the keys in this map 057 * @param <V> the type of the values in this map 058 * @since 3.0 059 */ 060public class LazySortedMap<K,V> extends LazyMap<K,V> implements SortedMap<K,V> { 061 062 /** Serialization version */ 063 private static final long serialVersionUID = 2715322183617658933L; 064 065 /** 066 * Factory method to create a lazily instantiated sorted map. 067 * 068 * @param <K> the key type 069 * @param <V> the value type 070 * @param map the map to decorate, must not be null 071 * @param factory the factory to use, must not be null 072 * @return a new lazy sorted map 073 * @throws NullPointerException if map or factory is null 074 * @since 4.0 075 */ 076 public static <K, V> LazySortedMap<K, V> lazySortedMap(final SortedMap<K, V> map, 077 final Factory<? extends V> factory) { 078 return new LazySortedMap<>(map, factory); 079 } 080 081 /** 082 * Factory method to create a lazily instantiated sorted map. 083 * 084 * @param <K> the key type 085 * @param <V> the value type 086 * @param map the map to decorate, must not be null 087 * @param factory the factory to use, must not be null 088 * @return a new lazy sorted map 089 * @throws NullPointerException if map or factory is null 090 * @since 4.0 091 */ 092 public static <K, V> LazySortedMap<K, V> lazySortedMap(final SortedMap<K, V> map, 093 final Transformer<? super K, ? extends V> factory) { 094 return new LazySortedMap<>(map, factory); 095 } 096 097 //----------------------------------------------------------------------- 098 /** 099 * Constructor that wraps (not copies). 100 * 101 * @param map the map to decorate, must not be null 102 * @param factory the factory to use, must not be null 103 * @throws NullPointerException if map or factory is null 104 */ 105 protected LazySortedMap(final SortedMap<K,V> map, final Factory<? extends V> factory) { 106 super(map, factory); 107 } 108 109 /** 110 * Constructor that wraps (not copies). 111 * 112 * @param map the map to decorate, must not be null 113 * @param factory the factory to use, must not be null 114 * @throws NullPointerException if map or factory is null 115 */ 116 protected LazySortedMap(final SortedMap<K,V> map, final Transformer<? super K, ? extends V> factory) { 117 super(map, factory); 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 @Override 132 public K firstKey() { 133 return getSortedMap().firstKey(); 134 } 135 136 @Override 137 public K lastKey() { 138 return getSortedMap().lastKey(); 139 } 140 141 @Override 142 public Comparator<? super K> comparator() { 143 return getSortedMap().comparator(); 144 } 145 146 @Override 147 public SortedMap<K,V> subMap(final K fromKey, final K toKey) { 148 final SortedMap<K,V> map = getSortedMap().subMap(fromKey, toKey); 149 return new LazySortedMap<>(map, factory); 150 } 151 152 @Override 153 public SortedMap<K,V> headMap(final K toKey) { 154 final SortedMap<K,V> map = getSortedMap().headMap(toKey); 155 return new LazySortedMap<>(map, factory); 156 } 157 158 @Override 159 public SortedMap<K,V> tailMap(final K fromKey) { 160 final SortedMap<K,V> map = getSortedMap().tailMap(fromKey); 161 return new LazySortedMap<>(map, factory); 162 } 163 164}