Java中Object 通用方法

16 篇文章 0 订阅
6 篇文章 0 订阅

Object 方法概述

  public boolean equals(Object obj)

  public native int hashCode()

  protected native Object clone() throws CloneNotSupportedException

  public String toString()

  public final native Class<?> getClass()

  protected void finalize() throws Throwable {}

  public final native void notify()

  public final native void notifyAll()

  public final native void wait(long timeout) throws InterruptedException

  public final void wait(long timeout, int nanos) throws InterruptedException

  public final void wait() throws InterruptedException

  一 equals()

    a) 性质:

        1. 自反性

   x.equals(x); // true

        2. 对称性

   x.equals(y) == y.equals(x); // true

        3. 传递性

   if (x.equals(y) && y.equals(z)){
      x.equals(z); // true;    
   }

        4. 一致性

      x.equals(y) == x.equals(y); // true

        多次调用equals()方法结果不变

        5. 非null型

   x.equals(null); // false; 

          equlas 参数为null时,则结果必定为false

     b) Object 源码中的equals方法

     public boolean equals(Object obj) {
        return (this == obj);
     }

          其实equals本身还是使用了==进行比较,

             对于基本数据类型比较内容是否相同

             对于引用数据类型比较对象hashCode是否相同,即比较的是不是同一个对象

         equals 比较必须有两个对象。

    c) 自定义重写equals方法 

        例:

    class People {
	private String id;
	private String name;
	private Integer age;
        People(String id,String name){
            this.id = id;
            this.name = name;
        }        
        @Override
	public int hashCode() {
	 final int prime = 31;
	    int result = 1;
	    result = prime * result + ((age == null) ? 0 : age.hashCode());
            result = prime * result + ((id == null) ? 0 : id.hashCode());
	    result = prime * result + ((name == null) ? 0 : name.hashCode());
	    return result;
    	}
    	@Override
	public boolean equals(Object obj) {
	    if (this == obj) //先使用==判断两个对象地址是否相同,相同的话就返回true。
	        return true;
	    if (obj == null) //如果比较的对象是null,直接返回false
		return false;
	    if (getClass() != obj.getClass()) 判断两个兑现的类型,相同就继续执行,否则返回false
		return false;
	    People other = (People) obj;//下面的步骤就是判断两个对象的各个属性,不相同返回false,所有属性都相同后返回true
	    if (age == null) {
		if (other.age != null)
	            return false;
	    } else if (!age.equals(other.age))
		return false;
	    if (id == null) {
		if (other.id != null)
		    return false;
	    } else if (!id.equals(other.id))
	        return false;
	    if (name == null) {
	        if (other.name != null)
		    return false;
	    } else if (!name.equals(other.name))
	        return false;
	    return true;
	}
    }

   

注意:

            重写equals()的时候一定要重写hashCode()

            例:

            假如现在有两个对象

                  People  p1 = new People("1","张三");

                  People  p2 = new People("1","张三");

            假如只重写了equals而不重写hashcode,那么people类就是Object默认的hashcode方法,由于默认的hashcode方法是根据对象的内存地址经哈希算法得来的,显然p1!=p2,故两者的hashcode不一定相同

            然而如果重写了equals,且p1.equals(p2)返回true,根据hashcode的规则,两个对象的哈希值就一定要相等,所以此处有矛盾,因此重写equals方法必须重写hashcode方法 

            hashcode 的规则:   

                1. 两个对象相同,hashcode一定相同

                    两个对象不同,hashcode不一定不同

                2. hashcode相同,两个对象不一定相同

                    hashcode不等,两个对象一定不同

 比较详情--->==和equals的区别 

 二 hashCode()方法

        1. hashCode()返回散列值,而equals()是用来判断两个对象是否等价,等价的两个对象散列值一定相同,但是散列值相同的两个对象不一定等价

            所以上述讲到在覆盖equals()方法的时候必须要覆盖hashCode()方法,以保证两个相同对象的散列值也是相同的。

    People p1 = new People("1","张三");
    People p2 = new People("1","张三);
    System.out.println(p1.equals(p2)); // true
    HashSet<People> set = new HashSet<People>();
    set.add(p1);
    set.add(p2); 
    System.out.println(set.size());   // 2

         此时我们希望两个对象是一样的,因为set集合添加的是唯一的对象<此时People 没有实现hashcode方法,因为这两个对象的散列值是不同的,最终导致添加了两个等价的对象。

       2. 理想的散列函数应当具有均匀性,即不相等的对象应当均匀分布到所有可能的散列值上。这就要求了散列函数要把所有域的值都考虑进来。可以将每个域都当成 R 进制的某一位,然后组成一个 R 进制的整数。R 一般取 31,因为它是一个奇素数,如果是偶数的话,当出现乘法溢出,信息就会丢失,因为与 2 相乘相当于向左移一位。

           一个数与 31 相乘可以转换成移位和减法:31*x == (x<<5)-x,编译器会自动进行这个优化。

  @Override
  public int hashCode() {
    int result = 17;
    result = 31 * result + x;
    result = 31 * result + y;
    result = 31 * result + z;
    return result;
  }

三  toString()方法

        默认返回 People@70dea4e 这种形式,即类名@散列码的无符号十六进制 

  public class People{	
    private String id;    
    public People(String id) {
        this.id= id;
    }    
    public static void main(String[] args) {
	System.out.println(new People("1").toString());
    }
  }

四 clone方法

     1. 是protect方法不能被重写    

     2. 复制引用

  Person p = new Person(23, "zhang");  
  Person p1 = p;

     3. 复制对象

  Person p = new Person(23, "zhang");  
  Person p1 = (Person) p.clone();

     4. 浅拷贝:引用同一个对象,不重写clone(),调用Object.clone()

     5. 深拷贝:引用不同的对象,实现Cloneable接口,重写方法。

  public class People implements Cloneable{
    private String id;
    public Object clone() {
    	People p = null;
    	try {
	    p = (People) super.clone();
	} catch (Exception e) {
	    e.printStackTrace();
	}
    	return p;
    }
  }

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值