KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > commons > collections > keyvalue > MultiKey


1 /*
2  * Copyright 2003-2004 The Apache Software Foundation
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.apache.commons.collections.keyvalue;
17
18 import java.io.Serializable JavaDoc;
19 import java.util.Arrays JavaDoc;
20
21 /**
22  * A <code>MultiKey</code> allows multiple map keys to be merged together.
23  * <p>
24  * The purpose of this class is to avoid the need to write code to handle
25  * maps of maps. An example might be the need to lookup a filename by
26  * key and locale. The typical solution might be nested maps. This class
27  * can be used instead by creating an instance passing in the key and locale.
28  * <p>
29  * Example usage:
30  * <pre>
31  * // populate map with data mapping key+locale to localizedText
32  * Map map = new HashMap();
33  * MultiKey multiKey = new MultiKey(key, locale);
34  * map.put(multiKey, localizedText);
35  *
36  * // later retireve the localized text
37  * MultiKey multiKey = new MultiKey(key, locale);
38  * String localizedText = (String) map.get(multiKey);
39  * </pre>
40  *
41  * @since Commons Collections 3.0
42  * @version $Revision: 1.5 $ $Date: 2004/03/13 12:43:43 $
43  *
44  * @author Howard Lewis Ship
45  * @author Stephen Colebourne
46  */

