Objects的使用(since jdk7)

最近回归基础,看《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;
    }
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值