View Javadoc
1   /*
2    * Copyright 2007 Kasper B. Graversen
3    * 
4    * Licensed under the Apache License, Version 2.0 (the "License");
5    * you may not use this file except in compliance with the License.
6    * You may obtain a copy of the License at
7    * 
8    *     http://www.apache.org/licenses/LICENSE-2.0
9    * 
10   * Unless required by applicable law or agreed to in writing, software
11   * distributed under the License is distributed on an "AS IS" BASIS,
12   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13   * See the License for the specific language governing permissions and
14   * limitations under the License.
15   */
16  package org.supercsv.util;
17  
18  import java.util.HashMap;
19  import java.util.Set;
20  
21  /**
22   * A 3-dimensional HashMap is a HashMap that enables you to refer to values via three keys rather than one. The
23   * underlying implementation is simply a HashMap containing HashMap containing a HashMap, each of which maps to values.
24   * 
25   * @param <K1>
26   *            the first key type
27   * @param <K2>
28   *            the second key type
29   * @param <K3>
30   *            the third key type
31   * @param <V>
32   *            the value type
33   * @author Kasper B. Graversen
34   * @since 2.0.0 (migrated from Spiffy 0.5)
35   */
36  public class ThreeDHashMap<K1, K2, K3, V> {
37  	
38  	private final HashMap<K1, HashMap<K2, HashMap<K3, V>>> map = new HashMap<K1, HashMap<K2, HashMap<K3, V>>>();
39  	
40  	/**
41  	 * Existence check of a value (or <tt>null</tt>) mapped to the keys.
42  	 * 
43  	 * @param firstKey
44  	 *            first key
45  	 * @param secondKey
46  	 *            second key
47  	 * @return true when an element (or <tt>null</tt>) has been stored with the keys
48  	 */
49  	public boolean containsKey(final K1 firstKey, final K2 secondKey) {
50  		// existence check on inner map
51  		final HashMap<K2, HashMap<K3, V>> innerMap1 = map.get(firstKey);
52  		if( innerMap1 == null ) {
53  			return false;
54  		}
55  		
56  		return innerMap1.containsKey(secondKey);
57  	}
58  	
59  	/**
60  	 * Existence check of a value (or <tt>null</tt>) mapped to the keys.
61  	 * 
62  	 * @param firstKey
63  	 *            first key
64  	 * @param secondKey
65  	 *            second key
66  	 * @param thirdKey
67  	 *            third key
68  	 * @return true when an element (or <tt>null</tt>) has been stored with the keys
69  	 */
70  	public boolean containsKey(final K1 firstKey, final K2 secondKey, final K3 thirdKey) {
71  		// existence check on inner map
72  		final HashMap<K2, HashMap<K3, V>> innerMap1 = map.get(firstKey);
73  		if( innerMap1 == null ) {
74  			return false;
75  		}
76  		
77  		// existence check on inner map1
78  		final HashMap<K3, V> innerMap2 = innerMap1.get(secondKey);
79  		if( innerMap2 == null ) {
80  			return false;
81  		}
82  		return innerMap2.containsKey(thirdKey);
83  	}
84  	
85  	/**
86  	 * Fetch the outermost Hashmap.
87  	 * 
88  	 * @param firstKey
89  	 *            first key
90  	 * @return the the innermost hashmap
91  	 */
92  	public HashMap<K2, HashMap<K3, V>> get(final K1 firstKey) {
93  		return map.get(firstKey);
94  	}
95  	
96  	/**
97  	 * Fetch the outermost Hashmap as a TwoDHashMap.
98  	 * 
99  	 * @param firstKey
100 	 *            first key
101 	 * @return the the innermost hashmap
102 	 */
103 	public TwoDHashMap<K2, K3, V> getAs2d(final K1 firstKey) {
104 		final HashMap<K2, HashMap<K3, V>> innerMap1 = map.get(firstKey);
105 		if( innerMap1 != null ) {
106 			return new TwoDHashMap<K2, K3, V>(innerMap1);
107 		} else {
108 			return new TwoDHashMap<K2, K3, V>();
109 		}
110 		
111 	}
112 	
113 	/**
114 	 * Fetch the innermost Hashmap.
115 	 * 
116 	 * @param firstKey
117 	 *            first key
118 	 * @param secondKey
119 	 *            second key
120 	 * @return the the innermost hashmap
121 	 */
122 	public HashMap<K3, V> get(final K1 firstKey, final K2 secondKey) {
123 		// existence check on inner map
124 		final HashMap<K2, HashMap<K3, V>> innerMap1 = map.get(firstKey);
125 		if( innerMap1 == null ) {
126 			return null;
127 		}
128 		
129 		return innerMap1.get(secondKey);
130 	}
131 	
132 	/**
133 	 * Fetch a value from the Hashmap.
134 	 * 
135 	 * @param firstKey
136 	 *            first key
137 	 * @param secondKey
138 	 *            second key
139 	 * @param thirdKey
140 	 *            third key
141 	 * @return the element or null.
142 	 */
143 	public V get(final K1 firstKey, final K2 secondKey, final K3 thirdKey) {
144 		// existence check on inner map
145 		final HashMap<K2, HashMap<K3, V>> innerMap1 = map.get(firstKey);
146 		if( innerMap1 == null ) {
147 			return null;
148 		}
149 		
150 		// existence check on inner map1
151 		final HashMap<K3, V> innerMap2 = innerMap1.get(secondKey);
152 		if( innerMap2 == null ) {
153 			return null;
154 		}
155 		return innerMap2.get(thirdKey);
156 	}
157 	
158 	/**
159 	 * Insert a value
160 	 * 
161 	 * @param firstKey
162 	 *            first key
163 	 * @param secondKey
164 	 *            second key
165 	 * @param thirdKey
166 	 *            third key
167 	 * @param value
168 	 *            the value to be inserted. <tt>null</tt> may be inserted as well.
169 	 * @return null or the value the insert is replacing.
170 	 */
171 	public Object set(final K1 firstKey, final K2 secondKey, final K3 thirdKey, final V value) {
172 		// existence check on inner map1
173 		HashMap<K2, HashMap<K3, V>> innerMap1 = map.get(firstKey);
174 		
175 		if( innerMap1 == null ) {
176 			// no inner map, create it
177 			innerMap1 = new HashMap<K2, HashMap<K3, V>>();
178 			map.put(firstKey, innerMap1);
179 		}
180 		
181 		// existence check on inner map1
182 		HashMap<K3, V> innerMap2 = innerMap1.get(secondKey);
183 		if( innerMap2 == null ) {
184 			// no inner map, create it
185 			innerMap2 = new HashMap<K3, V>();
186 			innerMap1.put(secondKey, innerMap2);
187 		}
188 		
189 		return innerMap2.put(thirdKey, value);
190 	}
191 	
192 	/**
193 	 * Returns the number of key-value mappings in this map for the first key.
194 	 * 
195 	 * @return Returns the number of key-value mappings in this map for the first key.
196 	 */
197 	public int size() {
198 		return map.size();
199 	}
200 	
201 	/**
202 	 * Returns the number of key-value mappings in this map for the second key.
203 	 * 
204 	 * @param firstKey
205 	 *            the first key
206 	 * @return Returns the number of key-value mappings in this map for the second key.
207 	 */
208 	public int size(final K1 firstKey) {
209 		// existence check on inner map
210 		final HashMap<K2, HashMap<K3, V>> innerMap = map.get(firstKey);
211 		if( innerMap == null ) {
212 			return 0;
213 		}
214 		return innerMap.size();
215 	}
216 	
217 	/**
218 	 * Returns the number of key-value mappings in this map for the third key.
219 	 * 
220 	 * @param firstKey
221 	 *            the first key
222 	 * @param secondKey
223 	 *            the second key
224 	 * @return Returns the number of key-value mappings in this map for the third key.
225 	 */
226 	public int size(final K1 firstKey, final K2 secondKey) {
227 		// existence check on inner map
228 		final HashMap<K2, HashMap<K3, V>> innerMap1 = map.get(firstKey);
229 		if( innerMap1 == null ) {
230 			return 0;
231 		}
232 		
233 		// existence check on inner map1
234 		final HashMap<K3, V> innerMap2 = innerMap1.get(secondKey);
235 		if( innerMap2 == null ) {
236 			return 0;
237 		}
238 		return innerMap2.size();
239 	}
240 	
241 	/**
242 	 * Returns a set of the keys of the outermost map.
243 	 * 
244 	 * @return the key set for the outermost map
245 	 */
246 	public Set<K1> keySet() {
247 		return map.keySet();
248 	}
249 	
250 }