001 /*
002 Copyright (c) 1996-2012, 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 * With pairwise elements considered equal if both null or equals() is true.
076 */
077 @Override
078 public boolean equals(final Object obj)
079 {
080 if(this == obj) { return(true); }
081 if(!(obj instanceof Pair)) { return(false); }
082
083 final Pair other = (Pair) obj;
084 if(first == null)
085 { if(other.first != null) { return(false); } }
086 else if(!first.equals(other.first)) { return(false); }
087 if(second == null)
088 { if(other.second != null) { return(false); } }
089 else if(!second.equals(other.second)) { return(false); }
090
091 return(true); // Equal!
092 }
093
094 /**Unique Serialisation class ID generated by http://random.hd.org/. */
095 private static final long serialVersionUID = -5550500104003361224L;
096 }
097
098
099 /**A simple immutable Comparable pair (though the referenced items may be mutable).
100 * Either or both fields can be null.
101 * <p />
102 * Equality and hash are based on that of the two members.
103 * <p />
104 * The natural ordering given by compareTo() is determined by "first", with "second" breaking ties.
105 */
106 public static final class ComparablePair<T1 extends Comparable<T1>, T2 extends Comparable<T2>> implements
107 Serializable, Comparable<ComparablePair<T1,T2>>
108 {
109 public ComparablePair(final T1 first, final T2 second)
110 {
111 this.first = first;
112 this.second = second;
113 }
114
115 /**The first member of the pair. */
116 public final T1 first;
117
118 /**The second member of the pair. */
119 public final T2 second;
120
121 /**Human-readable form. */
122 @Override
123 public String toString()
124 { return("<" + first + "," + second + ">"); }
125
126 /**Hash is based on that of the two members. */
127 @Override
128 public int hashCode()
129 {
130 return(
131 ((first == null) ? 101 : first.hashCode()) ^
132 ((second == null) ? 2002 : second.hashCode())
133 );
134 }
135
136 /**Indicates whether some other object is "equal to" this one.
137 */
138 @Override
139 public boolean equals(final Object obj)
140 {
141 if(this == obj) { return(true); }
142 if(!(obj instanceof ComparablePair)) { return(false); }
143
144 final ComparablePair other = (ComparablePair) obj;
145 if(first == null)
146 { if(other.first != null) { return(false); } }
147 else if(!first.equals(other.first)) { return(false); }
148 if(second == null)
149 { if(other.second != null) { return(false); } }
150 else if(!second.equals(other.second)) { return(false); }
151
152 return(true); // Equal!
153 }
154
155 /**The ordering is determined by "first", with "second" breaking ties.
156 * Instances with nulls may not be comparable.
157 */
158 public int compareTo(final ComparablePair<T1,T2> other)
159 {
160 final int cf = first.compareTo(other.first);
161 if(cf != 0) { return(cf); }
162 return(second.compareTo(other.second));
163 }
164
165 /**Unique Serialisation class ID generated by http://random.hd.org/. */
166 private static final long serialVersionUID = -5550500104003361225L;
167 }
168
169
170 /**A simple immutable 3-tuple/triple (though the referenced items may be mutable).
171 * Any or all fields can be null.
172 * <p />
173 * Equality and hash are based on that of the three members.
174 */
175 public static final class Triple<T1,T2,T3> implements Serializable
176 {
177 public Triple(final T1 first, final T2 second, final T3 third)
178 {
179 this.first = first;
180 this.second = second;
181 this.third = third;
182 }
183
184 /**The first member of the triple. */
185 public final T1 first;
186
187 /**The second member of the triple. */
188 public final T2 second;
189
190 /**The third member of the triple. */
191 public final T3 third;
192
193 /**Human-readable form. */
194 @Override
195 public String toString()
196 { return("<" + first + "," + second + "," + third + ">"); }
197
198 /**Hash is based on that of the members. */
199 @Override
200 public int hashCode()
201 {
202 return(
203 ((first == null) ? -101 : first.hashCode()) ^
204 ((second == null) ? -10102 : Integer.rotateRight(second.hashCode(), 11)) ^
205 ((third == null) ? -1010103 : Integer.rotateLeft(third.hashCode(), 11))
206 );
207 }
208
209 /**Indicates whether some other object is "equal to" this one. */
210 @Override
211 public boolean equals(final Object obj)
212 {
213 if(this == obj) { return(true); }
214 if(!(obj instanceof Triple)) { return(false); }
215
216 final Triple other = (Triple) obj;
217 if(first == null)
218 { if(other.first != null) { return(false); } }
219 else if(!first.equals(other.first)) { return(false); }
220 if(second == null)
221 { if(other.second != null) { return(false); } }
222 else if(!second.equals(other.second)) { return(false); }
223 if(third == null)
224 { if(other.third != null) { return(false); } }
225 else if(!third.equals(other.third)) { return(false); }
226
227 return(true); // Equal!
228 }
229
230 private static final long serialVersionUID = -4570980722385392466L;
231 }
232
233 /**A simple immutable Comparable pair (though the referenced items may be mutable).
234 * Either or both fields can be null.
235 * <p />
236 * Equality and hash are based on that of the two members.
237 * <p />
238 * The natural ordering given by compareTo() is determined by "first", with "second" breaking ties.
239 */
240 public static final class ComparableTriple<T1 extends Comparable<T1>, T2 extends Comparable<T2>, T3 extends Comparable<T3>> implements
241 Serializable, Comparable<ComparableTriple<T1,T2,T3>>
242 {
243 public ComparableTriple(final T1 first, final T2 second, final T3 third)
244 {
245 this.first = first;
246 this.second = second;
247 this.third = third;
248 }
249
250 /**The first member of the triple. */
251 public final T1 first;
252
253 /**The second member of the triple. */
254 public final T2 second;
255
256 /**The third member of the triple. */
257 public final T3 third;
258
259 /**Human-readable form. */
260 @Override
261 public String toString()
262 { return("<" + first + "," + second + "," + third + ">"); }
263
264 /**Hash is based on that of the members. */
265 @Override
266 public int hashCode()
267 {
268 return(
269 ((first == null) ? -101 : first.hashCode()) ^
270 ((second == null) ? -10102 : second.hashCode()) ^
271 ((third == null) ? -1010103 : third.hashCode())
272 );
273 }
274
275 /**Indicates whether some other object is "equal to" this one. */
276 @Override
277 public boolean equals(final Object obj)
278 {
279 if(this == obj) { return(true); }
280 if(!(obj instanceof ComparableTriple)) { return(false); }
281
282 final ComparableTriple other = (ComparableTriple) obj;
283 if(first == null)
284 { if(other.first != null) { return(false); } }
285 else if(!first.equals(other.first)) { return(false); }
286 if(second == null)
287 { if(other.second != null) { return(false); } }
288 else if(!second.equals(other.second)) { return(false); }
289 if(third == null)
290 { if(other.third != null) { return(false); } }
291 else if(!third.equals(other.third)) { return(false); }
292
293 return(true); // Equal!
294 }
295
296
297 /**The ordering is determined by "first", with "second" and then "third" breaking ties.
298 * Instances with nulls may not be comparable.
299 */
300 public int compareTo(final ComparableTriple<T1,T2,T3> other)
301 {
302 final int cf1 = first.compareTo(other.first);
303 if(cf1 != 0) { return(cf1); }
304 final int cf2 = second.compareTo(other.second);
305 if(cf2 != 0) { return(cf2); }
306 return(third.compareTo(other.third));
307 }
308
309 private static final long serialVersionUID = -4570980722385392467L;
310 }
311 }