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 }