Java常用类-----java.util.Objects工具类详解

2022-07-28,,,

java.util.Objects工具详解

  • 简介
    • Objects 与 Object 区别
    • 构造函数
    • 常用方法
      • equals
      • deepEquals
      • hashCode
      • hash
      • toString
        • toString(Object o)
        • toString(Object o, String nullDefault)
      • compare
      • requireNonNull
        • requireNonNull​(T obj)
        • requireNonNull​(T obj, String message)
      • isNull
      • nonNull

简介

Objects 与 Object 区别

  1. Object 是 Java 中所有类的基类,位于java.lang包。
  2. Objects 是 Object 的工具类,位于java.util包。

  java.util.Objects由 Java 7 引入的 ,包含static实用程序方法,用于操作对象或在操作前检查某些条件。

  需要注意的是:这个类用关键字final修饰不能被继承,拥有私有的构造函数。
问题描述:

  用户希望使用静态工具方法实现非空验证、比较等操作。

适用场景:

  它在流处理中相当有用,实用程序包括null或null方法,用于计算对象的哈希代码,返回对象的字符串,比较两个对象,以及检查索引或子范围值是否超出范围。

构造函数

    private Objects() {
        throw new AssertionError("No java.util.Objects instances for you!");
    }

  可以看到Objects类中只有一个构造函数,并且声明为private,构造函数中抛出一个AssertionError。因此这个类不可以实例化

常用方法

equals

    public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }

  这里Objects.equals方法中已经做了非空判断,所以不会抛出空指针异常,它是null-save空指针安全的。
  如果两个参数相等,返回true,否则返回false。 因此,如果这两个参数是null ,返回true,如果只有一个参数为null ,返回false, 否则,通过使用第一个参数的equals方法确定相等性。

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);
    }
    

  若两个都是null值的字符串或者数组比较,返回true。如果两个参数都是数组,则使用Arrays.deepEquals中的算法来确定相等性,在参数数组的循环中,递归调用deepEquals0,直到出现不相同的元素, 或者循环结束;否则,通过使用第一个参数的equals方法确定相等性。
  注:该方法在数组比较中尤其有用,当我们在业务中需要判断两个复杂类型,比如使用了泛型的列表对象List、或者通过反射得到的对象,不清楚对象的具体类型时可以直接使用此方法来解决。
测试:

public static void main(String[] args) {
        String[] arr1 = new String[]{"123"};
        String[] arr2 = new String[]{"124"};
        int[] arr3 = new int[]{1,2,3};
        int[] arr4 = new int[]{1,2,3};
        String s1 = "100";
        int s2 = 100;
        boolean b1 = Objects.deepEquals(arr1,arr2);
        boolean b2 = Objects.deepEquals(arr3,arr4);
        boolean b3 = Objects.deepEquals(s1,s2);
        System.out.println("字符串数组比较结果:"+b1);
        System.out.println("整型数组比较结果:"+b2);
        System.out.println("字符串和整型比较结果:"+b3);
    }

结果为:

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;
    }

  若参数是基本类型的数组,则根据该类型调用Arrays.equals方法。Arrays工具类依照八种基本类型对equals方法做了重载。

hashCode

    public static int hashCode(Object o) {
        return o != null ? o.hashCode() : 0;
    }

  判断引用o所指对象是否为null,不为null,则返回o所指对象的hasCode方法执行结果,为null,返回0。

hash

    public static int hash(Object... values) {
        return Arrays.hashCode(values);
    }

  为一系列的输入值生成哈希码,该方法的参数是可变参数。它将所有的输入值都放到一个数组,然后调用Arrays.hashCode(Object[])方法来实现哈希码的生成。
  警告:当提供的参数是单个对象的引用时,返回值不等于该对象引用的散列码。这个值可以通过调用hashCode(Object)方法来计算。
public static int hashCode(Object a[ ])实现方法如下:

    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;
    }

toString

toString(Object o)

    public static String toString(Object o) {
        return String.valueOf(o);
    }

  返回指定对象的字符串表示形式。如果参数为null,则返回字符串“null”。
  String.valueOf(Object obj)方法的内部实现:

public static String valueOf(Object obj) {
        return (obj == null) ? "null" : obj.toString();
    }

  Object.toString()方法的内部实现:

public String toString() {
        return getClass().getName() + "@" + Integer.toHexString(hashCode());
    }

toString(Object o, String nullDefault)

    public static String toString(Object o, String nullDefault) {
        return (o != null) ? o.toString() : nullDefault;
    }

  若第一个参数不是 null ,则返回在第一个参数上调用 toString的结果,否则返回第二个参数。

compare

    public static <T> int compare(T a, T b, Comparator<? super T> c) {
        return (a == b) ? 0 :  c.compare(a, b);
    }

  注意:若其中一个参数为null ,是否会抛出空指针异常NullPointerException取决于排序策略,如果有的话,则由Comparator来决定空值null。
代码实例:

        int num1 = 100;
        int num2 = 200;
        System.out.println(Objects.compare(num2, num1, new Comparator<Integer>() {

            @Override
            public int compare(Integer o1, Integer o2) {
                if (o1 - o2 > 0){
                    return 1;
                }else{
                    return -1;
                }
            }

        }));
        System.out.println(Objects.compare(new Object(), new Object(), new Comparator<Object>() {

            @Override
            public int compare(Object o1, Object o2) {
                return o1.hashCode() - o2.hashCode();
            }

        }));

requireNonNull

requireNonNull​(T obj)

    public static <T> T requireNonNull(T obj) {
        if (obj == null)
            throw new NullPointerException();
        return obj;
    }

  检查指定的对象引用是不是null 。若为null,则抛出空指针异常,否则返回对象本身。此方法主要用于在方法和构造函数中进行参数校验,如下所示:

 public Foo(Bar bar) {
     this.bar = Objects.requireNonNull(bar);
 }

  当我们通过带参的构造函数创建对象时,创建对象的同时就可以进行参数校验。

requireNonNull​(T obj, String message)

    public static <T> T requireNonNull(T obj, String message) {
        if (obj == null)
            throw new NullPointerException(message);
        return obj;
    }

  该方法是requireNonNull的重载方法,当被校验的参数为null时,根据第二个参数message抛出自定义的NullPointerException 。
  注:此方法主要用于在具有多个参数的方法和构造函数中进行参数校验,如下所示:

public Foo(Bar bar, Baz baz) {
     this.bar = Objects.requireNonNull(bar, "bar must not be null");
     this.baz = Objects.requireNonNull(baz, "baz must not be null");
 }

isNull

    public static boolean isNull(Object obj) {
        return obj == null;
    }

  判空方法,如果参数为null则返回true,否则返回false。

nonNull

    public static boolean nonNull(Object obj) {
        return obj != null;
    }

  判断非空方法,若参数是非空,返回true,否则返回false。

本文地址:https://blog.csdn.net/weixin_41758106/article/details/109264060

《Java常用类-----java.util.Objects工具类详解.doc》

下载本文的Word格式文档,以方便收藏与打印。