精华内容
下载资源
问答
  • Java里对象equals方法

    2016-08-19 05:55:35
    如果我有个student类,里面有两个属性id和name,如果我重写equals和hashcode方法equals里判断name是否相等,hashcode里判断id。现在新建对象stu1(1,“aaa”)stu2(1,“aaa”) stu3(2,“aaa”)我想问下,...
  • 不是所有的equals都是比较整个对象的。 #1. 普通Object类: 先看源码: public boolean equals(Object obj) { return (this == obj); } 看到了没,用“==”,比较的是对象引用,也就是地址。假如两个对象...

    不是所有的equals都是比较整个对象的。


    #1. 普通Object类:

    先看源码:

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

    看到了没,用“==”,比较的是对象引用,也就是地址。假如两个对象传入的参数一样,但是都用new去创建,地址就不同了,那么用equals返回的就是false。


    #2. String类:

    先看源码:

        public boolean equals(Object anObject) {
    	if (this == anObject) {
    	    return true;
    	}
    	if (anObject instanceof String) {
    	    String anotherString = (String)anObject;
    	    int n = count;
    	    if (n == anotherString.count) {
    		char v1[] = value;
    		char v2[] = anotherString.value;
    		int i = offset;
    		int j = anotherString.offset;
    		while (n-- != 0) {
    		    if (v1[i++] != v2[j++])
    			return false;
    		}
    		return true;
    	    }
    	}
    	return false;
        }

    比较的是内容,所以只要内容一样,用new去创建的两个String对象,调用equals返回true。


    #3. Integer类

    先看源码:

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

    一样是比较内容。
    展开全文
  • java对象equals方法的重写

    千次阅读 2011-03-04 11:28:00
    我们知道每一个java类都继承自Object类,equals()是Object类中提供的方法之一。那么,让我们先来看看Object#equals()在Java中的原代码: public boolean equals(Object obj) { return (this == obj); } 可以看出,...

    又在javaEye发现了一篇好文章,迫切转过来呵呵

    http://www.javaeye.com/topic/269601

     

    什么时候需要重写equals()?
      我们知道每一个java类都继承自Object类,equals()是Object类中提供的方法之一。那么,让我们先来看看Object#equals()在Java中的原代码:

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

    可以看出,只有当一个实例等于它本身的时候,equals()才会返回true值。通俗地说,此时比较的是两个引用是否指向内存中的同一个对象,也可以称做是否实例相等。而我们在使用equals()来比较两个指向值对象的引用的时候,往往希望知道它们逻辑上是否相等,而不是它们是否指向同一个对象。在这样的情况下, 如果超类也没有重写equals()以实现期望的行为,这时我们就需要重写equals方法。而且这样做也使得这个类的实例可以被用做映射表(map)的键,或者集合(set)的元素,并使映射表或者集合表现出预期的行为。
    Object类提供的equals方法只是一个很简单的,不能适应应用程序有特殊要求的情况。
      比如网络对象,带有volatile属性的对象,或是带有多层子对象的复合对象,等等,是不能像String一类的对象进行简单比较的,所以提供了这样一个机制,就像serializable接口一样,既有默认的序列化方法,也提供了程序自己定制,覆盖默认方式的可能性。
      Object仅仅提供了一个对引用的比较,如果两个引用不是同一个那就返回false,这是无法满足大多数对象比较的需要的,所以要覆盖。

    怎样重写equals()方法?
      重写equals()方法看起来非常简单,但是有许多改写的方式会导致错误,并且后果非常严重。要想正确改写equals()方法,你必须要遵守它的通用约定。下面是约定的内容,来自java.lang.Object的规范:
    equals方法实现了等价关系(equivalence relation):
    1. 自反性:对于任意的引用值x,x.equals(x)一定为true。
    2. 对称性:对于任意的引用值x 和 y,当x.equals(y)返回true时,
      y.equals(x)也一定返回true。
    3. 传递性:对于任意的引用值x、y和z,如果x.equals(y)返回true,
      并且y.equals(z)也返回true,那么x.equals(z)也一定返回true。
    4. 一致性:对于任意的引用值x 和 y,如果用于equals比较的对象信息没有被修
      改,多次调用x.equals(y)要么一致地返回true,要么一致地返回false。
    5. 非空性:对于任意的非空引用值x,x.equals(null)一定返回false。
    接下来我们通过实例来理解上面的约定。我们首先以一个简单的非可变的二维点类作为开始:
    public class Point{
      private final int x;
      private final int y;
      public Point(int x, int y){
        this.x = x;
        this.y = y;
      }

      public boolean equals(Object o){
        if(!(o instanceof Point))
          return false;
        Point p = (Point)o;
          return p.x == x && p.y == y;
      }

    }


    假设你想要扩展这个类,为一个点增加颜色信息:
    public class ColorPoint extends Point{
      private Color color;
      public ColorPoint(int x, int y, Color color){
        super(x, y);
        this.color = color;
      }

      //override equasl()

      public boolean equals(Object o){
        if(!(o instanceof ColorPoint))
         return false;
        ColorPoint cp = (ColorPoint)o;
        return super.equals(o) && cp.color==color;
      }
    }


      我们重写了equals方法,只有当实参是另一个有色点,并且具有同样的位置和颜色的时候,它才返回true。可这个方法的问题在于,你在比较一个普通点和一个有色点,以及反过来的情形的时候,可能会得到不同的结果:
    public static void main(String[] args){
      Point p = new Point(1, 2);
      ColorPoint cp = new ColorPoint(1, 2, Color.RED);
      System.out.println(p.equals(cp));
      System.out.println(cp.eqauls(p));
    }

    运行结果:
    true  
    false
    这样的结果显然违反了对称性,你可以做这样的尝试来修正这个问题:让ColorPoint.equals在进行“混合比较”的时候忽略颜色信息:
    public boolean equals(Object o){
      if(!(o instanceof Point))
        return false;
      //如果o是一个普通点,就忽略颜色信息
      if(!(o instanceof ColorPoint))
        return o.equals(this);
      //如果o是一个有色点,就做完整的比较
      ColorPoint cp = (ColorPoint)o;
      return super.equals(o) && cp.color==color;
    }

    这种方法的结果会怎样呢?让我们先来测试一下:
    public static void main(String[] args){
      ColorPoint p1 = new ColorPoint(1, 2, Color.RED);
      Point p2 = new Point(1, 2);
      ColorPoint p3 = new ColorPoint(1, 2, Color.BLUE);
      System.out.println(p1.equals(p2));
      System.out.println(p2.equals(p1));
      System.out.println(p2.equals(p3));
      System.out.println(p1.eqauls(p3));
    }

    运行结果:
    true
    true
    true
    false

      这种方法确实提供了对称性,但是却牺牲了传递性(按照约定,p1.equals(p2)和p2.eqauals(p3)都返回true,p1.equals(p3)也应返回true)。要怎么解决呢?事实上,这是面向对象语言中关于等价关系的一个基本问题。要想在扩展一个可实例化的类的同时,既要增加新的特征,同时还要保留equals约定,没有一个简单的办法可以做到这一点。新的解决办法就是不再让ColorPoint扩展Point,而是在ColorPoint中加入一个私有的Point域,以及一个公有的视图(view)方法:
    public class ColorPoint{
      private Point point;
      private Color color;
      public ColorPoint(int x, int y, Color color){
        point = new Point(x, y);
        this.color = color;
      }

      //返回一个与该有色点在同一位置上的普通Point对象
      public Point asPoint(){
        return point;
      }

      public boolean equals(Object o){
        if(o == this)
         return true;
        if(!(o instanceof ColorPoint))
         return false;
        ColorPoint cp = (ColorPoint)o;
        return cp.point.equals(point)&&
                 cp.color.equals(color);

      }
    }

      还有另外一个解决的办法就是把Point设计成一个抽象的类(abstract class),这样你就可以在该抽象类的子类中增加新的特征,而不会违反equals约定。因为抽象类无法创建类的实例,那么前面所述的种种问题都不会发生。

    重写equals方法的要点:
    1. 使用==操作符检查“实参是否为指向对象的一个引用”。
    2. 使用instanceof操作符检查“实参是否为正确的类型”。
    3. 把实参转换到正确的类型。
    4. 对于该类中每一个“关键”域,检查实参中的域与当前对象中对应的域值是否匹
      配。对于既不是float也不是double类型的基本类型的域,可以使用==操作符
      进行比较;对于对象引用类型的域,可以递归地调用所引用的对象的equals方法;
      对于float类型的域,先使用Float.floatToIntBits转换成int类型的值,
      然后使用==操作符比较int类型的值;对于double类型的域,先使用
      Double.doubleToLongBits转换成long类型的值,然后使用==操作符比较
      long类型的值。
    5. 当你编写完成了equals方法之后,应该问自己三个问题:它是否是对称的、传
      递的、一致的?(其他两个特性通常会自行满足)如果答案是否定的,那么请找到
      这些特性未能满足的原因,再修改equals方法的代码。

    展开全文
  • JS 中对象equals方法的实现

    千次阅读 2006-05-28 21:13:00
    上次我们谈到Javascript ...克隆满足的条件clone()方法对象复制了一份并返还给调用者。所谓“复制”的含义与clone()方法是怎么实现的有关。一般而言,clone()方法满足以下的描述:第一、对任何的对象x,都有:x.clone

    上次我们谈到Javascript 中 浅拷贝与深拷贝的实现..
    这回我们看看如何实现判断两个对像的内容是否相等。
    这里有一个克隆结果原则是针对Java语言的,当然JavaScript也可以胜任。

    克隆满足的条件
    clone()方法将对象复制了一份并返还给调用者。所谓“复制”的含义与clone()方法是怎么实现的有关。一般而言,clone()方法满足以下的描述:

    第一、对任何的对象x,都有:x.clone() != x;换言之,克隆对象与原对象不是同一个对象。

    第二、对任何的对象x,都有:x.clone().getClass == x.getClass(),换言之,克隆对象与原对象的类型一样;在Javascript getClass 就相当于constructor。

    第三、如果对象x的equals()方法是定义恰当的话,那么 x.clone().equals(x)也应当是成立的。

    在Java语言的API中,凡是提供了clone()方法的类,都满足上面的这些这些条件。Java语言的设计师在设计自己的clone()方法是,也应当遵守这三个条件。
    第三条为可选,不必强制实现的,意思是说只要编制得当,也可以实现。
    我们还拿上次的例子看一下:
    运行代码框

    [Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]

    其它对像的equals 方法的样例:
    后面一个,我重定义了 Boolean 构造函数,并实现了它的toStirng()方法。
    可以瞅瞅。
    运行代码框

    [Ctrl+A 全部选择 提示:你可先修改部分代码,再按运行]

    展开全文
  • HashSet 添加元素,首先比较hash值 ...测试方法,使用一个Java Bean的person类,有name和age两个域,覆写public boolean equals(Object obj) 和public int hashCode() 两个方法,覆写方法中都添加一句输出语句,测试是

    HashSet 添加元素,首先比较hash值 是否有相同hash,没有则添加成功,有则继续比较equals,如果不同则添加成功,否则不添加。


    测试方法,使用一个Java Bean的person类,有name和age两个域,覆写public boolean equals(Object obj)  和public int hashCode()  两个方法,覆写方法中都添加一句输出语句,测试是否该方法被调用/

    person类:


    package info.dyndns.oszc;
    
    public class Person {
    
    	public String name;
    	public int age;
    	
    	public Person(String name, int age)
    	{
    		this.name = name;
    		this.age = age;
    	}
    	
    	public void print(){
    		System.out.println(name + age);
    	}
    
    	public String getName() {
    		return name;
    	}
    
    	public void setName(String name) {
    		this.name = name;
    	}
    
    	public int getAge() {
    		return age;
    	}
    
    	public void setAge(int age) {
    		this.age = age;
    	}
    	public String toString(){
    		return getName() +".." + getAge();
    	}
    
    	@Override
    	public boolean equals(Object obj) {
    		System.out.println("调用equals方法");  //这里打印为了看清程序是否调用了equals方法
    		if( !(obj instanceof Person)){
    			return false;
    		}
    		
    		Person p =(Person) obj;
    		
    		return getName().equals(p.getName()) && getAge()==p.getAge();
    	}
    
    	@Override
    	public int hashCode() {
    		System.out.println("调用hashCode方法,hash为:"+ getName().hashCode() + getAge()*9); //这里打印为了看清程序是否调用了equals方法
    		return getName().hashCode() + getAge()*9;
    	}
    	
    }
    




    工具类


    package info.dyndns.oszc;
    
    import java.util.*;
    
    public class Utils {
    
    	public static <E>void print(E e)
    	{
    		System.out.println(e);
    	}
    	public static <E>void printElements(Collection<E> al)
    	{
    		Iterator<E> it = al.iterator();
    	
    		while (it.hasNext()){
    			print(it.next());
    		}
    	}
    	public static <E>void put (Collection al,E e)
    	{
    		if (!al.contains(e))
    			al.add(e);
    	}
    }
    

    测试类,首先添加两个不同的元素

    package info.dyndns.oszc;
    
    import java.util.HashSet;
    
    public class HashSetTest {
    
    	public void test(){
    		HashSet<Person> hs = new HashSet<Person>();
    		hs.add(new Person("zs", 11));
    		hs.add(new Person("ls", 12));
    		Utils.printElements(hs);
    	}
    	
    	public static void main(String[] args) {
    		HashSetTest hst = new HashSetTest();
    		hst.test();
    	}
    }
    

    output:

    调用hashCode方法,hash为:389799
    调用hashCode方法,hash为:3463108
    ls..12
    zs..11
    

    显然调用了两次hashcode方法,由于hash值不同,所以没有调用equals方法。


    然后我们添加两遍同一个元素:

    package info.dyndns.oszc;
    
    import java.util.HashSet;
    
    public class HashSetTest {
    
    	public void test(){
    		HashSet<Person> hs = new HashSet<Person>();
    		hs.add(new Person("zs", 11));
    		hs.add(new Person("zs", 11));
    		Utils.printElements(hs);
    	}
    	
    	public static void main(String[] args) {
    		HashSetTest hst = new HashSetTest();
    		hst.test();
    	}
    }
    

    output:

    调用hashCode方法,hash为:389799
    调用hashCode方法,hash为:389799
    调用equals方法
    zs..11
    

    可以看出当hash值相同时,equals方法会被调用,当他们都相同,则hashset判断两个元素完全一致,所以后一个元素未能加入到hashset集合中。


    所以我们在自定义类要添加到hashset中时候,务必重写以上两个方法,来保证hashset添加元素的唯一性。

    展开全文
  • JAVA对象equals方法

    2019-03-07 23:34:57
    一切类都是Object的子类,Object有equals方法,因此所有对象都有equals方法。 此方法可以按程序自己的规则判断两个对象是否相等,比如以下代码: String a = new String(&quot;hi&quot;); String b = new...
  • 通常我们比较对象是想比较对象的内容是否相同,我们可以通过重写Object类的equals方法或者用String类的equals方法来达到预期结果。
  • 对象equals()方法的书写模板

    千次阅读 2016-12-26 15:37:53
    下面先给出编写一个完美的equals方法的建议: 1)显示参数命名为otherObject,稍后需要将他转变成另一个叫做other的变量 2)检测this与otherObject是否引用了同一个对象: if(this == otherObject) return true; 3)...
  • equals方法

    万次阅读 2018-06-28 19:50:31
    因为Java中所有类都继承自Object类,所以Java中的所有对象都有equals方法。 /** * Object类默认的equals()方法 */ public boolean equals(Object obj) { return (this == obj); } 重写equals方法 Object的...
  • Java对象equals方法分析与重写

    千次阅读 2015-07-26 14:46:08
     equals才是比较的对象的内容,且Object类的equals方法的默认实现也是按照内存地址比较对象是否相等。  Javaequals方法有以下特性:  1、自反性:对任意引用值X,x.equals(x)的返回值一定为true.  2、对称性:...
  • 重写对象equals方法和hascode方法

    千次阅读 2015-09-15 18:14:02
    如果List里面存储的是对象,会调用对象equals方法和hasCode方法 因此要重新写,没有重写的对象比较是失效的。第一次遇到要比较对象是否相等。主要是对象的属性值是否相等 注:instanceof用法,判断...
  • 在Java语言中,equals方法在使用时: ... 针对String对象,比较的也是String的值(因为String内部重写了equals方法和hashCode方法)  针对其他object对象,比较的是两个对象的引用是否指向同一个内存地址
  • 前言:我们都知道String也是对象,但是用String的==和equals()来判断和其他对象的==和equals()来判断的结果是不是一样呢?看代码:package zm.demo;import java.util.HashMap; import java.util.Iterator; import ...
  • 为什么要重写hashCode和equals方法以及如何重写
  • 重写equals方法

    千次阅读 2019-03-17 16:24:17
    Object类是Java中所有类的基类,Object类中的equals方法实际比较的是两个对象的内存地址是否相等。如果两个引用指向同一个对象,则equals返回true,否则返回false Object类中equals方法定义如下: public boolean ...
  • 如String类型的变量,是靠调用equals方法来比较的,而其它的类似数组或普通的对象直接调用equals方法一般是不可以的,这是因为String类型的变量通过调用equals方法来比较变量是因为String类覆盖了Object的HashCode...
  • 两个对象equals方法比较为true,它们的Hashcode值相同吗?  答:不一定相同。正常情况下,因为equals()方法比较的就是对象在内存中的值,如果值相同,那么Hashcode值也应该相同。但是如果不重写hashcode方法,...
  • 面试题:下面程序输出结果? package com.wlkj.test; public class EqualTest { public static void main(String[] args) { StringBuffer str = new StringBuffer("... if(str.equals("")){ S...
  • 但是比较两个对象的引用时,==比较的是两个引用是否引用的同一个对象。 测试代码如下: public class Test_1 { public static void main(String[] args) { A a1 = new A(); A a2 = new A(); A a3 = a2; System...
  • 重写hashcode和equals方法

    万次阅读 多人点赞 2019-05-07 21:55:43
    一。前言 我们都知道,要比较两个对象是否相等时需要调用对象的equals()方法,即判断对象引用所指向的对象地址是否相等,对象地址相等...对象在不重写的情况下使用的是Object的equals方法和hashcode方法,从Object...
  • 实例对象的clone 对于八种基本数据类型clone则比较简单: int m=10; int n=m; 这样就可以实现基本数据类型的clone,但是实例对象就不可以,因为上述操作对象,只是两个变量都指向同一个对象,因此通过任何一个...
  • 一,equals方法的作用:检测一个对象是否等于另一个对象   1)比较两个基本类型的数据的值是否相等。这里是直接比较的值。【错误:基本数据类型没有equals方法】 mark:Java中的基本类型: int,4个字节存储,4...
  • 判断两个对象内容相等与equals方法

    千次阅读 2015-04-30 17:12:01
    不能直接调用Object类里的equals方法,将equals方法写到Object类当中是让所有对象都拥有equals方法,,它的目的是给开发者重写的,不然其方法实现的功能与’==’一模一样 而用==号是不能判断两个对象内容相等的 eg...
  • 对象equal()方法的实现 方法来自《Java核心技术·卷一》 (2)是为了判断是否指向同一对象,以优化运行速度。 (4)是为了判断超类与子类。 (5)(6)是将其做显式转换后,再判断内部域的比较。 ...
  • equals呢, Object类中默认实现equals方法的语句如下: public boolean equals(Object o){  return (this==obj);//没懂的地方,this==obj,this指什么 }   相当于Object类中...
  • equals和hashcode总结

    万次阅读 多人点赞 2019-07-31 18:37:06
    1.equals方法没有重写的话,用于判断对象的内存地址引用是否是用一个地址。重写之后一般用来比较对象的内容是否相等(比如student对象,里面有姓名和年龄,我们重写 equals方法来判断只要姓名和年龄相同就认为是用...
  • 判断对象是否相等---重写equals方法

    千次阅读 2016-03-24 13:24:33
    前言学习了面向对象编程语言,对于对象理应有了一定的理解,...开篇前先扫下盲,一些新手在比较对象的时候可能会使用 == 比较,这是很严重的一个错误,众所周知,String 也是对象对象的比较是使用equals方法!!!好
  • 学习了多年的java的人对hashCode和equals方法都不是很清楚。 总的来说,Java中的集合(Collection)有两类,一类是List,另一类是Set。前者集合内的元素是有序的,元素可以重复;后者元素无序,但元素不可重复。那么...

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 575,987
精华内容 230,394
关键字:

对象的equals方法