47 public class MultiKey implements Serializable JavaDoc {
48     // This class could implement List, but that would confuse it's purpose
49

50     /** Serialisation version */
51     private static final long serialVersionUID = 4465448607415788805L;
52
53     /** The individual keys */
54     private final Object JavaDoc[] keys;
55     /** The cached hashCode */
56     private final int hashCode;
57     
58     /**
59      * Constructor taking two keys.
60      * <p>
61      * The keys should be immutable
62      * If they are not then they must not be changed after adding to the MultiKey.
63      *
64      * @param key1 the first key
65      * @param key2 the second key
66      */

67     public MultiKey(Object JavaDoc key1, Object JavaDoc key2) {
68         this(new Object JavaDoc[] {key1, key2}, false);
69     }
70     
71     /**
72      * Constructor taking three keys.
73      * <p>
74      * The keys should be immutable
75      * If they are not then they must not be changed after adding to the MultiKey.
76      *
77      * @param key1 the first key
78      * @param key2 the second key
79      * @param key3 the third key
80      */

81     public MultiKey(Object JavaDoc key1, Object JavaDoc key2, Object JavaDoc key3) {
82         this(new Object JavaDoc[] {key1, key2, key3}, false);
83     }
84     
85     /**
86      * Constructor taking four keys.
87      * <p>
88      * The keys should be immutable
89      * If they are not then they must not be changed after adding to the MultiKey.
90      *
91      * @param key1 the first key
92      * @param key2 the second key
93      * @param key3 the third key
94      * @param key4 the fourth key
95      */

96     public MultiKey(Object JavaDoc key1, Object JavaDoc key2, Object JavaDoc key3, Object JavaDoc key4) {
97         this(new Object JavaDoc[] {key1, key2, key3, key4}, false);
98     }
99     
100     /**
101      * Constructor taking five keys.
102      * <p>
103      * The keys should be immutable
104      * If they are not then they must not be changed after adding to the MultiKey.
105      *
106      * @param key1 the first key
107      * @param key2 the second key
108      * @param key3 the third key
109      * @param key4 the fourth key
110      * @param key5 the fifth key
111      */

112     public MultiKey(Object JavaDoc key1, Object JavaDoc key2, Object JavaDoc key3, Object JavaDoc key4, Object JavaDoc key5) {
113         this(new Object JavaDoc[] {key1, key2, key3, key4, key5}, false);
114     }
115     
116     /**
117      * Constructor taking an array of keys which is cloned.
118      * <p>
119      * The keys should be immutable
120      * If they are not then they must not be changed after adding to the MultiKey.
121      * <p>
122      * This is equivalent to <code>new MultiKey(keys, true)</code>.
123      *
124      * @param keys the array of keys, not null
125      * @throws IllegalArgumentException if the key array is null
126      */

127     public MultiKey(Object JavaDoc[] keys) {
128         this(keys, true);
129     }
130     
131     /**
132      * Constructor taking an array of keys, optionally choosing whether to clone.
133      * <p>
134      * <b>If the array is not cloned, then it must not be modified.</b>
135      * <p>
136      * This method is public for performance reasons only, to avoid a clone.
137      * The hashcode is calculated once here in this method.
138      * Therefore, changing the array passed in would not change the hashcode but
139      * would change the equals method, which is a bug.
140      * <p>
141      * This is the only fully safe usage of this constructor, as the object array
142      * is never made available in a variable:
143      * <pre>
144      * new MultiKey(new Object[] {...}, false);
145      * </pre>
146      * <p>
147      * The keys should be immutable
148      * If they are not then they must not be changed after adding to the MultiKey.
149      *
150      * @param keys the array of keys, not null
151      * @param makeClone true to clone the array, false to assign it
152      * @throws IllegalArgumentException if the key array is null
153      * @since Commons Collections 3.1
154      */

155     public MultiKey(Object JavaDoc[] keys, boolean makeClone) {
156         super();
157         if (keys == null) {
158             throw new IllegalArgumentException JavaDoc("The array of keys must not be null");
159         }
160         if (makeClone) {
161             this.keys = (Object JavaDoc[]) keys.clone();
162         } else {
163             this.keys = keys;
164         }
165         
166         int total = 0;
167         for (int i = 0; i < keys.length; i++) {
168             if (keys[i] != null) {
169                 total ^= keys[i].hashCode();
170             }
171         }
172         hashCode = total;
173     }
174     
175     //-----------------------------------------------------------------------
176
/**
177      * Gets a clone of the array of keys.
178      * <p>
179      * The keys should be immutable
180      * If they are not then they must not be changed.
181      *
182      * @return the individual keys
183      */

184     public Object JavaDoc[] getKeys() {
185         return (Object JavaDoc[]) keys.clone();
186     }
187     
188     /**
189      * Gets the key at the specified index.
190      * <p>
191      * The key should be immutable.
192      * If it is not then it must not be changed.
193      *
194      * @param index the index to retrieve
195      * @return the key at the index
196      * @throws IndexOutOfBoundsException if the index is invalid
197      * @since Commons Collections 3.1
198      */

199     public Object JavaDoc getKey(int index) {
200         return keys[index];
201     }
202     
203     /**
204      * Gets the size of the list of keys.
205      *
206      * @return the size of the list of keys
207      * @since Commons Collections 3.1
208      */

209     public int size() {
210         return keys.length;
211     }
212     
213     //-----------------------------------------------------------------------
214
/**
215      * Compares this object to another.
216      * <p>
217      * To be equal, the other object must be a <code>MultiKey</code> with the
218      * same number of keys which are also equal.
219      *
220      * @param other the other object to compare to
221      * @return true if equal
222      */

223     public boolean equals(Object JavaDoc other) {
224         if (other == this) {
225             return true;
226         }
227         if (other instanceof MultiKey) {
228             MultiKey otherMulti = (MultiKey) other;
229             return Arrays.equals(keys, otherMulti.keys);
230         }
231         return false;
232     }
233
234     /**
235      * Gets the combined hash code that is computed from all the keys.
236      * <p>
237      * This value is computed once and then cached, so elements should not
238      * change their hash codes once created (note that this is the same
239      * constraint that would be used if the individual keys elements were
240      * themselves {@link java.util.Map Map} keys.
241      *
242      * @return the hash code
243      */

244     public int hashCode() {
245         return hashCode;
246     }
247
248     /**
249      * Gets a debugging string version of the key.
250      *
251      * @return a debugging string
252      */

253     public String JavaDoc toString() {
254         return "MultiKey" + Arrays.asList(keys).toString();
255     }
256
257 }
258
Popular Tags