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 1147522 2011-07-17 04:22:51Z mbenson $
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 */
428 public static <T extends Comparable<? super T>> T median(T... items) {
429 Validate.notEmpty(items);
430 Validate.noNullElements(items);
431 TreeSet<T> sort = new TreeSet<T>();
432 Collections.addAll(sort, items);
433 @SuppressWarnings("unchecked") //we know all items added were T instances
434 T result = (T) sort.toArray()[(sort.size() - 1) / 2];
435 return result;
436 }
437
438 /**
439 * Find the "best guess" middle value among comparables. If there is an even
440 * number of total values, the lower of the two middle values will be returned.
441 * @param <T> type of values processed by this method
442 * @param comparator to use for comparisons
443 * @param items to compare
444 * @return T at middle position
445 * @throws NullPointerException if items or comparator is {@code null}
446 * @throws IllegalArgumentException if items is empty or contains {@code null} values
447 */
448 public static <T> T median(Comparator<T> comparator, T... items) {
449 Validate.notEmpty(items, "null/empty items");
450 Validate.noNullElements(items);
451 Validate.notNull(comparator, "null comparator");
452 TreeSet<T> sort = new TreeSet<T>(comparator);
453 Collections.addAll(sort, items);
454 @SuppressWarnings("unchecked") //we know all items added were T instances
455 T result = (T) sort.toArray()[(sort.size() - 1) / 2];
456 return result;
457 }
458
459 // Mode
460 //-----------------------------------------------------------------------
461 /**
462 * Find the most frequently occurring item.
463 *
464 * @param <T>
465 * @param items to check
466 * @return most populous T, {@code null} if non-unique or no items supplied
467 */
468 public static <T> T mode(T... items) {
469 if (ArrayUtils.isNotEmpty(items)) {
470 HashMap<T, MutableInt> occurrences = new HashMap<T, MutableInt>(items.length);
471 for (T t : items) {
472 MutableInt count = occurrences.get(t);
473 if (count == null) {
474 occurrences.put(t, new MutableInt(1));
475 } else {
476 count.increment();
477 }
478 }
479 T result = null;
480 int max = 0;
481 for (Map.Entry<T, MutableInt> e : occurrences.entrySet()) {
482 int cmp = e.getValue().intValue();
483 if (cmp == max) {
484 result = null;
485 } else if (cmp > max) {
486 max = cmp;
487 result = e.getKey();
488 }
489 }
490 return result;
491 }
492 return null;
493 }
494
495 // cloning
496 //-----------------------------------------------------------------------
497 /**
498 * <p>Clone an object.</p>
499 *
500 * @param <T> the type of the object
501 * @param obj the object to clone, null returns null
502 * @return the clone if the object implements {@link Cloneable} otherwise {@code null}
503 * @throws CloneFailedException if the object is cloneable and the clone operation fails
504 * @since 3.0
505 */
506 public static <T> T clone(final T obj) {
507 if (obj instanceof Cloneable) {
508 final Object result;
509 if (obj.getClass().isArray()) {
510 final Class<?> componentType = obj.getClass().getComponentType();
511 if (!componentType.isPrimitive()) {
512 result = ((Object[]) obj).clone();
513 } else {
514 int length = Array.getLength(obj);
515 result = Array.newInstance(componentType, length);
516 while (length-- > 0) {
517 Array.set(result, length, Array.get(obj, length));
518 }
519 }
520 } else {
521 try {
522 final Method clone = obj.getClass().getMethod("clone");
523 result = clone.invoke(obj);
524 } catch (final NoSuchMethodException e) {
525 throw new CloneFailedException("Cloneable type "
526 + obj.getClass().getName()
527 + " has no clone method", e);
528 } catch (final IllegalAccessException e) {
529 throw new CloneFailedException("Cannot clone Cloneable type "
530 + obj.getClass().getName(), e);
531 } catch (final InvocationTargetException e) {
532 throw new CloneFailedException("Exception cloning Cloneable type "
533 + obj.getClass().getName(), e.getCause());
534 }
535 }
536 @SuppressWarnings("unchecked")
537 final T checked = (T) result;
538 return checked;
539 }
540
541 return null;
542 }
543
544 /**
545 * <p>Clone an object if possible.</p>
546 *
547 * <p>This method is similar to {@link #clone(Object)}, but will return the provided
548 * instance as the return value instead of {@code null} if the instance
549 * is not cloneable. This is more convenient if the caller uses different
550 * implementations (e.g. of a service) and some of the implementations do not allow concurrent
551 * processing or have state. In such cases the implementation can simply provide a proper
552 * clone implementation and the caller's code does not have to change.</p>
553 *
554 * @param <T> the type of the object
555 * @param obj the object to clone, null returns null
556 * @return the clone if the object implements {@link Cloneable} otherwise the object itself
557 * @throws CloneFailedException if the object is cloneable and the clone operation fails
558 * @since 3.0
559 */
560 public static <T> T cloneIfPossible(final T obj) {
561 final T clone = clone(obj);
562 return clone == null ? obj : clone;
563 }
564
565 // Null
566 //-----------------------------------------------------------------------
567 /**
568 * <p>Class used as a null placeholder where {@code null}
569 * has another meaning.</p>
570 *
571 * <p>For example, in a {@code HashMap} the
572 * {@link java.util.HashMap#get(java.lang.Object)} method returns
573 * {@code null} if the {@code Map} contains {@code null} or if there is
574 * no matching key. The {@code Null} placeholder can be used to distinguish
575 * between these two cases.</p>
576 *
577 * <p>Another example is {@code Hashtable}, where {@code null}
578 * cannot be stored.</p>
579 */
580 public static class Null implements Serializable {
581 /**
582 * Required for serialization support. Declare serialization compatibility with Commons Lang 1.0
583 *
584 * @see java.io.Serializable
585 */
586 private static final long serialVersionUID = 7092611880189329093L;
587
588 /**
589 * Restricted constructor - singleton.
590 */
591 Null() {
592 super();
593 }
594
595 /**
596 * <p>Ensure singleton.</p>
597 *
598 * @return the singleton value
599 */
600 private Object readResolve() {
601 return ObjectUtils.NULL;
602 }
603 }
604
605 }