jlibs.core.lang.Util Maven / Gradle / Ivy
/**
* Copyright 2015 Santhosh Kumar Tekuri
*
* The JLibs authors license 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 jlibs.core.lang;
import jlibs.core.io.ByteArrayOutputStream2;
import java.io.ObjectInputStream;
import java.io.ObjectOutputStream;
import java.io.Serializable;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Arrays;
/**
* @author Santhosh Kumar T
*/
public class Util{
/**
* Returns first non null element in values
.
* If all elements are null, it returns null.
*/
public static T notNull(T... values){
for(T value: values){
if(value!=null)
return value;
}
return null;
}
/**
* Returns true if given two objects are same.
*
* null values are handled as follows:
* null != non-null
* null == null
*
* Arrays are handled using Arrays.equals(...)
*/
public static boolean equals(Object obj1, Object obj2){
if(obj1==obj2)
return true;
else if(obj1==null || obj2==null)
return false;
else if(obj1.getClass().isArray()){
if(obj2.getClass().isArray()){
if(obj1 instanceof Object[] && obj2 instanceof Object[])
return Arrays.deepEquals((Object[])obj1, (Object[])obj2);
else if(obj1 instanceof boolean[] && obj2 instanceof boolean[])
return Arrays.equals((boolean[])obj1, (boolean[])obj2);
else if(obj1 instanceof char[] && obj2 instanceof char[])
return Arrays.equals((char[])obj1, (char[])obj2);
else if(obj1 instanceof byte[] && obj2 instanceof byte[])
return Arrays.equals((byte[])obj1, (byte[])obj2);
else if(obj1 instanceof short[] && obj2 instanceof short[])
return Arrays.equals((short[])obj1, (short[])obj2);
else if(obj1 instanceof int[] && obj2 instanceof int[])
return Arrays.equals((int[])obj1, (int[])obj2);
else if(obj1 instanceof long[] && obj2 instanceof long[])
return Arrays.equals((long[])obj1, (long[])obj2);
else if(obj1 instanceof float[] && obj2 instanceof float[])
return Arrays.equals((float[])obj1, (float[])obj2);
else if(obj1 instanceof double[] && obj2 instanceof double[])
return Arrays.equals((double[])obj1, (double[])obj2);
else
throw new ImpossibleException("couldn't do equals for"+obj1.getClass().getComponentType().getSimpleName()+"[]");
}else
return false;
}else
return obj1.equals(obj2);
}
/*-------------------------------------------------[ HashCode ]---------------------------------------------------*/
/**
* returns hashCode of given argument.
* if argument is null, returns 0
*/
public static int hashCode(Object obj){
if(obj==null)
return 0;
else if(obj.getClass().isArray()){
if(obj instanceof Object[])
return Arrays.deepHashCode((Object[])obj);
else if(obj instanceof boolean[])
return Arrays.hashCode((boolean[])obj);
else if(obj instanceof char[])
return Arrays.hashCode((char[])obj);
else if(obj instanceof byte[])
return Arrays.hashCode((byte[])obj);
else if(obj instanceof short[])
return Arrays.hashCode((short[])obj);
else if(obj instanceof int[])
return Arrays.hashCode((int[])obj);
else if(obj instanceof long[])
return Arrays.hashCode((long[])obj);
else if(obj instanceof float[])
return Arrays.hashCode((float[])obj);
else if(obj instanceof double[])
return Arrays.hashCode((double[])obj);
else
throw new ImpossibleException("couldn't find hascode for"+obj.getClass().getComponentType().getSimpleName()+"[]");
}else
return obj.hashCode();
}
/**
* returns hashCode of given arguments.
* if any argument is null, then it considers
* its hashCode as zero
*/
public static int hashCode(Object... objects){
int hashCode = 0;
for(Object obj: objects)
hashCode = 31*hashCode + hashCode(obj);
return hashCode;
}
@SuppressWarnings({"ThrowableInstanceNeverThrown", "unchecked"})
public static T clone(T obj) throws CloneNotSupportedException{
if(obj==null)
return null;
try{
if(obj instanceof Cloneable){
Method method = obj.getClass().getMethod("clone");
if(!Modifier.isPublic(method.getModifiers()))
method.setAccessible(true);
return (T)method.invoke(obj);
}else if(obj instanceof Serializable){
ByteArrayOutputStream2 bout = new ByteArrayOutputStream2();
ObjectOutputStream objOut = new ObjectOutputStream(bout);
objOut.writeObject(obj);
objOut.close();
ObjectInputStream objIn = new ObjectInputStream(bout.toByteSequence().asInputStream());
return (T)objIn.readObject();
}else
throw new CloneNotSupportedException(obj.getClass().getName());
}catch(Exception ex){
if(ex instanceof CloneNotSupportedException)
throw (CloneNotSupportedException)ex;
else
throw (CloneNotSupportedException)new CloneNotSupportedException().initCause(ex);
}
}
public static long parseLong(String value){
int len = value.length();
if(len==0)
throw new NumberFormatException("empty string");
int i = 0;
boolean negative = false;
char firstChar = value.charAt(0);
if(firstChar<'0'){
if(firstChar=='-')
negative = true;
else if(firstChar!='+')
throw new NumberFormatException("for input string \""+value+"\"");
if(len==1)
throw new NumberFormatException("cannot have lone + or -");
++i;
}
int result = 0;
while(i='0' && ch<='9')
result = result*10 + (ch-'0');
else
throw new NumberFormatException("for input string \""+value+"\"");
}
return negative ? -result : result;
}
}