source: src/main/java/agents/org/apache/commons/lang/builder/EqualsBuilder.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: 30.1 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;
23
24import agents.org.apache.commons.lang.ArrayUtils;
25
26/**
27 * <p>Assists in implementing {@link Object#equals(Object)} methods.</p>
28 *
29 * <p> This class provides methods to build a good equals method for any
30 * class. It follows rules laid out in
31 * <a href="http://java.sun.com/docs/books/effective/index.html">Effective Java</a>
32 * , by Joshua Bloch. In particular the rule for comparing <code>doubles</code>,
33 * <code>floats</code>, and arrays can be tricky. Also, making sure that
34 * <code>equals()</code> and <code>hashCode()</code> are consistent can be
35 * difficult.</p>
36 *
37 * <p>Two Objects that compare as equals must generate the same hash code,
38 * but two Objects with the same hash code do not have to be equal.</p>
39 *
40 * <p>All relevant fields should be included in the calculation of equals.
41 * Derived fields may be ignored. In particular, any field used in
42 * generating a hash code must be used in the equals method, and vice
43 * versa.</p>
44 *
45 * <p>Typical use for the code is as follows:</p>
46 * <pre>
47 * public boolean equals(Object obj) {
48 * if (obj == null) { return false; }
49 * if (obj == this) { return true; }
50 * if (obj.getClass() != getClass()) {
51 * return false;
52 * }
53 * MyClass rhs = (MyClass) obj;
54 * return new EqualsBuilder()
55 * .appendSuper(super.equals(obj))
56 * .append(field1, rhs.field1)
57 * .append(field2, rhs.field2)
58 * .append(field3, rhs.field3)
59 * .isEquals();
60 * }
61 * </pre>
62 *
63 * <p> Alternatively, there is a method that uses reflection to determine
64 * the fields to test. Because these fields are usually private, the method,
65 * <code>reflectionEquals</code>, uses <code>AccessibleObject.setAccessible</code> to
66 * change the visibility of the fields. This will fail under a security
67 * manager, unless the appropriate permissions are set up correctly. It is
68 * also slower than testing explicitly.</p>
69 *
70 * <p> A typical invocation for this method would look like:</p>
71 * <pre>
72 * public boolean equals(Object obj) {
73 * return EqualsBuilder.reflectionEquals(this, obj);
74 * }
75 * </pre>
76 *
77 * @author Apache Software Foundation
78 * @author <a href="mailto:steve.downey@netfolio.com">Steve Downey</a>
79 * @author Gary Gregory
80 * @author Pete Gieser
81 * @author Arun Mammen Thomas
82 * @since 1.0
83 * @version $Id: EqualsBuilder.java 905707 2010-02-02 16:59:59Z niallp $
84 */
85public class EqualsBuilder {
86
87 /**
88 * If the fields tested are equals.
89 * The default value is <code>true</code>.
90 */
91 private boolean isEquals = true;
92
93 /**
94 * <p>Constructor for EqualsBuilder.</p>
95 *
96 * <p>Starts off assuming that equals is <code>true</code>.</p>
97 * @see Object#equals(Object)
98 */
99 public EqualsBuilder() {
100 // do nothing for now.
101 }
102
103 //-------------------------------------------------------------------------
104
105 /**
106 * <p>This method uses reflection to determine if the two <code>Object</code>s
107 * are equal.</p>
108 *
109 * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private
110 * fields. This means that it will throw a security exception if run under
111 * a security manager, if the permissions are not set up correctly. It is also
112 * not as efficient as testing explicitly.</p>
113 *
114 * <p>Transient members will be not be tested, as they are likely derived
115 * fields, and not part of the value of the Object.</p>
116 *
117 * <p>Static fields will not be tested. Superclass fields will be included.</p>
118 *
119 * @param lhs <code>this</code> object
120 * @param rhs the other object
121 * @return <code>true</code> if the two Objects have tested equals.
122 */
123 public static boolean reflectionEquals(Object lhs, Object rhs) {
124 return reflectionEquals(lhs, rhs, false, null, null);
125 }
126
127 /**
128 * <p>This method uses reflection to determine if the two <code>Object</code>s
129 * are equal.</p>
130 *
131 * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private
132 * fields. This means that it will throw a security exception if run under
133 * a security manager, if the permissions are not set up correctly. It is also
134 * not as efficient as testing explicitly.</p>
135 *
136 * <p>Transient members will be not be tested, as they are likely derived
137 * fields, and not part of the value of the Object.</p>
138 *
139 * <p>Static fields will not be tested. Superclass fields will be included.</p>
140 *
141 * @param lhs <code>this</code> object
142 * @param rhs the other object
143 * @param excludeFields Collection of String field names to exclude from testing
144 * @return <code>true</code> if the two Objects have tested equals.
145 */
146 public static boolean reflectionEquals(Object lhs, Object rhs, Collection /*String*/ excludeFields) {
147 return reflectionEquals(lhs, rhs, ReflectionToStringBuilder.toNoNullStringArray(excludeFields));
148 }
149
150 /**
151 * <p>This method uses reflection to determine if the two <code>Object</code>s
152 * are equal.</p>
153 *
154 * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private
155 * fields. This means that it will throw a security exception if run under
156 * a security manager, if the permissions are not set up correctly. It is also
157 * not as efficient as testing explicitly.</p>
158 *
159 * <p>Transient members will be not be tested, as they are likely derived
160 * fields, and not part of the value of the Object.</p>
161 *
162 * <p>Static fields will not be tested. Superclass fields will be included.</p>
163 *
164 * @param lhs <code>this</code> object
165 * @param rhs the other object
166 * @param excludeFields array of field names to exclude from testing
167 * @return <code>true</code> if the two Objects have tested equals.
168 */
169 public static boolean reflectionEquals(Object lhs, Object rhs, String[] excludeFields) {
170 return reflectionEquals(lhs, rhs, false, null, excludeFields);
171 }
172
173 /**
174 * <p>This method uses reflection to determine if the two <code>Object</code>s
175 * are equal.</p>
176 *
177 * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private
178 * fields. This means that it will throw a security exception if run under
179 * a security manager, if the permissions are not set up correctly. It is also
180 * not as efficient as testing explicitly.</p>
181 *
182 * <p>If the TestTransients parameter is set to <code>true</code>, transient
183 * members will be tested, otherwise they are ignored, as they are likely
184 * derived fields, and not part of the value of the <code>Object</code>.</p>
185 *
186 * <p>Static fields will not be tested. Superclass fields will be included.</p>
187 *
188 * @param lhs <code>this</code> object
189 * @param rhs the other object
190 * @param testTransients whether to include transient fields
191 * @return <code>true</code> if the two Objects have tested equals.
192 */
193 public static boolean reflectionEquals(Object lhs, Object rhs, boolean testTransients) {
194 return reflectionEquals(lhs, rhs, testTransients, null, null);
195 }
196
197 /**
198 * <p>This method uses reflection to determine if the two <code>Object</code>s
199 * are equal.</p>
200 *
201 * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private
202 * fields. This means that it will throw a security exception if run under
203 * a security manager, if the permissions are not set up correctly. It is also
204 * not as efficient as testing explicitly.</p>
205 *
206 * <p>If the testTransients parameter is set to <code>true</code>, transient
207 * members will be tested, otherwise they are ignored, as they are likely
208 * derived fields, and not part of the value of the <code>Object</code>.</p>
209 *
210 * <p>Static fields will not be included. Superclass fields will be appended
211 * up to and including the specified superclass. A null superclass is treated
212 * as java.lang.Object.</p>
213 *
214 * @param lhs <code>this</code> object
215 * @param rhs the other object
216 * @param testTransients whether to include transient fields
217 * @param reflectUpToClass the superclass to reflect up to (inclusive),
218 * may be <code>null</code>
219 * @return <code>true</code> if the two Objects have tested equals.
220 * @since 2.0
221 */
222 public static boolean reflectionEquals(Object lhs, Object rhs, boolean testTransients, Class reflectUpToClass) {
223 return reflectionEquals(lhs, rhs, testTransients, reflectUpToClass, null);
224 }
225
226 /**
227 * <p>This method uses reflection to determine if the two <code>Object</code>s
228 * are equal.</p>
229 *
230 * <p>It uses <code>AccessibleObject.setAccessible</code> to gain access to private
231 * fields. This means that it will throw a security exception if run under
232 * a security manager, if the permissions are not set up correctly. It is also
233 * not as efficient as testing explicitly.</p>
234 *
235 * <p>If the testTransients parameter is set to <code>true</code>, transient
236 * members will be tested, otherwise they are ignored, as they are likely
237 * derived fields, and not part of the value of the <code>Object</code>.</p>
238 *
239 * <p>Static fields will not be included. Superclass fields will be appended
240 * up to and including the specified superclass. A null superclass is treated
241 * as java.lang.Object.</p>
242 *
243 * @param lhs <code>this</code> object
244 * @param rhs the other object
245 * @param testTransients whether to include transient fields
246 * @param reflectUpToClass the superclass to reflect up to (inclusive),
247 * may be <code>null</code>
248 * @param excludeFields array of field names to exclude from testing
249 * @return <code>true</code> if the two Objects have tested equals.
250 * @since 2.0
251 */
252 public static boolean reflectionEquals(Object lhs, Object rhs, boolean testTransients, Class reflectUpToClass,
253 String[] excludeFields) {
254 if (lhs == rhs) {
255 return true;
256 }
257 if (lhs == null || rhs == null) {
258 return false;
259 }
260 // Find the leaf class since there may be transients in the leaf
261 // class or in classes between the leaf and root.
262 // If we are not testing transients or a subclass has no ivars,
263 // then a subclass can test equals to a superclass.
264 Class lhsClass = lhs.getClass();
265 Class rhsClass = rhs.getClass();
266 Class testClass;
267 if (lhsClass.isInstance(rhs)) {
268 testClass = lhsClass;
269 if (!rhsClass.isInstance(lhs)) {
270 // rhsClass is a subclass of lhsClass
271 testClass = rhsClass;
272 }
273 } else if (rhsClass.isInstance(lhs)) {
274 testClass = rhsClass;
275 if (!lhsClass.isInstance(rhs)) {
276 // lhsClass is a subclass of rhsClass
277 testClass = lhsClass;
278 }
279 } else {
280 // The two classes are not related.
281 return false;
282 }
283 EqualsBuilder equalsBuilder = new EqualsBuilder();
284 try {
285 reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients, excludeFields);
286 while (testClass.getSuperclass() != null && testClass != reflectUpToClass) {
287 testClass = testClass.getSuperclass();
288 reflectionAppend(lhs, rhs, testClass, equalsBuilder, testTransients, excludeFields);
289 }
290 } catch (IllegalArgumentException e) {
291 // In this case, we tried to test a subclass vs. a superclass and
292 // the subclass has ivars or the ivars are transient and
293 // we are testing transients.
294 // If a subclass has ivars that we are trying to test them, we get an
295 // exception and we know that the objects are not equal.
296 return false;
297 }
298 return equalsBuilder.isEquals();
299 }
300
301 /**
302 * <p>Appends the fields and values defined by the given object of the
303 * given Class.</p>
304 *
305 * @param lhs the left hand object
306 * @param rhs the right hand object
307 * @param clazz the class to append details of
308 * @param builder the builder to append to
309 * @param useTransients whether to test transient fields
310 * @param excludeFields array of field names to exclude from testing
311 */
312 private static void reflectionAppend(
313 Object lhs,
314 Object rhs,
315 Class clazz,
316 EqualsBuilder builder,
317 boolean useTransients,
318 String[] excludeFields) {
319 Field[] fields = clazz.getDeclaredFields();
320 AccessibleObject.setAccessible(fields, true);
321 for (int i = 0; i < fields.length && builder.isEquals; i++) {
322 Field f = fields[i];
323 if (!ArrayUtils.contains(excludeFields, f.getName())
324 && (f.getName().indexOf('$') == -1)
325 && (useTransients || !Modifier.isTransient(f.getModifiers()))
326 && (!Modifier.isStatic(f.getModifiers()))) {
327 try {
328 builder.append(f.get(lhs), f.get(rhs));
329 } catch (IllegalAccessException e) {
330 //this can't happen. Would get a Security exception instead
331 //throw a runtime exception in case the impossible happens.
332 throw new InternalError("Unexpected IllegalAccessException");
333 }
334 }
335 }
336 }
337
338 //-------------------------------------------------------------------------
339
340 /**
341 * <p>Adds the result of <code>super.equals()</code> to this builder.</p>
342 *
343 * @param superEquals the result of calling <code>super.equals()</code>
344 * @return EqualsBuilder - used to chain calls.
345 * @since 2.0
346 */
347 public EqualsBuilder appendSuper(boolean superEquals) {
348 if (isEquals == false) {
349 return this;
350 }
351 isEquals = superEquals;
352 return this;
353 }
354
355 //-------------------------------------------------------------------------
356
357 /**
358 * <p>Test if two <code>Object</code>s are equal using their
359 * <code>equals</code> method.</p>
360 *
361 * @param lhs the left hand object
362 * @param rhs the right hand object
363 * @return EqualsBuilder - used to chain calls.
364 */
365 public EqualsBuilder append(Object lhs, Object rhs) {
366 if (isEquals == false) {
367 return this;
368 }
369 if (lhs == rhs) {
370 return this;
371 }
372 if (lhs == null || rhs == null) {
373 this.setEquals(false);
374 return this;
375 }
376 Class lhsClass = lhs.getClass();
377 if (!lhsClass.isArray()) {
378 // The simple case, not an array, just test the element
379 isEquals = lhs.equals(rhs);
380 } else if (lhs.getClass() != rhs.getClass()) {
381 // Here when we compare different dimensions, for example: a boolean[][] to a boolean[]
382 this.setEquals(false);
383 }
384 // 'Switch' on type of array, to dispatch to the correct handler
385 // This handles multi dimensional arrays of the same depth
386 else if (lhs instanceof long[]) {
387 append((long[]) lhs, (long[]) rhs);
388 } else if (lhs instanceof int[]) {
389 append((int[]) lhs, (int[]) rhs);
390 } else if (lhs instanceof short[]) {
391 append((short[]) lhs, (short[]) rhs);
392 } else if (lhs instanceof char[]) {
393 append((char[]) lhs, (char[]) rhs);
394 } else if (lhs instanceof byte[]) {
395 append((byte[]) lhs, (byte[]) rhs);
396 } else if (lhs instanceof double[]) {
397 append((double[]) lhs, (double[]) rhs);
398 } else if (lhs instanceof float[]) {
399 append((float[]) lhs, (float[]) rhs);
400 } else if (lhs instanceof boolean[]) {
401 append((boolean[]) lhs, (boolean[]) rhs);
402 } else {
403 // Not an array of primitives
404 append((Object[]) lhs, (Object[]) rhs);
405 }
406 return this;
407 }
408
409 /**
410 * <p>
411 * Test if two <code>long</code> s are equal.
412 * </p>
413 *
414 * @param lhs
415 * the left hand <code>long</code>
416 * @param rhs
417 * the right hand <code>long</code>
418 * @return EqualsBuilder - used to chain calls.
419 */
420 public EqualsBuilder append(long lhs, long rhs) {
421 if (isEquals == false) {
422 return this;
423 }
424 isEquals = (lhs == rhs);
425 return this;
426 }
427
428 /**
429 * <p>Test if two <code>int</code>s are equal.</p>
430 *
431 * @param lhs the left hand <code>int</code>
432 * @param rhs the right hand <code>int</code>
433 * @return EqualsBuilder - used to chain calls.
434 */
435 public EqualsBuilder append(int lhs, int rhs) {
436 if (isEquals == false) {
437 return this;
438 }
439 isEquals = (lhs == rhs);
440 return this;
441 }
442
443 /**
444 * <p>Test if two <code>short</code>s are equal.</p>
445 *
446 * @param lhs the left hand <code>short</code>
447 * @param rhs the right hand <code>short</code>
448 * @return EqualsBuilder - used to chain calls.
449 */
450 public EqualsBuilder append(short lhs, short rhs) {
451 if (isEquals == false) {
452 return this;
453 }
454 isEquals = (lhs == rhs);
455 return this;
456 }
457
458 /**
459 * <p>Test if two <code>char</code>s are equal.</p>
460 *
461 * @param lhs the left hand <code>char</code>
462 * @param rhs the right hand <code>char</code>
463 * @return EqualsBuilder - used to chain calls.
464 */
465 public EqualsBuilder append(char lhs, char rhs) {
466 if (isEquals == false) {
467 return this;
468 }
469 isEquals = (lhs == rhs);
470 return this;
471 }
472
473 /**
474 * <p>Test if two <code>byte</code>s are equal.</p>
475 *
476 * @param lhs the left hand <code>byte</code>
477 * @param rhs the right hand <code>byte</code>
478 * @return EqualsBuilder - used to chain calls.
479 */
480 public EqualsBuilder append(byte lhs, byte rhs) {
481 if (isEquals == false) {
482 return this;
483 }
484 isEquals = (lhs == rhs);
485 return this;
486 }
487
488 /**
489 * <p>Test if two <code>double</code>s are equal by testing that the
490 * pattern of bits returned by <code>doubleToLong</code> are equal.</p>
491 *
492 * <p>This handles NaNs, Infinities, and <code>-0.0</code>.</p>
493 *
494 * <p>It is compatible with the hash code generated by
495 * <code>HashCodeBuilder</code>.</p>
496 *
497 * @param lhs the left hand <code>double</code>
498 * @param rhs the right hand <code>double</code>
499 * @return EqualsBuilder - used to chain calls.
500 */
501 public EqualsBuilder append(double lhs, double rhs) {
502 if (isEquals == false) {
503 return this;
504 }
505 return append(Double.doubleToLongBits(lhs), Double.doubleToLongBits(rhs));
506 }
507
508 /**
509 * <p>Test if two <code>float</code>s are equal byt testing that the
510 * pattern of bits returned by doubleToLong are equal.</p>
511 *
512 * <p>This handles NaNs, Infinities, and <code>-0.0</code>.</p>
513 *
514 * <p>It is compatible with the hash code generated by
515 * <code>HashCodeBuilder</code>.</p>
516 *
517 * @param lhs the left hand <code>float</code>
518 * @param rhs the right hand <code>float</code>
519 * @return EqualsBuilder - used to chain calls.
520 */
521 public EqualsBuilder append(float lhs, float rhs) {
522 if (isEquals == false) {
523 return this;
524 }
525 return append(Float.floatToIntBits(lhs), Float.floatToIntBits(rhs));
526 }
527
528 /**
529 * <p>Test if two <code>booleans</code>s are equal.</p>
530 *
531 * @param lhs the left hand <code>boolean</code>
532 * @param rhs the right hand <code>boolean</code>
533 * @return EqualsBuilder - used to chain calls.
534 */
535 public EqualsBuilder append(boolean lhs, boolean rhs) {
536 if (isEquals == false) {
537 return this;
538 }
539 isEquals = (lhs == rhs);
540 return this;
541 }
542
543 /**
544 * <p>Performs a deep comparison of two <code>Object</code> arrays.</p>
545 *
546 * <p>This also will be called for the top level of
547 * multi-dimensional, ragged, and multi-typed arrays.</p>
548 *
549 * @param lhs the left hand <code>Object[]</code>
550 * @param rhs the right hand <code>Object[]</code>
551 * @return EqualsBuilder - used to chain calls.
552 */
553 public EqualsBuilder append(Object[] lhs, Object[] rhs) {
554 if (isEquals == false) {
555 return this;
556 }
557 if (lhs == rhs) {
558 return this;
559 }
560 if (lhs == null || rhs == null) {
561 this.setEquals(false);
562 return this;
563 }
564 if (lhs.length != rhs.length) {
565 this.setEquals(false);
566 return this;
567 }
568 for (int i = 0; i < lhs.length && isEquals; ++i) {
569 append(lhs[i], rhs[i]);
570 }
571 return this;
572 }
573
574 /**
575 * <p>Deep comparison of array of <code>long</code>. Length and all
576 * values are compared.</p>
577 *
578 * <p>The method {@link #append(long, long)} is used.</p>
579 *
580 * @param lhs the left hand <code>long[]</code>
581 * @param rhs the right hand <code>long[]</code>
582 * @return EqualsBuilder - used to chain calls.
583 */
584 public EqualsBuilder append(long[] lhs, long[] rhs) {
585 if (isEquals == false) {
586 return this;
587 }
588 if (lhs == rhs) {
589 return this;
590 }
591 if (lhs == null || rhs == null) {
592 this.setEquals(false);
593 return this;
594 }
595 if (lhs.length != rhs.length) {
596 this.setEquals(false);
597 return this;
598 }
599 for (int i = 0; i < lhs.length && isEquals; ++i) {
600 append(lhs[i], rhs[i]);
601 }
602 return this;
603 }
604
605 /**
606 * <p>Deep comparison of array of <code>int</code>. Length and all
607 * values are compared.</p>
608 *
609 * <p>The method {@link #append(int, int)} is used.</p>
610 *
611 * @param lhs the left hand <code>int[]</code>
612 * @param rhs the right hand <code>int[]</code>
613 * @return EqualsBuilder - used to chain calls.
614 */
615 public EqualsBuilder append(int[] lhs, int[] rhs) {
616 if (isEquals == false) {
617 return this;
618 }
619 if (lhs == rhs) {
620 return this;
621 }
622 if (lhs == null || rhs == null) {
623 this.setEquals(false);
624 return this;
625 }
626 if (lhs.length != rhs.length) {
627 this.setEquals(false);
628 return this;
629 }
630 for (int i = 0; i < lhs.length && isEquals; ++i) {
631 append(lhs[i], rhs[i]);
632 }
633 return this;
634 }
635
636 /**
637 * <p>Deep comparison of array of <code>short</code>. Length and all
638 * values are compared.</p>
639 *
640 * <p>The method {@link #append(short, short)} is used.</p>
641 *
642 * @param lhs the left hand <code>short[]</code>
643 * @param rhs the right hand <code>short[]</code>
644 * @return EqualsBuilder - used to chain calls.
645 */
646 public EqualsBuilder append(short[] lhs, short[] rhs) {
647 if (isEquals == false) {
648 return this;
649 }
650 if (lhs == rhs) {
651 return this;
652 }
653 if (lhs == null || rhs == null) {
654 this.setEquals(false);
655 return this;
656 }
657 if (lhs.length != rhs.length) {
658 this.setEquals(false);
659 return this;
660 }
661 for (int i = 0; i < lhs.length && isEquals; ++i) {
662 append(lhs[i], rhs[i]);
663 }
664 return this;
665 }
666
667 /**
668 * <p>Deep comparison of array of <code>char</code>. Length and all
669 * values are compared.</p>
670 *
671 * <p>The method {@link #append(char, char)} is used.</p>
672 *
673 * @param lhs the left hand <code>char[]</code>
674 * @param rhs the right hand <code>char[]</code>
675 * @return EqualsBuilder - used to chain calls.
676 */
677 public EqualsBuilder append(char[] lhs, char[] rhs) {
678 if (isEquals == false) {
679 return this;
680 }
681 if (lhs == rhs) {
682 return this;
683 }
684 if (lhs == null || rhs == null) {
685 this.setEquals(false);
686 return this;
687 }
688 if (lhs.length != rhs.length) {
689 this.setEquals(false);
690 return this;
691 }
692 for (int i = 0; i < lhs.length && isEquals; ++i) {
693 append(lhs[i], rhs[i]);
694 }
695 return this;
696 }
697
698 /**
699 * <p>Deep comparison of array of <code>byte</code>. Length and all
700 * values are compared.</p>
701 *
702 * <p>The method {@link #append(byte, byte)} is used.</p>
703 *
704 * @param lhs the left hand <code>byte[]</code>
705 * @param rhs the right hand <code>byte[]</code>
706 * @return EqualsBuilder - used to chain calls.
707 */
708 public EqualsBuilder append(byte[] lhs, byte[] rhs) {
709 if (isEquals == false) {
710 return this;
711 }
712 if (lhs == rhs) {
713 return this;
714 }
715 if (lhs == null || rhs == null) {
716 this.setEquals(false);
717 return this;
718 }
719 if (lhs.length != rhs.length) {
720 this.setEquals(false);
721 return this;
722 }
723 for (int i = 0; i < lhs.length && isEquals; ++i) {
724 append(lhs[i], rhs[i]);
725 }
726 return this;
727 }
728
729 /**
730 * <p>Deep comparison of array of <code>double</code>. Length and all
731 * values are compared.</p>
732 *
733 * <p>The method {@link #append(double, double)} is used.</p>
734 *
735 * @param lhs the left hand <code>double[]</code>
736 * @param rhs the right hand <code>double[]</code>
737 * @return EqualsBuilder - used to chain calls.
738 */
739 public EqualsBuilder append(double[] lhs, double[] rhs) {
740 if (isEquals == false) {
741 return this;
742 }
743 if (lhs == rhs) {
744 return this;
745 }
746 if (lhs == null || rhs == null) {
747 this.setEquals(false);
748 return this;
749 }
750 if (lhs.length != rhs.length) {
751 this.setEquals(false);
752 return this;
753 }
754 for (int i = 0; i < lhs.length && isEquals; ++i) {
755 append(lhs[i], rhs[i]);
756 }
757 return this;
758 }
759
760 /**
761 * <p>Deep comparison of array of <code>float</code>. Length and all
762 * values are compared.</p>
763 *
764 * <p>The method {@link #append(float, float)} is used.</p>
765 *
766 * @param lhs the left hand <code>float[]</code>
767 * @param rhs the right hand <code>float[]</code>
768 * @return EqualsBuilder - used to chain calls.
769 */
770 public EqualsBuilder append(float[] lhs, float[] rhs) {
771 if (isEquals == false) {
772 return this;
773 }
774 if (lhs == rhs) {
775 return this;
776 }
777 if (lhs == null || rhs == null) {
778 this.setEquals(false);
779 return this;
780 }
781 if (lhs.length != rhs.length) {
782 this.setEquals(false);
783 return this;
784 }
785 for (int i = 0; i < lhs.length && isEquals; ++i) {
786 append(lhs[i], rhs[i]);
787 }
788 return this;
789 }
790
791 /**
792 * <p>Deep comparison of array of <code>boolean</code>. Length and all
793 * values are compared.</p>
794 *
795 * <p>The method {@link #append(boolean, boolean)} is used.</p>
796 *
797 * @param lhs the left hand <code>boolean[]</code>
798 * @param rhs the right hand <code>boolean[]</code>
799 * @return EqualsBuilder - used to chain calls.
800 */
801 public EqualsBuilder append(boolean[] lhs, boolean[] rhs) {
802 if (isEquals == false) {
803 return this;
804 }
805 if (lhs == rhs) {
806 return this;
807 }
808 if (lhs == null || rhs == null) {
809 this.setEquals(false);
810 return this;
811 }
812 if (lhs.length != rhs.length) {
813 this.setEquals(false);
814 return this;
815 }
816 for (int i = 0; i < lhs.length && isEquals; ++i) {
817 append(lhs[i], rhs[i]);
818 }
819 return this;
820 }
821
822 /**
823 * <p>Returns <code>true</code> if the fields that have been checked
824 * are all equal.</p>
825 *
826 * @return boolean
827 */
828 public boolean isEquals() {
829 return this.isEquals;
830 }
831
832 /**
833 * Sets the <code>isEquals</code> value.
834 *
835 * @param isEquals The value to set.
836 * @since 2.1
837 */
838 protected void setEquals(boolean isEquals) {
839 this.isEquals = isEquals;
840 }
841
842 /**
843 * Reset the EqualsBuilder so you can use the same object again
844 * @since 2.5
845 */
846 public void reset() {
847 this.isEquals = true;
848 }
849}
Note: See TracBrowser for help on using the repository browser.