最近回归基础,看《Java核心技术 卷1》,受益良多,特此记录一番。边看书,边看源码,此不做教学使用,仅作为记录、分享。
1、Objects(jdk7开始有)
1-1介绍
这个类是一个工具类,里面包含的都是Object的增强方法,放在java.util包下,里面有各种用于Object的实用方法。如带空值判断的equals方法等等
//这是摘自Objects类中,对于这个类的描述。
This class consists of {@code static} utility methods for operating
* on objects, or checking certain conditions before operation. These utilities
* include {@code null}-safe or {@code null}-tolerant methods for computing the
* hash code of an object, returning a string for an object, comparing two
* objects, and checking if indexes or sub-range values are out of bounds.
*
* @apiNote
* Static methods such as {@link Objects#checkIndex},
* {@link Objects#checkFromToIndex}, and {@link Objects#checkFromIndexSize} are
* provided for the convenience of checking if values corresponding to indexes
* and sub-ranges are out of bounds.
* Variations of these static methods support customization of the runtime
* exception, and corresponding exception detail message, that is thrown when
* values are out of bounds. Such methods accept a functional interface
* argument, instances of {@code BiFunction}, that maps out-of-bound values to a
* runtime exception. Care should be taken when using such methods in
* combination with an argument that is a lambda expression, method reference or
* class that capture values. In such cases the cost of capture, related to
* functional interface allocation, may exceed the cost of checking bounds.
1-2 api讲解
1-2-1 equals
带非空判断的equals方法
//Objects中的源码,下同。
public static boolean equals(Object a, Object b) {
return (a == b) || (a != null && a.equals(b));
}
1-2-2 deepEquals
深度校验的equals函数,可以对对象数组、基本类型数组进行元素的判断。本质还是要实现或者重写对象的equals方法的。
//java.util.Objects#deepEquals
public static boolean deepEquals(Object a, Object b) {
if (a == b)
return true;
else if (a == null || b == null)
return false;
else
return Arrays.deepEquals0(a, b);
}
///
//java.util.Arrays#deepEquals0
static boolean deepEquals0(Object e1, Object e2) {
assert e1 != null;
boolean eq;
if (e1 instanceof Object[] && e2 instanceof Object[])
eq = deepEquals ((Object[]) e1, (Object[]) e2);
else if (e1 instanceof byte[] && e2 instanceof byte[])
eq = equals((byte[]) e1, (byte[]) e2);
else if (e1 instanceof short[] && e2 instanceof short[])
eq = equals((short[]) e1, (short[]) e2);
else if (e1 instanceof int[] && e2 instanceof int[])
eq = equals((int[]) e1, (int[]) e2);
else if (e1 instanceof long[] && e2 instanceof long[])
eq = equals((long[]) e1, (long[]) e2);
else if (e1 instanceof char[] && e2 instanceof char[])
eq = equals((char[]) e1, (char[]) e2);
else if (e1 instanceof float[] && e2 instanceof float[])
eq = equals((float[]) e1, (float[]) e2);
else if (e1 instanceof double[] && e2 instanceof double[])
eq = equals((double[]) e1, (double[]) e2);
else if (e1 instanceof boolean[] && e2 instanceof boolean[])
eq = equals((boolean[]) e1, (boolean[]) e2);
else
eq = e1.equals(e2);
return eq;
}
1-2-3 hashCode
如果不为空,返回hashcode
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
1-2-4 hash
返回一个输入序列的哈希值。
//java.util.Objects#hash
public static int hash(Object... values) {
return Arrays.hashCode(values);
}
/
//其实本质是调用Arrays的hashcode方法
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
1-2-5 toString
注意:如果对象为空,返回的是“null”字符串!!
public static String toString(Object o) {
return String.valueOf(o);
}
//
//java.lang.String#valueOf(java.lang.Object)
public static String valueOf(Object obj) {
return (obj == null) ? "null" : obj.toString();
}
在Objects还有一个重载方法
public static String toString(Object o, String nullDefault) {
return (o != null) ? o.toString() : nullDefault;
}
1-2-6 compare
传入一个函数式的接口进行对比,注意:返回值是一个int类型的值
如果是同一个对象就返回 0 ,否则就
调用函数式接口
注意:作者特意在源码的注释中提示:如果有其中之一一个参数是null,抛不抛NPE取决于你的排序方针,如果有,Comparator将会拥有这个null参数。如果c是null,一样报错
public static <T> int compare(T a, T b, Comparator<? super T> c) {
return (a == b) ? 0 : c.compare(a, b);
}
1-2-7 requireNonNull
非空则返回原值,否则报npe
public static <T> T requireNonNull(T obj) {
if (obj == null)
throw new NullPointerException();
return obj;
}
还有一个重载的方法,若空,则附带提示信息的报错
public static <T> T requireNonNull(T obj, String message) {
if (obj == null)
throw new NullPointerException(message);
return obj;
}
1-2-8 isNull(8开始)
空吗?
public static boolean isNull(Object obj) {
return obj == null;
}
1-2-9 nonNull(8开始)
不空吗?
public static boolean nonNull(Object obj) {
return obj != null;
}
1-2-10 requireNonNullElse(9开始)
非空返回原来的值,空则返回默认值。如果defaultObj为空,则"defaultObj"字符串作为 提示消息报npe。
public static <T> T requireNonNullElse(T obj, T defaultObj) {
return (obj != null) ? obj : requireNonNull(defaultObj, "defaultObj");
}
1-2-11 requireNonNullElseGet(9开始)
这里依旧使用了函数式接口,如果obj不为空,返回;如果supplier为空,报带"supplier.get()"作为提示信息的npe,否则调用supplier的get方法。
public static <T> T requireNonNullElseGet(T obj, Supplier<? extends T> supplier) {
return (obj != null) ? obj
: requireNonNull(requireNonNull(supplier, "supplier").get(), "supplier.get()");
}
1-2-12 requireNonNull(8开始)
只要obj为空,则都报错,只是这个报错信息由messageSupplier提供了。
不为空则返回。
public static <T> T requireNonNull(T obj, Supplier<String> messageSupplier) {
if (obj == null)
throw new NullPointerException(messageSupplier == null ?
null : messageSupplier.get());
return obj;
}
1-2-13 checkIndex(9开始)
如果index在0(包括0)到 length(不包括length)直接,返回index,否则报越界的错。
public static
int checkIndex(int index, int length) {
return Preconditions.checkIndex(index, length, null);
}
/
public static <X extends RuntimeException>
int checkIndex(int index, int length,
BiFunction<String, List<Integer>, X> oobef) {
if (index < 0 || index >= length)
throw outOfBoundsCheckIndex(oobef, index, length);
return index;
}
1-2-14 checkFromToIndex(9开始)
如果fromindex小于0 或者 toindex大于fromindex 或者 toidex大于length,则报错,否则返回fromindex。
这个应该是用来判断formindex到toindex的区间是否在0到length这个区间内的,如果在,就返回fromindex。
public static
int checkFromToIndex(int fromIndex, int toIndex, int length) {
return Preconditions.checkFromToIndex(fromIndex, toIndex, length, null);
}
/
//jdk.internal.util.Preconditions#checkFromToIndex
public static <X extends RuntimeException>
int checkFromToIndex(int fromIndex, int toIndex, int length,
BiFunction<String, List<Integer>, X> oobef) {
if (fromIndex < 0 || fromIndex > toIndex || toIndex > length)
throw outOfBoundsCheckFromToIndex(oobef, fromIndex, toIndex, length);
return fromIndex;
}
1-2-15 checkFromIndexSize(9开始)
这个是用来判断fromindex+size 的值是否大于length。也是用于区间的判断。
是:报错
否:返回fromindex
public static
int checkFromIndexSize(int fromIndex, int size, int length) {
return Preconditions.checkFromIndexSize(fromIndex, size, length, null);
}
///
public static <X extends RuntimeException>
public static <X extends RuntimeException>
int checkFromIndexSize(int fromIndex, int size, int length,
BiFunction<String, List<Integer>, X> oobef) {
if ((length | fromIndex | size) < 0 || size > length - fromIndex)
throw outOfBoundsCheckFromIndexSize(oobef, fromIndex, size, length);
return fromIndex;
}