net.hasor.cobble.ObjectUtils Maven / Gradle / Ivy
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package net.hasor.cobble;
import java.io.Serializable;
import java.util.Objects;
import java.util.function.Function;
/**
* Operations on Object
.
*
* This class tries to handle null
input gracefully.
* An exception will generally not be thrown for a null
input.
* Each method documents its behaviour in more detail.
*
* #ThreadSafe#
*
* 2021-11-01 reduction based on Apache Commons lang3, org.apache.commons.lang3.ObjectUtils
*
* @author 赵永春 ([email protected])
* @author Apache Software Foundation
* @author Nissim Karpenstein
* @author Janek Bogucki
* @author Daniel L. Rall
* @author Gary Gregory
* @author Mario Winterer
* @author David J. M. Karlsen
* @since 1.0
* @version $Id: ObjectUtils.java 1057434 2011-01-11 01:27:37Z niallp $
*/
public class ObjectUtils {
private static final int INITIAL_HASH = 7;
private static final int MULTIPLIER = 31;
/**
* Singleton used as a null
placeholder where
* null
has another meaning.
*
* For example, in a HashMap
the
* {@link java.util.HashMap#get(Object)} method returns
* null
if the Map
contains
* null
or if there is no matching key. The
* Null
placeholder can be used to distinguish between
* these two cases.
*
* Another example is Hashtable
, where null
* cannot be stored.
*
* This instance is Serializable.
*/
public static final Null NULL = new Null();
/**
* ObjectUtils
instances should NOT be constructed in
* standard programming. Instead, the class should be used as
* ObjectUtils.defaultIfNull("a","b");
.
*
* This constructor is public to permit tools that require a JavaBean instance
* to operate.
*/
public ObjectUtils() {
super();
}
// Defaulting
//-----------------------------------------------------------------------
/**
* Returns a default value if the object passed is
* null
.
*
*
* ObjectUtils.defaultIfNull(null, null) = null
* ObjectUtils.defaultIfNull(null, "") = ""
* ObjectUtils.defaultIfNull(null, "zz") = "zz"
* ObjectUtils.defaultIfNull("abc", *) = "abc"
* ObjectUtils.defaultIfNull(Boolean.TRUE, *) = Boolean.TRUE
*
*
* @param object the Object
to test, may be null
* @param defaultValue the default value to return, may be null
* @return object
if it is not null
, defaultValue otherwise
*/
public static Object defaultIfNull(Object object, Object defaultValue) {
return object != null ? object : defaultValue;
}
/**
* Compares two objects for equality, where either one or both
* objects may be null
.
*
*
* ObjectUtils.equals(null, null) = true
* ObjectUtils.equals(null, "") = false
* ObjectUtils.equals("", null) = false
* ObjectUtils.equals("", "") = true
* ObjectUtils.equals(Boolean.TRUE, null) = false
* ObjectUtils.equals(Boolean.TRUE, "true") = false
* ObjectUtils.equals(Boolean.TRUE, Boolean.TRUE) = true
* ObjectUtils.equals(Boolean.TRUE, Boolean.FALSE) = false
*
*
* @param object1 the first object, may be null
* @param object2 the second object, may be null
* @return true
if the values of both objects are the same
*/
public static boolean equals(Object object1, Object object2) {
if (object1 == object2) {
return true;
}
if ((object1 == null) || (object2 == null)) {
return false;
}
return object1.equals(object2);
}
/**
* Compares two objects for inequality, where either one or both
* objects may be null
.
*
*
* ObjectUtils.notEqual(null, null) = false
* ObjectUtils.notEqual(null, "") = true
* ObjectUtils.notEqual("", null) = true
* ObjectUtils.notEqual("", "") = false
* ObjectUtils.notEqual(Boolean.TRUE, null) = true
* ObjectUtils.notEqual(Boolean.TRUE, "true") = true
* ObjectUtils.notEqual(Boolean.TRUE, Boolean.TRUE) = false
* ObjectUtils.notEqual(Boolean.TRUE, Boolean.FALSE) = true
*
*
* @param object1 the first object, may be null
* @param object2 the second object, may be null
* @return false
if the values of both objects are the same
* @since 2.6
*/
public static boolean notEqual(Object object1, Object object2) {
return ObjectUtils.equals(object1, object2) == false;
}
/**
* Gets the hash code of an object returning zero when the
* object is null
.
*
*
* ObjectUtils.hashCode(null) = 0
* ObjectUtils.hashCode(obj) = obj.hashCode()
*
*
* @param obj the object to obtain the hash code of, may be null
* @return the hash code of the object, or zero if null
* @since 2.1
*/
public static int hashCode(Object obj) {
return (obj == null) ? 0 : obj.hashCode();
}
// Identity ToString
//-----------------------------------------------------------------------
/**
* Gets the toString that would be produced by Object
* if a class did not override toString itself. null
* will return null
.
*
*
* ObjectUtils.identityToString(null) = null
* ObjectUtils.identityToString("") = "java.lang.String@1e23"
* ObjectUtils.identityToString(Boolean.TRUE) = "java.lang.Boolean@7fa"
*
*
* @param object the object to create a toString for, may be
* null
* @return the default toString text, or null
if
* null
passed in
*/
public static String identityToString(Object object) {
if (object == null) {
return null;
}
StringBuffer buffer = new StringBuffer();
identityToString(buffer, object);
return buffer.toString();
}
/**
* Appends the toString that would be produced by Object
* if a class did not override toString itself. null
* will throw a NullPointerException for either of the two parameters.
*
*
* ObjectUtils.identityToString(buf, "") = buf.append("java.lang.String@1e23"
* ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa"
* ObjectUtils.identityToString(buf, Boolean.TRUE) = buf.append("java.lang.Boolean@7fa")
*
*
* @param buffer the buffer to append to
* @param object the object to create a toString for
* @since 2.4
*/
public static void identityToString(StringBuffer buffer, Object object) {
if (object == null) {
throw new NullPointerException("Cannot get the toString of a null identity");
}
buffer.append(object.getClass().getName()).append('@').append(Integer.toHexString(System.identityHashCode(object)));
}
// ToString
//-----------------------------------------------------------------------
/**
* Gets the toString
of an Object
returning
* an empty string ("") if null
input.
*
*
* ObjectUtils.toString(null) = ""
* ObjectUtils.toString("") = ""
* ObjectUtils.toString("bat") = "bat"
* ObjectUtils.toString(Boolean.TRUE) = "true"
*
*
* @see StringUtils#defaultString(String)
* @see String#valueOf(Object)
* @param obj the Object to toString
, may be null
* @return the passed in Object's toString, or nullStr if null
input
* @since 2.0
*/
public static String toString(Object obj) {
return obj == null ? "" : obj.toString();
}
/**
* Gets the toString
of an Object
returning
* a specified text if null
input.
*
*
* ObjectUtils.toString(null, null) = null
* ObjectUtils.toString(null, "null") = "null"
* ObjectUtils.toString("", "null") = ""
* ObjectUtils.toString("bat", "null") = "bat"
* ObjectUtils.toString(Boolean.TRUE, "null") = "true"
*
*
* @see StringUtils#defaultString(String, String)
* @see String#valueOf(Object)
* @param obj the Object to toString
, may be null
* @param nullStr the String to return if null
input, may be null
* @return the passed in Object's toString, or nullStr if null
input
* @since 2.0
*/
public static String toString(Object obj, String nullStr) {
return obj == null ? nullStr : obj.toString();
}
// Min/Max
//-----------------------------------------------------------------------
/**
* Null safe comparison of Comparables.
*
* @param c1 the first comparable, may be null
* @param c2 the second comparable, may be null
* @return
*
* - If both objects are non-null and unequal, the lesser object.
*
- If both objects are non-null and equal, c1.
*
- If one of the comparables is null, the non-null object.
*
- If both the comparables are null, null is returned.
*
*/
public static Object min(Comparable c1, Comparable c2) {
return (compare(c1, c2, true) <= 0 ? c1 : c2);
}
/**
* Null safe comparison of Comparables.
*
* @param c1 the first comparable, may be null
* @param c2 the second comparable, may be null
* @return
*
* - If both objects are non-null and unequal, the greater object.
*
- If both objects are non-null and equal, c1.
*
- If one of the comparables is null, the non-null object.
*
- If both the comparables are null, null is returned.
*
*/
public static Object max(Comparable c1, Comparable c2) {
return (compare(c1, c2, false) >= 0 ? c1 : c2);
}
/**
* Null safe comparison of Comparables.
* {@code null} is assumed to be less than a non-{@code null} value.
*
* @param c1 the first comparable, may be null
* @param c2 the second comparable, may be null
* @return a negative value if c1 < c2, zero if c1 = c2
* and a positive value if c1 > c2
* @since 2.6
*/
public static int compare(Comparable c1, Comparable c2) {
return compare(c1, c2, false);
}
/**
* Null safe comparison of Comparables.
*
* @param c1 the first comparable, may be null
* @param c2 the second comparable, may be null
* @param nullGreater if true null
is considered greater
* than a Non-null
value or if false null
is
* considered less than a Non-null
value
* @return a negative value if c1 < c2, zero if c1 = c2
* and a positive value if c1 > c2
* @see java.util.Comparator#compare(Object, Object)
* @since 2.6
*/
public static int compare(Comparable c1, Comparable c2, boolean nullGreater) {
if (c1 == c2) {
return 0;
} else if (c1 == null) {
return (nullGreater ? 1 : -1);
} else if (c2 == null) {
return (nullGreater ? -1 : 1);
}
return c1.compareTo(c2);
}
// cast or convert
//-----------------------------------------------------------------------
public static T tryCast(Object obj, Class clazz) {
return clazz.isInstance(obj) ? clazz.cast(obj) : null;
}
public static S tryCastConvert(Object obj, Class clazz, Function super T, ? extends S> convertor) {
//noinspection unchecked
return clazz.isInstance(obj) ? convertor.apply((T) obj) : null;
}
public static S doConvert(T obj, Function super T, ? extends S> function) {
return obj == null ? null : function.apply(obj);
}
// hashCode
//-----------------------------------------------------------------------
/**
* Return as hash code for the given object; typically the value of
* {@code Object#hashCode()}}. If the object is an array,
* this method will delegate to any of the {@code nullSafeHashCode}
* methods for arrays in this class. If the object is {@code null},
* this method returns 0.
* @see Object#hashCode()
* @see #nullSafeHashCode(Object[])
* @see #nullSafeHashCode(boolean[])
* @see #nullSafeHashCode(byte[])
* @see #nullSafeHashCode(char[])
* @see #nullSafeHashCode(double[])
* @see #nullSafeHashCode(float[])
* @see #nullSafeHashCode(int[])
* @see #nullSafeHashCode(long[])
* @see #nullSafeHashCode(short[])
*/
public static int nullSafeHashCode(Object obj) {
if (obj == null) {
return 0;
}
if (obj.getClass().isArray()) {
if (obj instanceof Object[]) {
return nullSafeHashCode((Object[]) obj);
}
if (obj instanceof boolean[]) {
return nullSafeHashCode((boolean[]) obj);
}
if (obj instanceof byte[]) {
return nullSafeHashCode((byte[]) obj);
}
if (obj instanceof char[]) {
return nullSafeHashCode((char[]) obj);
}
if (obj instanceof double[]) {
return nullSafeHashCode((double[]) obj);
}
if (obj instanceof float[]) {
return nullSafeHashCode((float[]) obj);
}
if (obj instanceof int[]) {
return nullSafeHashCode((int[]) obj);
}
if (obj instanceof long[]) {
return nullSafeHashCode((long[]) obj);
}
if (obj instanceof short[]) {
return nullSafeHashCode((short[]) obj);
}
}
return obj.hashCode();
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(Object[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (Object element : array) {
hash = MULTIPLIER * hash + nullSafeHashCode(element);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(boolean[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (boolean element : array) {
hash = MULTIPLIER * hash + Boolean.hashCode(element);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(byte[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (byte element : array) {
hash = MULTIPLIER * hash + element;
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(char[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (char element : array) {
hash = MULTIPLIER * hash + element;
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(double[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (double element : array) {
hash = MULTIPLIER * hash + Double.hashCode(element);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(float[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (float element : array) {
hash = MULTIPLIER * hash + Float.hashCode(element);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(int[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (int element : array) {
hash = MULTIPLIER * hash + element;
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(long[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (long element : array) {
hash = MULTIPLIER * hash + Long.hashCode(element);
}
return hash;
}
/**
* Return a hash code based on the contents of the specified array.
* If {@code array} is {@code null}, this method returns 0.
*/
public static int nullSafeHashCode(short[] array) {
if (array == null) {
return 0;
}
int hash = INITIAL_HASH;
for (short element : array) {
hash = MULTIPLIER * hash + element;
}
return hash;
}
// Null
//-----------------------------------------------------------------------
/**
* Class used as a null placeholder where null
* has another meaning.
*
* For example, in a HashMap
the
* {@link java.util.HashMap#get(Object)} method returns
* null
if the Map
contains
* null
or if there is no matching key. The
* Null
placeholder can be used to distinguish between
* these two cases.
*
* Another example is Hashtable
, where null
* cannot be stored.
*/
public static class Null implements Serializable {
/**
* Required for serialization support. Declare serialization compatibility with Commons Lang 1.0
* @see Serializable
*/
private static final long serialVersionUID = 7092611880189329093L;
/**
* Restricted constructor - singleton.
*/
Null() {
super();
}
/**
* Ensure singleton.
*
* @return the singleton value
*/
private Object readResolve() {
return ObjectUtils.NULL;
}
}
// Check form Netty common
//-----------------------------------------------------------------------
/**
* Checks that the given argument is not null. If it is, throws {@link NullPointerException}.
* Otherwise, returns the argument.
*/
public static T checkNotNull(T arg, String text) {
return Objects.requireNonNull(arg, text);
}
/**
* Checks that the given argument is strictly positive. If it is not, throws {@link IllegalArgumentException}.
* Otherwise, returns the argument.
*/
public static int checkPositive(int i, String name) {
if (i <= 0) {
throw new IllegalArgumentException(name + ": " + i + " (expected: > 0)");
}
return i;
}
/**
* Checks that the given argument is strictly positive. If it is not, throws {@link IllegalArgumentException}.
* Otherwise, returns the argument.
*/
public static long checkPositive(long l, String name) {
if (l <= 0) {
throw new IllegalArgumentException(name + ": " + l + " (expected: > 0)");
}
return l;
}
/**
* Checks that the given argument is positive or zero. If it is not , throws {@link IllegalArgumentException}.
* Otherwise, returns the argument.
*/
public static int checkPositiveOrZero(int i, String name) {
if (i < 0) {
throw new IllegalArgumentException(name + ": " + i + " (expected: >= 0)");
}
return i;
}
/**
* Checks that the given argument is positive or zero. If it is not, throws {@link IllegalArgumentException}.
* Otherwise, returns the argument.
*/
public static long checkPositiveOrZero(long l, String name) {
if (l < 0) {
throw new IllegalArgumentException(name + ": " + l + " (expected: >= 0)");
}
return l;
}
/**
* Checks that the given argument is in range. If it is not, throws {@link IllegalArgumentException}.
* Otherwise, returns the argument.
*/
public static int checkInRange(int i, int start, int end, String name) {
if (i < start || i > end) {
throw new IllegalArgumentException(name + ": " + i + " (expected: " + start + "-" + end + ")");
}
return i;
}
/**
* Checks that the given argument is in range. If it is not, throws {@link IllegalArgumentException}.
* Otherwise, returns the argument.
*/
public static long checkInRange(long l, long start, long end, String name) {
if (l < start || l > end) {
throw new IllegalArgumentException(name + ": " + l + " (expected: " + start + "-" + end + ")");
}
return l;
}
// assert
//-----------------------------------------------------------------------
public static boolean assertTrue(boolean value, Object message) {
if (!value) {
String resultMessage = "Assertion failed";
if (message != null) {
resultMessage += ": " + message;
}
throw new IllegalArgumentException(resultMessage);
}
return true;
}
public static boolean assertTrue(boolean value) {
//noinspection ConstantConditions
return value || assertTrue(false, null);
}
}