source: src/main/java/agents/org/apache/commons/lang/builder/CompareToBuilder.java

Last change on this file was 127, checked in by Wouter Pasman, 6 years ago

#41 ROLL BACK of rev.126 . So this version is equal to rev. 125

File size: 38.2 KB
Line 
1/*
2 * Licensed to the Apache Software Foundation (ASF) under one or more
3 * contributor license agreements. See the NOTICE file distributed with
4 * this work for additional information regarding copyright ownership.
5 * The ASF licenses this file to You under the Apache License, Version 2.0
6 * (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17package agents.org.apache.commons.lang.builder;
18
19import java.lang.reflect.AccessibleObject;
20import java.lang.reflect.Field;
21import java.lang.reflect.Modifier;
22import java.util.Collection;
23import java.util.Comparator;
24
25import agents.org.apache.commons.lang.ArrayUtils;
26import agents.org.apache.commons.lang.math.NumberUtils;
27
28/**
29 * Assists in implementing {@link java.lang.Comparable#compareTo(Object)} methods.
30 *
31 * It is consistent with <code>equals(Object)</code> and
32 * <code>hashcode()</code> built with {@link EqualsBuilder} and
33 * {@link HashCodeBuilder}.</p>
34 *
35 * <p>Two Objects that compare equal using <code>equals(Object)</code> should normally
36 * also compare equal using <code>compareTo(Object)</code>.</p>
37 *
38 * <p>All relevant fields should be included in the calculation of the
39 * comparison. Derived fields may be ignored. The same fields, in the same
40 * order, should be used in both <code>compareTo(Object)</code> and
41 * <code>equals(Object)</code>.</p>
42 *
43 * <p>To use this class write code as follows:</p>
44 *
45 * <pre>
46 * public class MyClass {
47 * String field1;
48 * int field2;
49 * boolean field3;
50 *
51 * ...
52 *
53 * public int compareTo(Object o) {
54 * MyClass myClass = (MyClass) o;
55 * return new CompareToBuilder()
56 * .appendSuper(super.compareTo(o)
57 * .append(this.field1, myClass.field1)
58 * .append(this.field2, myClass.field2)
59 * .append(this.field3, myClass.field3)
60 * .toComparison();
61 * }
62 * }
63 * </pre>
64 *
65 * <p>Alternatively, there are {@link #reflectionCompare(Object, Object) reflectionCompare} methods that use
66 * reflection to determine the fields to append. Because fields can be private,
67 * <code>reflectionCompare</code> uses {@link java.lang.reflect.AccessibleObject#setAccessible(boolean)} to
68 * bypass normal access control checks. This will fail under a security manager,
69 * unless the appropriate permissions are set up correctly. It is also
70 * slower than appending explicitly.</p>
71 *
72 * <p>A typical implementation of <code>compareTo(Object)</code> using
73 * <code>reflectionCompare</code> looks like:</p>
74
75 * <pre>
76 * public int compareTo(Object o) {
77 * return CompareToBuilder.reflectionCompare(this, o);
78 * }
79 * </pre>
80 *
81 * @see java.lang.Comparable
82 * @see java.lang.Object#equals(Object)
83 * @see java.lang.Object#hashCode()
84 * @see EqualsBuilder
85 * @see HashCodeBuilder
86 * @author Apache Software Foundation
87 * @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</a>
88 * @author Gary Gregory
89 * @author Pete Gieser
90 * @since 1.0
91 * @version $Id: CompareToBuilder.java 1056843 2011-01-09 00:29:01Z niallp $
92 */
93public class CompareToBuilder {
94
95 /**
96 * Current state of the comparison as appended fields are checked.
97 */
98 private int comparison;
99
100 /**
101 * <p>Constructor for CompareToBuilder.</p>
102 *
103 * <p>Starts off assuming that the objects are equal. Multiple calls are
104 * then made to the various append methods, followed by a call to
105 * {@link #toComparison} to get the result.</p>
106 */
107 public CompareToBuilder() {
108 super();
109 comparison = 0;
110 }
111
112 //-----------------------------------------------------------------------
113 /**
114 * <p>Compares two <code>Object</code>s via reflection.</p>
115 *
116 * <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
117 * is used to bypass normal access control checks. This will fail under a
118 * security manager unless the appropriate permissions are set.</p>
119 *
120 * <ul>
121 * <li>Static fields will not be compared</li>
122 * <li>Transient members will be not be compared, as they are likely derived
123 * fields</li>
124 * <li>Superclass fields will be compared</li>
125 * </ul>
126 *
127 * <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
128 * they are considered equal.</p>
129 *
130 * @param lhs left-hand object
131 * @param rhs right-hand object
132 * @return a negative integer, zero, or a positive integer as <code>lhs</code>
133 * is less than, equal to, or greater than <code>rhs</code>
134 * @throws NullPointerException if either (but not both) parameters are
135 * <code>null</code>
136 * @throws ClassCastException if <code>rhs</code> is not assignment-compatible
137 * with <code>lhs</code>
138 */
139 public static int reflectionCompare(Object lhs, Object rhs) {
140 return reflectionCompare(lhs, rhs, false, null, null);
141 }
142
143 /**
144 * <p>Compares two <code>Object</code>s via reflection.</p>
145 *
146 * <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
147 * is used to bypass normal access control checks. This will fail under a
148 * security manager unless the appropriate permissions are set.</p>
149 *
150 * <ul>
151 * <li>Static fields will not be compared</li>
152 * <li>If <code>compareTransients</code> is <code>true</code>,
153 * compares transient members. Otherwise ignores them, as they
154 * are likely derived fields.</li>
155 * <li>Superclass fields will be compared</li>
156 * </ul>
157 *
158 * <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
159 * they are considered equal.</p>
160 *
161 * @param lhs left-hand object
162 * @param rhs right-hand object
163 * @param compareTransients whether to compare transient fields
164 * @return a negative integer, zero, or a positive integer as <code>lhs</code>
165 * is less than, equal to, or greater than <code>rhs</code>
166 * @throws NullPointerException if either <code>lhs</code> or <code>rhs</code>
167 * (but not both) is <code>null</code>
168 * @throws ClassCastException if <code>rhs</code> is not assignment-compatible
169 * with <code>lhs</code>
170 */
171 public static int reflectionCompare(Object lhs, Object rhs, boolean compareTransients) {
172 return reflectionCompare(lhs, rhs, compareTransients, null, null);
173 }
174
175 /**
176 * <p>Compares two <code>Object</code>s via reflection.</p>
177 *
178 * <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
179 * is used to bypass normal access control checks. This will fail under a
180 * security manager unless the appropriate permissions are set.</p>
181 *
182 * <ul>
183 * <li>Static fields will not be compared</li>
184 * <li>If <code>compareTransients</code> is <code>true</code>,
185 * compares transient members. Otherwise ignores them, as they
186 * are likely derived fields.</li>
187 * <li>Superclass fields will be compared</li>
188 * </ul>
189 *
190 * <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
191 * they are considered equal.</p>
192 *
193 * @param lhs left-hand object
194 * @param rhs right-hand object
195 * @param excludeFields Collection of String fields to exclude
196 * @return a negative integer, zero, or a positive integer as <code>lhs</code>
197 * is less than, equal to, or greater than <code>rhs</code>
198 * @throws NullPointerException if either <code>lhs</code> or <code>rhs</code>
199 * (but not both) is <code>null</code>
200 * @throws ClassCastException if <code>rhs</code> is not assignment-compatible
201 * with <code>lhs</code>
202 * @since 2.2
203 */
204 public static int reflectionCompare(Object lhs, Object rhs, Collection /*String*/ excludeFields) {
205 return reflectionCompare(lhs, rhs, ReflectionToStringBuilder.toNoNullStringArray(excludeFields));
206 }
207
208 /**
209 * <p>Compares two <code>Object</code>s via reflection.</p>
210 *
211 * <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
212 * is used to bypass normal access control checks. This will fail under a
213 * security manager unless the appropriate permissions are set.</p>
214 *
215 * <ul>
216 * <li>Static fields will not be compared</li>
217 * <li>If <code>compareTransients</code> is <code>true</code>,
218 * compares transient members. Otherwise ignores them, as they
219 * are likely derived fields.</li>
220 * <li>Superclass fields will be compared</li>
221 * </ul>
222 *
223 * <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
224 * they are considered equal.</p>
225 *
226 * @param lhs left-hand object
227 * @param rhs right-hand object
228 * @param excludeFields array of fields to exclude
229 * @return a negative integer, zero, or a positive integer as <code>lhs</code>
230 * is less than, equal to, or greater than <code>rhs</code>
231 * @throws NullPointerException if either <code>lhs</code> or <code>rhs</code>
232 * (but not both) is <code>null</code>
233 * @throws ClassCastException if <code>rhs</code> is not assignment-compatible
234 * with <code>lhs</code>
235 * @since 2.2
236 */
237 public static int reflectionCompare(Object lhs, Object rhs, String[] excludeFields) {
238 return reflectionCompare(lhs, rhs, false, null, excludeFields);
239 }
240
241 /**
242 * <p>Compares two <code>Object</code>s via reflection.</p>
243 *
244 * <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
245 * is used to bypass normal access control checks. This will fail under a
246 * security manager unless the appropriate permissions are set.</p>
247 *
248 * <ul>
249 * <li>Static fields will not be compared</li>
250 * <li>If the <code>compareTransients</code> is <code>true</code>,
251 * compares transient members. Otherwise ignores them, as they
252 * are likely derived fields.</li>
253 * <li>Compares superclass fields up to and including <code>reflectUpToClass</code>.
254 * If <code>reflectUpToClass</code> is <code>null</code>, compares all superclass fields.</li>
255 * </ul>
256 *
257 * <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
258 * they are considered equal.</p>
259 *
260 * @param lhs left-hand object
261 * @param rhs right-hand object
262 * @param compareTransients whether to compare transient fields
263 * @param reflectUpToClass last superclass for which fields are compared
264 * @return a negative integer, zero, or a positive integer as <code>lhs</code>
265 * is less than, equal to, or greater than <code>rhs</code>
266 * @throws NullPointerException if either <code>lhs</code> or <code>rhs</code>
267 * (but not both) is <code>null</code>
268 * @throws ClassCastException if <code>rhs</code> is not assignment-compatible
269 * with <code>lhs</code>
270 * @since 2.0
271 */
272 public static int reflectionCompare(Object lhs, Object rhs, boolean compareTransients,
273 Class reflectUpToClass)
274 {
275 return reflectionCompare(lhs, rhs, compareTransients, reflectUpToClass, null);
276 }
277
278 /**
279 * <p>Compares two <code>Object</code>s via reflection.</p>
280 *
281 * <p>Fields can be private, thus <code>AccessibleObject.setAccessible</code>
282 * is used to bypass normal access control checks. This will fail under a
283 * security manager unless the appropriate permissions are set.</p>
284 *
285 * <ul>
286 * <li>Static fields will not be compared</li>
287 * <li>If the <code>compareTransients</code> is <code>true</code>,
288 * compares transient members. Otherwise ignores them, as they
289 * are likely derived fields.</li>
290 * <li>Compares superclass fields up to and including <code>reflectUpToClass</code>.
291 * If <code>reflectUpToClass</code> is <code>null</code>, compares all superclass fields.</li>
292 * </ul>
293 *
294 * <p>If both <code>lhs</code> and <code>rhs</code> are <code>null</code>,
295 * they are considered equal.</p>
296 *
297 * @param lhs left-hand object
298 * @param rhs right-hand object
299 * @param compareTransients whether to compare transient fields
300 * @param reflectUpToClass last superclass for which fields are compared
301 * @param excludeFields fields to exclude
302 * @return a negative integer, zero, or a positive integer as <code>lhs</code>
303 * is less than, equal to, or greater than <code>rhs</code>
304 * @throws NullPointerException if either <code>lhs</code> or <code>rhs</code>
305 * (but not both) is <code>null</code>
306 * @throws ClassCastException if <code>rhs</code> is not assignment-compatible
307 * with <code>lhs</code>
308 * @since 2.2
309 */
310 public static int reflectionCompare(
311 Object lhs,
312 Object rhs,
313 boolean compareTransients,
314 Class reflectUpToClass,
315 String[] excludeFields) {
316
317 if (lhs == rhs) {
318 return 0;
319 }
320 if (lhs == null || rhs == null) {
321 throw new NullPointerException();
322 }
323 Class lhsClazz = lhs.getClass();
324 if (!lhsClazz.isInstance(rhs)) {
325 throw new ClassCastException();
326 }
327 CompareToBuilder compareToBuilder = new CompareToBuilder();
328 reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
329 while (lhsClazz.getSuperclass() != null && lhsClazz != reflectUpToClass) {
330 lhsClazz = lhsClazz.getSuperclass();
331 reflectionAppend(lhs, rhs, lhsClazz, compareToBuilder, compareTransients, excludeFields);
332 }
333 return compareToBuilder.toComparison();
334 }
335
336 /**
337 * <p>Appends to <code>builder</code> the comparison of <code>lhs</code>
338 * to <code>rhs</code> using the fields defined in <code>clazz</code>.</p>
339 *
340 * @param lhs left-hand object
341 * @param rhs right-hand object
342 * @param clazz <code>Class</code> that defines fields to be compared
343 * @param builder <code>CompareToBuilder</code> to append to
344 * @param useTransients whether to compare transient fields
345 * @param excludeFields fields to exclude
346 */
347 private static void reflectionAppend(
348 Object lhs,
349 Object rhs,
350 Class clazz,
351 CompareToBuilder builder,
352 boolean useTransients,
353 String[] excludeFields) {
354
355 Field[] fields = clazz.getDeclaredFields();
356 AccessibleObject.setAccessible(fields, true);
357 for (int i = 0; i < fields.length && builder.comparison == 0; i++) {
358 Field f = fields[i];
359 if (!ArrayUtils.contains(excludeFields, f.getName())
360 && (f.getName().indexOf('$') == -1)
361 && (useTransients || !Modifier.isTransient(f.getModifiers()))
362 && (!Modifier.isStatic(f.getModifiers()))) {
363 try {
364 builder.append(f.get(lhs), f.get(rhs));
365 } catch (IllegalAccessException e) {
366 // This can't happen. Would get a Security exception instead.
367 // Throw a runtime exception in case the impossible happens.
368 throw new InternalError("Unexpected IllegalAccessException");
369 }
370 }
371 }
372 }
373
374 //-----------------------------------------------------------------------
375 /**
376 * <p>Appends to the <code>builder</code> the <code>compareTo(Object)</code>
377 * result of the superclass.</p>
378 *
379 * @param superCompareTo result of calling <code>super.compareTo(Object)</code>
380 * @return this - used to chain append calls
381 * @since 2.0
382 */
383 public CompareToBuilder appendSuper(int superCompareTo) {
384 if (comparison != 0) {
385 return this;
386 }
387 comparison = superCompareTo;
388 return this;
389 }
390
391 //-----------------------------------------------------------------------
392 /**
393 * <p>Appends to the <code>builder</code> the comparison of
394 * two <code>Object</code>s.</p>
395 *
396 * <ol>
397 * <li>Check if <code>lhs == rhs</code></li>
398 * <li>Check if either <code>lhs</code> or <code>rhs</code> is <code>null</code>,
399 * a <code>null</code> object is less than a non-<code>null</code> object</li>
400 * <li>Check the object contents</li>
401 * </ol>
402 *
403 * <p><code>lhs</code> must either be an array or implement {@link Comparable}.</p>
404 *
405 * @param lhs left-hand object
406 * @param rhs right-hand object
407 * @return this - used to chain append calls
408 * @throws ClassCastException if <code>rhs</code> is not assignment-compatible
409 * with <code>lhs</code>
410 */
411 public CompareToBuilder append(Object lhs, Object rhs) {
412 return append(lhs, rhs, null);
413 }
414
415 /**
416 * <p>Appends to the <code>builder</code> the comparison of
417 * two <code>Object</code>s.</p>
418 *
419 * <ol>
420 * <li>Check if <code>lhs == rhs</code></li>
421 * <li>Check if either <code>lhs</code> or <code>rhs</code> is <code>null</code>,
422 * a <code>null</code> object is less than a non-<code>null</code> object</li>
423 * <li>Check the object contents</li>
424 * </ol>
425 *
426 * <p>If <code>lhs</code> is an array, array comparison methods will be used.
427 * Otherwise <code>comparator</code> will be used to compare the objects.
428 * If <code>comparator</code> is <code>null</code>, <code>lhs</code> must
429 * implement {@link Comparable} instead.</p>
430 *
431 * @param lhs left-hand object
432 * @param rhs right-hand object
433 * @param comparator <code>Comparator</code> used to compare the objects,
434 * <code>null</code> means treat lhs as <code>Comparable</code>
435 * @return this - used to chain append calls
436 * @throws ClassCastException if <code>rhs</code> is not assignment-compatible
437 * with <code>lhs</code>
438 * @since 2.0
439 */
440 public CompareToBuilder append(Object lhs, Object rhs, Comparator comparator) {
441 if (comparison != 0) {
442 return this;
443 }
444 if (lhs == rhs) {
445 return this;
446 }
447 if (lhs == null) {
448 comparison = -1;
449 return this;
450 }
451 if (rhs == null) {
452 comparison = +1;
453 return this;
454 }
455 if (lhs.getClass().isArray()) {
456 // switch on type of array, to dispatch to the correct handler
457 // handles multi dimensional arrays
458 // throws a ClassCastException if rhs is not the correct array type
459 if (lhs instanceof long[]) {
460 append((long[]) lhs, (long[]) rhs);
461 } else if (lhs instanceof int[]) {
462 append((int[]) lhs, (int[]) rhs);
463 } else if (lhs instanceof short[]) {
464 append((short[]) lhs, (short[]) rhs);
465 } else if (lhs instanceof char[]) {
466 append((char[]) lhs, (char[]) rhs);
467 } else if (lhs instanceof byte[]) {
468 append((byte[]) lhs, (byte[]) rhs);
469 } else if (lhs instanceof double[]) {
470 append((double[]) lhs, (double[]) rhs);
471 } else if (lhs instanceof float[]) {
472 append((float[]) lhs, (float[]) rhs);
473 } else if (lhs instanceof boolean[]) {
474 append((boolean[]) lhs, (boolean[]) rhs);
475 } else {
476 // not an array of primitives
477 // throws a ClassCastException if rhs is not an array
478 append((Object[]) lhs, (Object[]) rhs, comparator);
479 }
480 } else {
481 // the simple case, not an array, just test the element
482 if (comparator == null) {
483 comparison = ((Comparable) lhs).compareTo(rhs);
484 } else {
485 comparison = comparator.compare(lhs, rhs);
486 }
487 }
488 return this;
489 }
490
491 //-------------------------------------------------------------------------
492 /**
493 * Appends to the <code>builder</code> the comparison of
494 * two <code>long</code>s.
495 *
496 * @param lhs left-hand value
497 * @param rhs right-hand value
498 * @return this - used to chain append calls
499 */
500 public CompareToBuilder append(long lhs, long rhs) {
501 if (comparison != 0) {
502 return this;
503 }
504 comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
505 return this;
506 }
507
508 /**
509 * Appends to the <code>builder</code> the comparison of
510 * two <code>int</code>s.
511 *
512 * @param lhs left-hand value
513 * @param rhs right-hand value
514 * @return this - used to chain append calls
515 */
516 public CompareToBuilder append(int lhs, int rhs) {
517 if (comparison != 0) {
518 return this;
519 }
520 comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
521 return this;
522 }
523
524 /**
525 * Appends to the <code>builder</code> the comparison of
526 * two <code>short</code>s.
527 *
528 * @param lhs left-hand value
529 * @param rhs right-hand value
530 * @return this - used to chain append calls
531 */
532 public CompareToBuilder append(short lhs, short rhs) {
533 if (comparison != 0) {
534 return this;
535 }
536 comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
537 return this;
538 }
539
540 /**
541 * Appends to the <code>builder</code> the comparison of
542 * two <code>char</code>s.
543 *
544 * @param lhs left-hand value
545 * @param rhs right-hand value
546 * @return this - used to chain append calls
547 */
548 public CompareToBuilder append(char lhs, char rhs) {
549 if (comparison != 0) {
550 return this;
551 }
552 comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
553 return this;
554 }
555
556 /**
557 * Appends to the <code>builder</code> the comparison of
558 * two <code>byte</code>s.
559 *
560 * @param lhs left-hand value
561 * @param rhs right-hand value
562 * @return this - used to chain append calls
563 */
564 public CompareToBuilder append(byte lhs, byte rhs) {
565 if (comparison != 0) {
566 return this;
567 }
568 comparison = ((lhs < rhs) ? -1 : ((lhs > rhs) ? 1 : 0));
569 return this;
570 }
571
572 /**
573 * <p>Appends to the <code>builder</code> the comparison of
574 * two <code>double</code>s.</p>
575 *
576 * <p>This handles NaNs, Infinities, and <code>-0.0</code>.</p>
577 *
578 * <p>It is compatible with the hash code generated by
579 * <code>HashCodeBuilder</code>.</p>
580 *
581 * @param lhs left-hand value
582 * @param rhs right-hand value
583 * @return this - used to chain append calls
584 */
585 public CompareToBuilder append(double lhs, double rhs) {
586 if (comparison != 0) {
587 return this;
588 }
589 comparison = NumberUtils.compare(lhs, rhs);
590 return this;
591 }
592
593 /**
594 * <p>Appends to the <code>builder</code> the comparison of
595 * two <code>float</code>s.</p>
596 *
597 * <p>This handles NaNs, Infinities, and <code>-0.0</code>.</p>
598 *
599 * <p>It is compatible with the hash code generated by
600 * <code>HashCodeBuilder</code>.</p>
601 *
602 * @param lhs left-hand value
603 * @param rhs right-hand value
604 * @return this - used to chain append calls
605 */
606 public CompareToBuilder append(float lhs, float rhs) {
607 if (comparison != 0) {
608 return this;
609 }
610 comparison = NumberUtils.compare(lhs, rhs);
611 return this;
612 }
613
614 /**
615 * Appends to the <code>builder</code> the comparison of
616 * two <code>booleans</code>s.
617 *
618 * @param lhs left-hand value
619 * @param rhs right-hand value
620 * @return this - used to chain append calls
621 */
622 public CompareToBuilder append(boolean lhs, boolean rhs) {
623 if (comparison != 0) {
624 return this;
625 }
626 if (lhs == rhs) {
627 return this;
628 }
629 if (lhs == false) {
630 comparison = -1;
631 } else {
632 comparison = +1;
633 }
634 return this;
635 }
636
637 //-----------------------------------------------------------------------
638 /**
639 * <p>Appends to the <code>builder</code> the deep comparison of
640 * two <code>Object</code> arrays.</p>
641 *
642 * <ol>
643 * <li>Check if arrays are the same using <code>==</code></li>
644 * <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
645 * <li>Check array length, a short length array is less than a long length array</li>
646 * <li>Check array contents element by element using {@link #append(Object, Object, Comparator)}</li>
647 * </ol>
648 *
649 * <p>This method will also will be called for the top level of multi-dimensional,
650 * ragged, and multi-typed arrays.</p>
651 *
652 * @param lhs left-hand array
653 * @param rhs right-hand array
654 * @return this - used to chain append calls
655 * @throws ClassCastException if <code>rhs</code> is not assignment-compatible
656 * with <code>lhs</code>
657 */
658 public CompareToBuilder append(Object[] lhs, Object[] rhs) {
659 return append(lhs, rhs, null);
660 }
661
662 /**
663 * <p>Appends to the <code>builder</code> the deep comparison of
664 * two <code>Object</code> arrays.</p>
665 *
666 * <ol>
667 * <li>Check if arrays are the same using <code>==</code></li>
668 * <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
669 * <li>Check array length, a short length array is less than a long length array</li>
670 * <li>Check array contents element by element using {@link #append(Object, Object, Comparator)}</li>
671 * </ol>
672 *
673 * <p>This method will also will be called for the top level of multi-dimensional,
674 * ragged, and multi-typed arrays.</p>
675 *
676 * @param lhs left-hand array
677 * @param rhs right-hand array
678 * @param comparator <code>Comparator</code> to use to compare the array elements,
679 * <code>null</code> means to treat <code>lhs</code> elements as <code>Comparable</code>.
680 * @return this - used to chain append calls
681 * @throws ClassCastException if <code>rhs</code> is not assignment-compatible
682 * with <code>lhs</code>
683 * @since 2.0
684 */
685 public CompareToBuilder append(Object[] lhs, Object[] rhs, Comparator comparator) {
686 if (comparison != 0) {
687 return this;
688 }
689 if (lhs == rhs) {
690 return this;
691 }
692 if (lhs == null) {
693 comparison = -1;
694 return this;
695 }
696 if (rhs == null) {
697 comparison = +1;
698 return this;
699 }
700 if (lhs.length != rhs.length) {
701 comparison = (lhs.length < rhs.length) ? -1 : +1;
702 return this;
703 }
704 for (int i = 0; i < lhs.length && comparison == 0; i++) {
705 append(lhs[i], rhs[i], comparator);
706 }
707 return this;
708 }
709
710 /**
711 * <p>Appends to the <code>builder</code> the deep comparison of
712 * two <code>long</code> arrays.</p>
713 *
714 * <ol>
715 * <li>Check if arrays are the same using <code>==</code></li>
716 * <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
717 * <li>Check array length, a shorter length array is less than a longer length array</li>
718 * <li>Check array contents element by element using {@link #append(long, long)}</li>
719 * </ol>
720 *
721 * @param lhs left-hand array
722 * @param rhs right-hand array
723 * @return this - used to chain append calls
724 */
725 public CompareToBuilder append(long[] lhs, long[] rhs) {
726 if (comparison != 0) {
727 return this;
728 }
729 if (lhs == rhs) {
730 return this;
731 }
732 if (lhs == null) {
733 comparison = -1;
734 return this;
735 }
736 if (rhs == null) {
737 comparison = +1;
738 return this;
739 }
740 if (lhs.length != rhs.length) {
741 comparison = (lhs.length < rhs.length) ? -1 : +1;
742 return this;
743 }
744 for (int i = 0; i < lhs.length && comparison == 0; i++) {
745 append(lhs[i], rhs[i]);
746 }
747 return this;
748 }
749
750 /**
751 * <p>Appends to the <code>builder</code> the deep comparison of
752 * two <code>int</code> arrays.</p>
753 *
754 * <ol>
755 * <li>Check if arrays are the same using <code>==</code></li>
756 * <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
757 * <li>Check array length, a shorter length array is less than a longer length array</li>
758 * <li>Check array contents element by element using {@link #append(int, int)}</li>
759 * </ol>
760 *
761 * @param lhs left-hand array
762 * @param rhs right-hand array
763 * @return this - used to chain append calls
764 */
765 public CompareToBuilder append(int[] lhs, int[] rhs) {
766 if (comparison != 0) {
767 return this;
768 }
769 if (lhs == rhs) {
770 return this;
771 }
772 if (lhs == null) {
773 comparison = -1;
774 return this;
775 }
776 if (rhs == null) {
777 comparison = +1;
778 return this;
779 }
780 if (lhs.length != rhs.length) {
781 comparison = (lhs.length < rhs.length) ? -1 : +1;
782 return this;
783 }
784 for (int i = 0; i < lhs.length && comparison == 0; i++) {
785 append(lhs[i], rhs[i]);
786 }
787 return this;
788 }
789
790 /**
791 * <p>Appends to the <code>builder</code> the deep comparison of
792 * two <code>short</code> arrays.</p>
793 *
794 * <ol>
795 * <li>Check if arrays are the same using <code>==</code></li>
796 * <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
797 * <li>Check array length, a shorter length array is less than a longer length array</li>
798 * <li>Check array contents element by element using {@link #append(short, short)}</li>
799 * </ol>
800 *
801 * @param lhs left-hand array
802 * @param rhs right-hand array
803 * @return this - used to chain append calls
804 */
805 public CompareToBuilder append(short[] lhs, short[] rhs) {
806 if (comparison != 0) {
807 return this;
808 }
809 if (lhs == rhs) {
810 return this;
811 }
812 if (lhs == null) {
813 comparison = -1;
814 return this;
815 }
816 if (rhs == null) {
817 comparison = +1;
818 return this;
819 }
820 if (lhs.length != rhs.length) {
821 comparison = (lhs.length < rhs.length) ? -1 : +1;
822 return this;
823 }
824 for (int i = 0; i < lhs.length && comparison == 0; i++) {
825 append(lhs[i], rhs[i]);
826 }
827 return this;
828 }
829
830 /**
831 * <p>Appends to the <code>builder</code> the deep comparison of
832 * two <code>char</code> arrays.</p>
833 *
834 * <ol>
835 * <li>Check if arrays are the same using <code>==</code></li>
836 * <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
837 * <li>Check array length, a shorter length array is less than a longer length array</li>
838 * <li>Check array contents element by element using {@link #append(char, char)}</li>
839 * </ol>
840 *
841 * @param lhs left-hand array
842 * @param rhs right-hand array
843 * @return this - used to chain append calls
844 */
845 public CompareToBuilder append(char[] lhs, char[] rhs) {
846 if (comparison != 0) {
847 return this;
848 }
849 if (lhs == rhs) {
850 return this;
851 }
852 if (lhs == null) {
853 comparison = -1;
854 return this;
855 }
856 if (rhs == null) {
857 comparison = +1;
858 return this;
859 }
860 if (lhs.length != rhs.length) {
861 comparison = (lhs.length < rhs.length) ? -1 : +1;
862 return this;
863 }
864 for (int i = 0; i < lhs.length && comparison == 0; i++) {
865 append(lhs[i], rhs[i]);
866 }
867 return this;
868 }
869
870 /**
871 * <p>Appends to the <code>builder</code> the deep comparison of
872 * two <code>byte</code> arrays.</p>
873 *
874 * <ol>
875 * <li>Check if arrays are the same using <code>==</code></li>
876 * <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
877 * <li>Check array length, a shorter length array is less than a longer length array</li>
878 * <li>Check array contents element by element using {@link #append(byte, byte)}</li>
879 * </ol>
880 *
881 * @param lhs left-hand array
882 * @param rhs right-hand array
883 * @return this - used to chain append calls
884 */
885 public CompareToBuilder append(byte[] lhs, byte[] rhs) {
886 if (comparison != 0) {
887 return this;
888 }
889 if (lhs == rhs) {
890 return this;
891 }
892 if (lhs == null) {
893 comparison = -1;
894 return this;
895 }
896 if (rhs == null) {
897 comparison = +1;
898 return this;
899 }
900 if (lhs.length != rhs.length) {
901 comparison = (lhs.length < rhs.length) ? -1 : +1;
902 return this;
903 }
904 for (int i = 0; i < lhs.length && comparison == 0; i++) {
905 append(lhs[i], rhs[i]);
906 }
907 return this;
908 }
909
910 /**
911 * <p>Appends to the <code>builder</code> the deep comparison of
912 * two <code>double</code> arrays.</p>
913 *
914 * <ol>
915 * <li>Check if arrays are the same using <code>==</code></li>
916 * <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
917 * <li>Check array length, a shorter length array is less than a longer length array</li>
918 * <li>Check array contents element by element using {@link #append(double, double)}</li>
919 * </ol>
920 *
921 * @param lhs left-hand array
922 * @param rhs right-hand array
923 * @return this - used to chain append calls
924 */
925 public CompareToBuilder append(double[] lhs, double[] rhs) {
926 if (comparison != 0) {
927 return this;
928 }
929 if (lhs == rhs) {
930 return this;
931 }
932 if (lhs == null) {
933 comparison = -1;
934 return this;
935 }
936 if (rhs == null) {
937 comparison = +1;
938 return this;
939 }
940 if (lhs.length != rhs.length) {
941 comparison = (lhs.length < rhs.length) ? -1 : +1;
942 return this;
943 }
944 for (int i = 0; i < lhs.length && comparison == 0; i++) {
945 append(lhs[i], rhs[i]);
946 }
947 return this;
948 }
949
950 /**
951 * <p>Appends to the <code>builder</code> the deep comparison of
952 * two <code>float</code> arrays.</p>
953 *
954 * <ol>
955 * <li>Check if arrays are the same using <code>==</code></li>
956 * <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
957 * <li>Check array length, a shorter length array is less than a longer length array</li>
958 * <li>Check array contents element by element using {@link #append(float, float)}</li>
959 * </ol>
960 *
961 * @param lhs left-hand array
962 * @param rhs right-hand array
963 * @return this - used to chain append calls
964 */
965 public CompareToBuilder append(float[] lhs, float[] rhs) {
966 if (comparison != 0) {
967 return this;
968 }
969 if (lhs == rhs) {
970 return this;
971 }
972 if (lhs == null) {
973 comparison = -1;
974 return this;
975 }
976 if (rhs == null) {
977 comparison = +1;
978 return this;
979 }
980 if (lhs.length != rhs.length) {
981 comparison = (lhs.length < rhs.length) ? -1 : +1;
982 return this;
983 }
984 for (int i = 0; i < lhs.length && comparison == 0; i++) {
985 append(lhs[i], rhs[i]);
986 }
987 return this;
988 }
989
990 /**
991 * <p>Appends to the <code>builder</code> the deep comparison of
992 * two <code>boolean</code> arrays.</p>
993 *
994 * <ol>
995 * <li>Check if arrays are the same using <code>==</code></li>
996 * <li>Check if for <code>null</code>, <code>null</code> is less than non-<code>null</code></li>
997 * <li>Check array length, a shorter length array is less than a longer length array</li>
998 * <li>Check array contents element by element using {@link #append(boolean, boolean)}</li>
999 * </ol>
1000 *
1001 * @param lhs left-hand array
1002 * @param rhs right-hand array
1003 * @return this - used to chain append calls
1004 */
1005 public CompareToBuilder append(boolean[] lhs, boolean[] rhs) {
1006 if (comparison != 0) {
1007 return this;
1008 }
1009 if (lhs == rhs) {
1010 return this;
1011 }
1012 if (lhs == null) {
1013 comparison = -1;
1014 return this;
1015 }
1016 if (rhs == null) {
1017 comparison = +1;
1018 return this;
1019 }
1020 if (lhs.length != rhs.length) {
1021 comparison = (lhs.length < rhs.length) ? -1 : +1;
1022 return this;
1023 }
1024 for (int i = 0; i < lhs.length && comparison == 0; i++) {
1025 append(lhs[i], rhs[i]);
1026 }
1027 return this;
1028 }
1029
1030 //-----------------------------------------------------------------------
1031 /**
1032 * Returns a negative integer, a positive integer, or zero as
1033 * the <code>builder</code> has judged the "left-hand" side
1034 * as less than, greater than, or equal to the "right-hand"
1035 * side.
1036 *
1037 * @return final comparison result
1038 */
1039 public int toComparison() {
1040 return comparison;
1041 }
1042
1043}
1044
Note: See TracBrowser for help on using the repository browser.