001 /*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements. See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License. You may obtain a copy of the License at
008 *
009 * http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017 package org.apache.commons.lang3;
018
019 import java.io.Serializable;
020 import java.lang.reflect.Array;
021 import java.lang.reflect.InvocationTargetException;
022 import java.lang.reflect.Method;
023 import java.util.Collections;
024 import java.util.Comparator;
025 import java.util.HashMap;
026 import java.util.Map;
027 import java.util.TreeSet;
028
029 import org.apache.commons.lang3.exception.CloneFailedException;
030 import org.apache.commons.lang3.mutable.MutableInt;
031
032 /**
033 * <p>Operations on {@code Object}.</p>
034 *
035 * <p>This class tries to handle {@code null} input gracefully.
036 * An exception will generally not be thrown for a {@code null} input.
037 * Each method documents its behaviour in more detail.</p>
038 *
039 * <p>#ThreadSafe#</p>
040 * @since 1.0
041 * @version $Id: ObjectUtils.java 1153350 2011-08-03 05:29:21Z bayard $
042 */
043 //@Immutable
044 public class ObjectUtils {
045
046 /**
047 * <p>Singleton used as a {@code null} placeholder where
048 * {@code null} has another meaning.</p>
049 *
050 * <p>For example, in a {@code HashMap} the
051 * {@link java.util.HashMap#get(java.lang.Object)} method returns
052 * {@code null} if the {@code Map} contains {@code null} or if there
053 * is no matching key. The {@code Null} placeholder can be used to
054 * distinguish between these two cases.</p>
055 *
056 * <p>Another example is {@code Hashtable}, where {@code null}
057 * cannot be stored.</p>
058 *
059 * <p>This instance is Serializable.</p>
060 */
061 public static final Null NULL = new Null();
062
063 /**
064 * <p>{@code ObjectUtils} instances should NOT be constructed in
065 * standard programming. Instead, the static methods on the class should
066 * be used, such as {@code ObjectUtils.defaultIfNull("a","b");}.</p>
067 *
068 * <p>This constructor is public to permit tools that require a JavaBean
069 * instance to operate.</p>
070 */
071 public ObjectUtils() {
072 super();
073 }
074
075 // Defaulting
076 //-----------------------------------------------------------------------
077 /**
078 * <p>Returns a default value if the object passed is {@code null}.</p>
079 *
080 * <pre>
081 * ObjectUtils.defaultIfNull(null, null) = null
082 * ObjectUtils.defaultIfNull(null, "") = ""
083 * ObjectUtils.defaultIfNull(null, "zz") = "zz"
084 * ObjectUtils.defaultIfNull("abc", *) = "abc"
085 * ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
086 * </pre>
087 *
088 * @param <T> the type of the object
089 * @param object the {@code Object} to test, may be {@code null}
090 * @param defaultValue the default value to return, may be {@code null}
091 * @return {@code object} if it is not {@code null}, defaultValue otherwise
092 */
093 public static <T> T defaultIfNull(T object, T defaultValue) {
094 return object != null ? object : defaultValue;
095 }
096
097 /**
098 * <p>Returns the first value in the array which is not {@code null}.
099 * If all the values are {@code null} or the array is {@code null}
100 * or empty then {@code null} is returned.</p>
101 *
102 * <pre>
103 * ObjectUtils.firstNonNull(null, null) = null
104 * ObjectUtils.firstNonNull(null, "") = ""
105 * ObjectUtils.firstNonNull(null, null, "") = ""
106 * ObjectUtils.firstNonNull(null, "zz") = "zz"
107 * ObjectUtils.firstNonNull("abc", *) = "abc"
108 * ObjectUtils.firstNonNull(null, "xyz", *) = "xyz"
109 * ObjectUtils.firstNonNull(Boolean.TRUE, *) = Boolean.TRUE
110 * ObjectUtils.firstNonNull() = null
111 * </pre>
112 *
113 * @param <T> the component type of the array
114 * @param values the values to test, may be {@code null} or empty
115 * @return the first value from {@code values} which is not {@code null},
116 * or {@code null} if there are no non-null values
117 * @since 3.0
118 */
119 public static <T> T firstNonNull(T... values) {
120 if (values != null) {
121 for (T val : values) {
122 if (val != null) {
123 return val;
124 }
125 }
126 }
127 return null;
128 }
129
130 // Null-safe equals/hashCode
131 //-----------------------------------------------------------------------
132 /**
133 * <p>Compares two objects for equality, where either one or both
134 * objects may be {@code null}.</p>
135 *
136 * <pre>
137 * ObjectUtils.equals(null, null) = true
138 * ObjectUtils.equals(null, "") = false
139 * ObjectUtils.equals("", null) = false
140 * ObjectUtils.equals("", "") = true
141 * ObjectUtils.equals(Boolean.TRUE, null) = false
142 * ObjectUtils.equals(Boolean.TRUE, "true") = false
143 * ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE) = true
144 * ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false
145 * </pre>
146 *
147 * @param object1 the first object, may be {@code null}
148 * @param object2 the second object, may be {@code null}
149 * @return {@code true} if the values of both objects are the same
150 */
151 public static boolean equals(Object object1, Object object2) {
152 if (object1 == object2) {
153 return true;
154 }
155 if ((object1 == null) || (object2 == null)) {
156 return false;
157 }
158 return object1.equals(object2);
159 }
160
161 /**
162 * <p>Compares two objects for inequality, where either one or both
163 * objects may be {@code null}.</p>
164 *
165 * <pre>
166 * ObjectUtils.notEqual(null, null) = false
167 * ObjectUtils.notEqual(null, "") = true
168 * ObjectUtils.notEqual("", null) = true
169 * ObjectUtils.notEqual("", "") = false
170 * ObjectUtils.notEqual(Boolean.TRUE, null) = true
171 * ObjectUtils.notEqual(Boolean.TRUE, "true") = true
172 * ObjectUtils.notEqual(Boolean.TRUE, Boolean.TRUE) = false
173 * ObjectUtils.notEqual(Boolean.TRUE, Boolean.FALSE) = true
174 * </pre>
175 *
176 * @param object1 the first object, may be {@code null}
177 * @param object2 the second object, may be {@code null}
178 * @return {@code false} if the values of both objects are the same
179 */
180 public static boolean notEqual(Object object1, Object object2) {
181 return ObjectUtils.equals(object1, object2) == false;
182 }
183
184 /**
185 * <p>Gets the hash code of an object returning zero when the
186 * object is {@code null}.</p>
187 *
188 * <pre>
189 * ObjectUtils.hashCode(null) = 0
190 * ObjectUtils.hashCode(obj) = obj.hashCode()
191 * </pre>
192 *
193 * @param obj the object to obtain the hash code of, may be {@code null}
194 * @return the hash code of the object, or zero if null
195 * @since 2.1
196 */
197 public static int hashCode(Object obj) {
198 // hashCode(Object) retained for performance, as hash code is often critical
199 return (obj == null) ? 0 : obj.hashCode();
200 }
201
202 /**
203 * <p>Gets the hash code for multiple objects.</p>
204 *
205 * <p>This allows a hash code to be rapidly calculated for a number of objects.
206 * The hash code for a single object is the <em>not</em> same as {@link #hashCode(Object)}.
207 * The hash code for multiple objects is the same as that calculated by an
208 * {@code ArrayList} containing the specified objects.</p>
209 *
210 * <pre>
211 * ObjectUtils.hashCodeMulti() = 1
212 * ObjectUtils.hashCodeMulti((Object[]) null) = 1
213 * ObjectUtils.hashCodeMulti(a) = 31 + a.hashCode()
214 * ObjectUtils.hashCodeMulti(a,b) = (31 + a.hashCode()) * 31 + b.hashCode()
215 * ObjectUtils.hashCodeMulti(a,b,c) = ((31 + a.hashCode()) * 31 + b.hashCode()) * 31 + c.hashCode()
216 * </pre>
217 *
218 * @param objects the objects to obtain the hash code of, may be {@code null}
219 * @return the hash code of the objects, or zero if null
220 * @since 3.0
221 */
222 public static int hashCodeMulti(Object... objects) {
223 int hash = 1;
224 if (objects != null) {
225 for (Object object : objects) {
226 hash = hash * 31 + ObjectUtils.hashCode(object);
227 }
228 }
229 return hash;
230 }
231
232 // Identity ToString
233 //-----------------------------------------------------------------------
234 /**
235 * <p>Gets the toString that would be produced by {@code Object}
236 * if a class did not override toString itself. {@code null}
237 * will return {@code null}.</p>
238 *
239 * <pre>
240 * ObjectUtils.identityToString(null) = null
241 * ObjectUtils.identityToString("") = "java.lang.String@1e23"
242 * ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
243 * </pre>
244 *
245 * @param object the object to create a toString for, may be
246 * {@code null}
247 * @return the default toString text, or {@code null} if
248 * {@code null} passed in
249 */
250 public static String identityToString(Object object) {
251 if (object == null) {
252 return null;
253 }
254 StringBuffer buffer = new StringBuffer();
255 identityToString(buffer, object);
256 return buffer.toString();
257 }
258
259 /**
260 * <p>Appends the toString that would be produced by {@code Object}
261 * if a class did not override toString itself. {@code null}
262 * will throw a NullPointerException for either of the two parameters. </p>
263 *
264 * <pre>
265 * ObjectUtils.identityToString(buf, "") = buf.append("java.lang.String@1e23"
266 * ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa"
267 * ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa")
268 * </pre>
269 *
270 * @param buffer the buffer to append to
271 * @param object the object to create a toString for
272 * @since 2.4
273 */
274 public static void identityToString(StringBuffer buffer, Object object) {
275 if (object == null) {
276 throw new NullPointerException("Cannot get the toString of a null identity");
277 }
278 buffer.append(object.getClass().getName())
279 .append('@')
280 .append(Integer.toHexString(System.identityHashCode(object)));
281 }
282
283 // ToString
284 //-----------------------------------------------------------------------
285 /**
286 * <p>Gets the {@code toString} of an {@code Object} returning
287 * an empty string ("") if {@code null} input.</p>
288 *
289 * <pre>
290 * ObjectUtils.toString(null) = ""
291 * ObjectUtils.toString("") = ""
292 * ObjectUtils.toString("bat") = "bat"
293 * ObjectUtils.toString(Boolean.TRUE) = "true"
294 * </pre>
295 *
296 * @see StringUtils#defaultString(String)
297 * @see String#valueOf(Object)
298 * @param obj the Object to {@code toString}, may be null
299 * @return the passed in Object's toString, or nullStr if {@code null} input
300 * @since 2.0
301 */
302 public static String toString(Object obj) {
303 return obj == null ? "" : obj.toString();
304 }
305
306 /**
307 * <p>Gets the {@code toString} of an {@code Object} returning
308 * a specified text if {@code null} input.</p>
309 *
310 * <pre>
311 * ObjectUtils.toString(null, null) = null
312 * ObjectUtils.toString(null, "null") = "null"
313 * ObjectUtils.toString("", "null") = ""
314 * ObjectUtils.toString("bat", "null") = "bat"
315 * ObjectUtils.toString(Boolean.TRUE, "null") = "true"
316 * </pre>
317 *
318 * @see StringUtils#defaultString(String,String)
319 * @see String#valueOf(Object)
320 * @param obj the Object to {@code toString}, may be null
321 * @param nullStr the String to return if {@code null} input, may be null
322 * @return the passed in Object's toString, or nullStr if {@code null} input
323 * @since 2.0
324 */
325 public static String toString(Object obj, String nullStr) {
326 return obj == null ? nullStr : obj.toString();
327 }
328
329 // Comparable
330 //-----------------------------------------------------------------------
331 /**
332 * <p>Null safe comparison of Comparables.</p>
333 *
334 * @param <T> type of the values processed by this method
335 * @param values the set of comparable values, may be null
336 * @return
337 * <ul>
338 * <li>If any objects are non-null and unequal, the lesser object.
339 * <li>If all objects are non-null and equal, the first.
340 * <li>If any of the comparables are null, the lesser of the non-null objects.
341 * <li>If all the comparables are null, null is returned.
342 * </ul>
343 */
344 public static <T extends Comparable<? super T>> T min(T... values) {
345 T result = null;
346 if (values != null) {
347 for (T value : values) {
348 if (compare(value, result, true) < 0) {
349 result = value;
350 }
351 }
352 }
353 return result;
354 }
355
356 /**
357 * <p>Null safe comparison of Comparables.</p>
358 *
359 * @param <T> type of the values processed by this method
360 * @param values the set of comparable values, may be null
361 * @return
362 * <ul>
363 * <li>If any objects are non-null and unequal, the greater object.
364 * <li>If all objects are non-null and equal, the first.
365 * <li>If any of the comparables are null, the greater of the non-null objects.
366 * <li>If all the comparables are null, null is returned.
367 * </ul>
368 */
369 public static <T extends Comparable<? super T>> T max(T... values) {
370 T result = null;
371 if (values != null) {
372 for (T value : values) {
373 if (compare(value, result, false) > 0) {
374 result = value;
375 }
376 }
377 }
378 return result;
379 }
380
381 /**
382 * <p>Null safe comparison of Comparables.
383 * {@code null} is assumed to be less than a non-{@code null} value.</p>
384 *
385 * @param <T> type of the values processed by this method
386 * @param c1 the first comparable, may be null
387 * @param c2 the second comparable, may be null
388 * @return a negative value if c1 < c2, zero if c1 = c2
389 * and a positive value if c1 > c2
390 */
391 public static <T extends Comparable<? super T>> int compare(T c1, T c2) {
392 return compare(c1, c2, false);
393 }
394
395 /**
396 * <p>Null safe comparison of Comparables.</p>
397 *
398 * @param <T> type of the values processed by this method
399 * @param c1 the first comparable, may be null
400 * @param c2 the second comparable, may be null
401 * @param nullGreater if true {@code null} is considered greater
402 * than a non-{@code null} value or if false {@code null} is
403 * considered less than a Non-{@code null} value
404 * @return a negative value if c1 < c2, zero if c1 = c2
405 * and a positive value if c1 > c2
406 * @see java.util.Comparator#compare(Object, Object)
407 */
408 public static <T extends Comparable<? super T>> int compare(T c1, T c2, boolean nullGreater) {
409 if (c1 == c2) {
410 return 0;
411 } else if (c1 == null) {
412 return (nullGreater ? 1 : -1);
413 } else if (c2 == null) {
414 return (nullGreater ? -1 : 1);
415 }
416 return c1.compareTo(c2);
417 }
418
419 /**
420 * Find the "best guess" middle value among comparables. If there is an even
421 * number of total values, the lower of the two middle values will be returned.
422 * @param <T> type of values processed by this method
423 * @param items to compare
424 * @return T at middle position
425 * @throws NullPointerException if items is {@code null}
426 * @throws IllegalArgumentException if items is empty or contains {@code null} values
427 * @since 3.0.1
428 */
429 public static <T extends Comparable<? super T>> T median(T... items) {
430 Validate.notEmpty(items);
431 Validate.noNullElements(items);
432 TreeSet<T> sort = new TreeSet<T>();
433 Collections.addAll(sort, items);
434 @SuppressWarnings("unchecked") //we know all items added were T instances
435 T result = (T) sort.toArray()[(sort.size() - 1) / 2];
436 return result;
437 }
438
439 /**
440 * Find the "best guess" middle value among comparables. If there is an even
441 * number of total values, the lower of the two middle values will be returned.
442 * @param <T> type of values processed by this method
443 * @param comparator to use for comparisons
444 * @param items to compare
445 * @return T at middle position
446 * @throws NullPointerException if items or comparator is {@code null}
447 * @throws IllegalArgumentException if items is empty or contains {@code null} values
448 * @since 3.0.1
449 */
450 public static <T> T median(Comparator<T> comparator, T... items) {
451 Validate.notEmpty(items, "null/empty items");
452 Validate.noNullElements(items);
453 Validate.notNull(comparator, "null comparator");
454 TreeSet<T> sort = new TreeSet<T>(comparator);
455 Collections.addAll(sort, items);
456 @SuppressWarnings("unchecked") //we know all items added were T instances
457 T result = (T) sort.toArray()[(sort.size() - 1) / 2];
458 return result;
459 }
460
461 // Mode
462 //-----------------------------------------------------------------------
463 /**
464 * Find the most frequently occurring item.
465 *
466 * @param <T> type of values processed by this method
467 * @param items to check
468 * @return most populous T, {@code null} if non-unique or no items supplied
469 * @since 3.0.1
470 */
471 public static <T> T mode(T... items) {
472 if (ArrayUtils.isNotEmpty(items)) {
473 HashMap<T, MutableInt> occurrences = new HashMap<T, MutableInt>(items.length);
474 for (T t : items) {
475 MutableInt count = occurrences.get(t);
476 if (count == null) {
477 occurrences.put(t, new MutableInt(1));
478 } else {
479 count.increment();
480 }
481 }
482 T result = null;
483 int max = 0;
484 for (Map.Entry<T, MutableInt> e : occurrences.entrySet()) {
485 int cmp = e.getValue().intValue();
486 if (cmp == max) {
487 result = null;
488 } else if (cmp > max) {
489 max = cmp;
490 result = e.getKey();
491 }
492 }
493 return result;
494 }
495 return null;
496 }
497
498 // cloning
499 //-----------------------------------------------------------------------
500 /**
501 * <p>Clone an object.</p>
502 *
503 * @param <T> the type of the object
504 * @param obj the object to clone, null returns null
505 * @return the clone if the object implements {@link Cloneable} otherwise {@code null}
506 * @throws CloneFailedException if the object is cloneable and the clone operation fails
507 * @since 3.0
508 */
509 public static <T> T clone(final T obj) {
510 if (obj instanceof Cloneable) {
511 final Object result;
512 if (obj.getClass().isArray()) {
513 final Class<?> componentType = obj.getClass().getComponentType();
514 if (!componentType.isPrimitive()) {
515 result = ((Object[]) obj).clone();
516 } else {
517 int length = Array.getLength(obj);
518 result = Array.newInstance(componentType, length);
519 while (length-- > 0) {
520 Array.set(result, length, Array.get(obj, length));
521 }
522 }
523 } else {
524 try {
525 final Method clone = obj.getClass().getMethod("clone");
526 result = clone.invoke(obj);
527 } catch (final NoSuchMethodException e) {
528 throw new CloneFailedException("Cloneable type "
529 + obj.getClass().getName()
530 + " has no clone method", e);
531 } catch (final IllegalAccessException e) {
532 throw new CloneFailedException("Cannot clone Cloneable type "
533 + obj.getClass().getName(), e);
534 } catch (final InvocationTargetException e) {
535 throw new CloneFailedException("Exception cloning Cloneable type "
536 + obj.getClass().getName(), e.getCause());
537 }
538 }
539 @SuppressWarnings("unchecked")
540 final T checked = (T) result;
541 return checked;
542 }
543
544 return null;
545 }
546
547 /**
548 * <p>Clone an object if possible.</p>
549 *
550 * <p>This method is similar to {@link #clone(Object)}, but will return the provided
551 * instance as the return value instead of {@code null} if the instance
552 * is not cloneable. This is more convenient if the caller uses different
553 * implementations (e.g. of a service) and some of the implementations do not allow concurrent
554 * processing or have state. In such cases the implementation can simply provide a proper
555 * clone implementation and the caller's code does not have to change.</p>
556 *
557 * @param <T> the type of the object
558 * @param obj the object to clone, null returns null
559 * @return the clone if the object implements {@link Cloneable} otherwise the object itself
560 * @throws CloneFailedException if the object is cloneable and the clone operation fails
561 * @since 3.0
562 */
563 public static <T> T cloneIfPossible(final T obj) {
564 final T clone = clone(obj);
565 return clone == null ? obj : clone;
566 }
567
568 // Null
569 //-----------------------------------------------------------------------
570 /**
571 * <p>Class used as a null placeholder where {@code null}
572 * has another meaning.</p>
573 *
574 * <p>For example, in a {@code HashMap} the
575 * {@link java.util.HashMap#get(java.lang.Object)} method returns
576 * {@code null} if the {@code Map} contains {@code null} or if there is
577 * no matching key. The {@code Null} placeholder can be used to distinguish
578 * between these two cases.</p>
579 *
580 * <p>Another example is {@code Hashtable}, where {@code null}
581 * cannot be stored.</p>
582 */
583 public static class Null implements Serializable {
584 /**
585 * Required for serialization support. Declare serialization compatibility with Commons Lang 1.0
586 *
587 * @see java.io.Serializable
588 */
589 private static final long serialVersionUID = 7092611880189329093L;
590
591 /**
592 * Restricted constructor - singleton.
593 */
594 Null() {
595 super();
596 }
597
598 /**
599 * <p>Ensure singleton.</p>
600 *
601 * @return the singleton value
602 */
603 private Object readResolve() {
604 return ObjectUtils.NULL;
605 }
606 }
607
608 }