zoukankan      html  css  js  c++  java
  • 好用的java.util.Objects类

    好用的java.util.Objects

    在jdk1.7中,新增了一个工具类,就是java.util.Objects类。它有3个简单的封装方法,对于平常的使用来说挺有用的,分别是:hashCodeequalstoString这3个方法。

    1、hashcode生成

    // 1. Objects.hash(Object... values)
    public static int hash(Object... values) {
        return Arrays.hashCode(values);
    }
    
    // 2. Arrays.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;
    }
    
    // 3. Object.hashCode()
    public native int hashCode();

    首先,Objects的hash方法接收可变参数,可变参数的内部是一个数组。然后内部调用Arrays的hashCode方法,我们来看一下其方法:核心是遍历每一个参数来计算result值,在计算的过程中,每一个参数上转型为Object使用hashCode来生成随机值。那么Object的hashCode又是什么?这是一个本地方法,源码不给出实现,其数值和对象的内存地址有关。

    参数虽然上转型为Object,但是对于String、Integer等对象类型,它们都重写了hashCode方法。

    因为是基于内存地址的生成,所以不同对象生成的hashcode值冲突的几率是很小的。

    2、对象equals比较

    // 1. Objects.equals(Object a, Object b)
    public static boolean equals(Object a, Object b) {
        return (a == b) || (a != null && a.equals(b));
    }
    
    // 2. Object.equals(Object obj)
    public boolean equals(Object obj) {
      return (this == obj);
    }

    首先是对象的引用判断,其次就是调用对象自身的equals方法来比较,如果对象类型没有重写equals的话,就会调用Object的equals方法(仍然是对象的引用比较)。

    事实上,我们进行equals比较的对象,除了引用对象之外,就是String、Integer(自动装箱后)等类型了。

    对于String,直接进行引用比较。而对于Integer、Double等对象类型,它们都重写了equals方法,贴出Integer的equals方法:

    public boolean equals(Object obj) {
      if (obj instanceof Integer) {
          return value == ((Integer)obj).intValue();
      }
        return false;
    }

    可以看到,内部是进行值相等判断。

    hashCode与equals方法的重要性

    对于散列结构(hash)的集合类型,比如说HashMap、HashSet等,如果我们用它们来存储我们自定义的对象,那么我们就必要重写类的hashCode与equals方法。<u>为什么要重写,这个原因就不赘述了。</u> 还有Set集合类,由于它存储不重复的元素。

    下面我们给出利用Objects工具类的一种较为简单实用的重写方式:

    public class Building {
    
        private String name;
        private double area;
    
        @Override
        public int hashCode() {
            return Objects.hash(name, area);
        }
    
        @Override
        public boolean equals(Object obj) {
              // 引用相等判断
            if (obj == this) {
                return true;
            }
              // 类型判断
            if (!(obj instanceof Building)) {
                return false;
            }
            Building building = (Building) obj;
              // 关键域相等判断
            // 基本类型不要用用Objects.equals()方法,会自动装箱带来额外开销
            return Objects.equals(name, building.name) && (area == building.area);
        }
    
        @Override
        public String toString() {
            return Objects.toString("name = " + name, "name is undefined") + ", "
                    + Objects.toString("area = " + area, "area is undefined");
        }
    
          // setter、getter
    }

    3、toString

    我们自己重写toString方法时,有一点比较难写,就是默认值设置。

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

    我们在重写toString时,可以参考上面的Building类的写法。

  • 相关阅读:
    Scala并发编程react、loop代码实战具体解释
    Linux内核通知链模块
    STL栈的应用之表达式求值
    ansi 控制码表及颜色代码
    关于substring的char[]共享
    jQuery几个经典表单应用整理回想
    ShareSDK for Android 2.3.10已经公布
    cocos2dx坐标系
    一种Android数据请求框架
    css 小问题解决方法整理
  • 原文地址:https://www.cnblogs.com/shoshana-kong/p/14985432.html
Copyright © 2011-2022 走看看