001 /*
002 Copyright (c) 1996-2011, Damon Hart-Davis
003 All rights reserved.
004
005 Redistribution and use in source and binary forms, with or without
006 modification, are permitted provided that the following conditions are
007 met:
008
009 * Redistributions of source code must retain the above copyright
010 notice, this list of conditions and the following disclaimer.
011
012 * Redistributions in binary form must reproduce the above copyright
013 notice, this list of conditions and the following disclaimer in the
014 documentation and/or other materials provided with the
015 distribution.
016
017 THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
018 IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
019 TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
020 PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
021 OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
022 SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
023 LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
024 DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
025 THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
026 (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
027 OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
028 */
029 package org.hd.d.pg2k.svrCore;
030
031 import java.io.Serializable;
032
033 /**Support for anonymous tuples such as pairs.
034 */
035 public final class Tuple
036 {
037 /**Prevent construction of an instance. */
038 private Tuple() { }
039
040 /**A simple immutable pair (though the referenced items may be mutable).
041 * Either or both fields can be null.
042 * <p />
043 * Equality and hash are based on that of the two members.
044 */
045 public static final class Pair<T1,T2> implements Serializable
046 {
047 public Pair(final T1 first, final T2 second)
048 {
049 this.first = first;
050 this.second = second;
051 }
052
053 /**The first member of the pair. */
054 public final T1 first;
055
056 /**The second member of the pair. */
057 public final T2 second;
058
059 /**Human-readable form. */
060 @Override
061 public String toString()
062 { return("<" + first + "," + second + ">"); }
063
064 /**Hash is based on that of the two members. */
065 @Override
066 public int hashCode()
067 {
068 return(
069 ((first == null) ? 1 : first.hashCode()) ^
070 ((second == null) ? 2 : second.hashCode())
071 );
072 }
073
074 /**Indicates whether some other object is "equal to" this one.
075 */
076 @Override
077 public boolean equals(final Object obj)
078 {
079 if(this == obj) { return(true); }
080 if(!(obj instanceof Pair)) { return(false); }
081
082 final Pair other = (Pair) obj;
083 if(first == null)
084 { if(other.first != null) { return(false); } }
085 else if(!first.equals(other.first)) { return(false); }
086 if(second == null)
087 { if(other.second != null) { return(false); } }
088 else if(!second.equals(other.second)) { return(false); }
089
090 return(true); // Equal!
091 }
092
093 /**Unique Serialisation class ID generated by http://random.hd.org/. */
094 private static final long serialVersionUID = -5550500104003361224L;
095 }
096
097
098 /**A simple immutable Comparable pair (though the referenced items may be mutable).
099 * Either or both fields can be null.
100 * <p />
101 * Equality and hash are based on that of the two members.
102 * <p />
103 * The natural ordering given by compareTo() is determined by "first", with "second" breaking ties.
104 */
105 public static final class ComparablePair<T1 extends Comparable<T1>, T2 extends Comparable<T2>> implements
106 Serializable, Comparable<ComparablePair<T1,T2>>
107 {
108 public ComparablePair(final T1 first, final T2 second)
109 {
110 this.first = first;
111 this.second = second;
112 }
113
114 /**The first member of the pair. */
115 public final T1 first;
116
117 /**The second member of the pair. */
118 public final T2 second;
119
120 /**Human-readable form. */
121 @Override
122 public String toString()
123 { return("<" + first + "," + second + ">"); }
124
125 /**Hash is based on that of the two members. */
126 @Override
127 public int hashCode()
128 {
129 return(
130 ((first == null) ? 101 : first.hashCode()) ^
131 ((second == null) ? 2002 : second.hashCode())
132 );
133 }
134
135 /**Indicates whether some other object is "equal to" this one.
136 */
137 @Override
138 public boolean equals(final Object obj)
139 {
140 if(this == obj) { return(true); }
141 if(!(obj instanceof ComparablePair)) { return(false); }
142
143 final ComparablePair other = (ComparablePair) obj;
144 if(first == null)
145 { if(other.first != null) { return(false); } }
146 else if(!first.equals(other.first)) { return(false); }
147 if(second == null)
148 { if(other.second != null) { return(false); } }
149 else if(!second.equals(other.second)) { return(false); }
150
151 return(true); // Equal!
152 }
153
154 /**The ordering is determined by "first", with "second" breaking ties.
155 * Instances with nulls may not be comparable.
156 */
157 public int compareTo(final ComparablePair<T1,T2> other)
158 {
159 final int cf = first.compareTo(other.first);
160 if(cf != 0) { return(cf); }
161 return(second.compareTo(other.second));
162 }
163
164 /**Unique Serialisation class ID generated by http://random.hd.org/. */
165 private static final long serialVersionUID = -5550500104003361225L;
166 }
167
168
169 /**A simple immutable 3-tuple/triple (though the referenced items may be mutable).
170 * Any or all fields can be null.
171 * <p />
172 * Equality and hash are based on that of the three members.
173 */
174 public static final class Triple<T1,T2,T3> implements Serializable
175 {
176 public Triple(final T1 first, final T2 second, final T3 third)
177 {
178 this.first = first;
179 this.second = second;
180 this.third = third;
181 }
182
183 /**The first member of the triple. */
184 public final T1 first;
185
186 /**The second member of the triple. */
187 public final T2 second;
188
189 /**The third member of the triple. */
190 public final T3 third;
191
192 /**Human-readable form. */
193 @Override
194 public String toString()
195 { return("<" + first + "," + second + "," + third + ">"); }
196
197 /**Hash is based on that of the members. */
198 @Override
199 public int hashCode()
200 {
201 return(
202 ((first == null) ? -101 : first.hashCode()) ^
203 ((second == null) ? -10102 : Integer.rotateRight(second.hashCode(), 11)) ^
204 ((third == null) ? -1010103 : Integer.rotateLeft(third.hashCode(), 11))
205 );
206 }
207
208 /**Indicates whether some other object is "equal to" this one. */
209 @Override
210 public boolean equals(final Object obj)
211 {
212 if(this == obj) { return(true); }
213 if(!(obj instanceof Triple)) { return(false); }
214
215 final Triple other = (Triple) obj;
216 if(first == null)
217 { if(other.first != null) { return(false); } }
218 else if(!first.equals(other.first)) { return(false); }
219 if(second == null)
220 { if(other.second != null) { return(false); } }
221 else if(!second.equals(other.second)) { return(false); }
222 if(third == null)
223 { if(other.third != null) { return(false); } }
224 else if(!third.equals(other.third)) { return(false); }
225
226 return(true); // Equal!
227 }
228
229 private static final long serialVersionUID = -4570980722385392466L;
230 }
231
232 /**A simple immutable Comparable pair (though the referenced items may be mutable).
233 * Either or both fields can be null.
234 * <p />
235 * Equality and hash are based on that of the two members.
236 * <p />
237 * The natural ordering given by compareTo() is determined by "first", with "second" breaking ties.
238 */
239 public static final class ComparableTriple<T1 extends Comparable<T1>, T2 extends Comparable<T2>, T3 extends Comparable<T3>> implements
240 Serializable, Comparable<ComparableTriple<T1,T2,T3>>
241 {
242 public ComparableTriple(final T1 first, final T2 second, final T3 third)
243 {
244 this.first = first;
245 this.second = second;
246 this.third = third;
247 }
248
249 /**The first member of the triple. */
250 public final T1 first;
251
252 /**The second member of the triple. */
253 public final T2 second;
254
255 /**The third member of the triple. */
256 public final T3 third;
257
258 /**Human-readable form. */
259 @Override
260 public String toString()
261 { return("<" + first + "," + second + "," + third + ">"); }
262
263 /**Hash is based on that of the members. */
264 @Override
265 public int hashCode()
266 {
267 return(
268 ((first == null) ? -101 : first.hashCode()) ^
269 ((second == null) ? -10102 : second.hashCode()) ^
270 ((third == null) ? -1010103 : third.hashCode())
271 );
272 }
273
274 /**Indicates whether some other object is "equal to" this one. */
275 @Override
276 public boolean equals(final Object obj)
277 {
278 if(this == obj) { return(true); }
279 if(!(obj instanceof ComparableTriple)) { return(false); }
280
281 final ComparableTriple other = (ComparableTriple) obj;
282 if(first == null)
283 { if(other.first != null) { return(false); } }
284 else if(!first.equals(other.first)) { return(false); }
285 if(second == null)
286 { if(other.second != null) { return(false); } }
287 else if(!second.equals(other.second)) { return(false); }
288 if(third == null)
289 { if(other.third != null) { return(false); } }
290 else if(!third.equals(other.third)) { return(false); }
291
292 return(true); // Equal!
293 }
294
295
296 /**The ordering is determined by "first", with "second" and then "third" breaking ties.
297 * Instances with nulls may not be comparable.
298 */
299 public int compareTo(final ComparableTriple<T1,T2,T3> other)
300 {
301 final int cf1 = first.compareTo(other.first);
302 if(cf1 != 0) { return(cf1); }
303 final int cf2 = second.compareTo(other.second);
304 if(cf2 != 0) { return(cf2); }
305 return(third.compareTo(other.third));
306 }
307
308 private static final long serialVersionUID = -4570980722385392467L;
309 }
310 }