- 浏览: 255717 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
aquarion:
非常感谢,解决了我的问题
Perspective 自定义设置扩展点 -
zheng_zhen:
好文章,进一步问您一下,请问自己实现的run/debug如何能 ...
【原创】Eclipse Launcher (Run/Debug As 菜单扩展)实现 -
salever:
mwdnjupt 写道http://www.xeclipse. ...
浅析OSGI的bundle依赖 -
mwdnjupt:
http://www.xeclipse.com/?p=1165 ...
浅析OSGI的bundle依赖 -
Tom.X:
插件化、模块化应遵循高内聚、低耦合的原则,尽量不要在各bund ...
浅析OSGI的bundle依赖
equals 方法在非空对象引用上实现相等关系:
自反性:对于任何非空引用值 x,x.equals(x) 都应返回 true。
对称性:对于任何非空引用值 x 和 y,当且仅当 y.equals(x) 返回 true 时,x.equals(y) 才应返回 true。
传递性:对于任何非空引用值 x、y 和 z,如果 x.equals(y) 返回 true,并且 y.equals(z) 返回 true,那么 x.equals(z) 应返回 true。
一致性:对于任何非空引用值 x 和 y,多次调用 x.equals(y) 始终返回 true 或始终返回 false,前提是对象上 equals 比较中所用的信息没有被修改。
对于任何非空引用值 x,x.equals(null) 都应返回 false。
Object 类的 equals 方法实现对象上差别可能性最大的相等关系;即,对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true(x == y 具有值 true)。
注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码。
参数:
obj - 要与之比较的引用对象。
返回:
如果此对象与 obj 参数相同,则返回 true;否则返回 false。
另请参见:
hashCode(), Hashtable
我们先来看看Object中equals的实现:
public boolean equals(Object obj) { return (this == obj); }
当且仅当两个对象是同一个时,equals才返回true,这个实现当然满足以上的自反性、对称性、传递性、一致性。然而在绝大多数情况下,这个默认实现都不好用,用户往往需要重写这个方法。一旦重写了这个方法,很可能潜在的破坏了以上约束,给程序带来潜在威胁。
看一个Effective java中给出的一个违反对称性的例子:
/** * Case-insensitive string. Case of the original string is preserved by * toString, but ignored in comparisons. */ public final class CaseInsensitiveString { private String s; public CaseInsensitiveString(String s) { if (s == null) throw new NullPointerException(); this.s = s; } // Broken - violates symmetry! public boolean equals(Object o) { if (o instanceof CaseInsensitiveString) return s.equalsIgnoreCase(((CaseInsensitiveString) o).s); if (o instanceof String) // One-way interoperability! return s.equalsIgnoreCase((String) o); return false; } // Remainder omitted }
这个实现对于
CaseInsensitiveString cis = new CaseInsensitiveString("Polish"); String s = "polish";
cis.equals(s) 为true,而s.equals(cis) 为false。如果出现下面的代码,结果是什么呢?
List list = new ArrayList(); list.add(cis); list.contains(s) = ?
到底list.contains(s)返回true还是false,这就说不清了。按照目前的JVM实现,这个是false。
一个可能的实现为:
public boolean equals(Object o) { return o instanceof CaseInsensitiveString && ((CaseInsensitiveString) o).s.equalsIgnoreCase(s); }
再看一个违反传递性的例子:
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; } // Broken - violates transitivity. public boolean equals(Object o) { if (!(o instanceof Point)) return false; // If o is a normal Point, do a color-blind comparison if (!(o instanceof ColorPoint)) return o.equals(this); // o is a ColorPoint; do a full comparison ColorPoint cp = (ColorPoint) o; return super.equals(o) && cp.color == color; } }
根据上面的实现
ColorPoint p1 = new ColorPoint(1, 2, Color.RED); Point p2 = new Point(1, 2); ColorPoint p3 = new ColorPoint(1, 2, Color.BLUE);
p1.equals(p2) = ture && p2.equals(p3) = true,而p1.equals(p3) = false,原因很简单,在
if (!(o instanceof ColorPoint)) return o.equals(this);
这里出了问题,当o为Point时,调用了Point的equals(),忽略了color属性,从而使得p1.equals(p2)&&p2.equals(p3),一个可能的实现为
// Adds an aspect without violating the equals contract 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; } /** * Returns the point-view of this color point. */ public Point asPoint() { return point; } public boolean equals(Object o) { if (!(o instanceof ColorPoint)) return false; ColorPoint cp = (ColorPoint)o; return cp.point.equals(point) && cp.color.equals(color); } ... // Remainder omitted }
在重写扩展基类的equals方法时,最好放弃使用继承,而采取组成的方式,将基类作为一个成员属性,这样可以避免由继承带来的各种问题。There is simply no way to extend an instantiable class with a new aspect while preserving the compareTo contract。如果你想扩展一个已经实现了equals的类,不要去继承它,而是在类中使用一个它的实例对象作为成员。
接下来讲讲 == 操作符与equals()的关系。== 比较两个对象时,返回true意味着两个对象是同一个。在Object的默认实现中,== 与equals就是一回事,也就是
Object obj1, obj2;
obj1.equals(obj2) 与obj1 == obj2 是一样的效果,
但是要注意在obj1、obj2都为null时,前者会抛出异常而后者则返回true。
Object obj1 = null, obj2 = null; if(obj1 == obj2){ System.out.println("true"); }else{ System.out.println("false"); } if(obj1.equals(obj2)){ System.out.println("true"); }else{ System.out.println("false"); } }
输出为:
Exception in thread "main" java.lang.NullPointerException
参考文档:
1,《Efficient Java》 Joshua Bloch
2, J2sk 6.0 API
发表评论
-
Java 技能树
2016-07-25 18:58 818java技能树 -
Java看书笔记
2014-08-07 17:15 729这一篇专用于一些日常的Java读书笔记 先写一点关 ... -
XStream和Jackson的使用优化
2012-12-17 11:09 0marker一下,需要研究一下这2种lib的使用方式。 -
ArrayList与LinkedList的简单比较
2012-07-27 11:07 1560本文同步发表在http://www.xeclipse.com/ ... -
java.lang.System类浅析
2012-07-25 09:58 1922本文同步发表在 http://www.xeclipse.com ... -
Linux/Unix下JFreeChart的NoClassDefFoundError问题
2012-07-04 14:51 1678最近遇到这样一个问题,使用JFreechart 1.0.13开 ... -
【转】常见的开源协议
2011-08-12 15:47 519Mozilla Public License ... -
【转】JDK发布版本时间以及代号
2011-06-20 14:02 1590已发行的版本: 版本号 名称 中文名 发布日期 ... -
最近的apache学习计划
2011-06-09 11:58 1242最近可能会要做一些apache相关的学习和开发工作,有一些pr ... -
Object类wait,notify,notifyAll的使用
2011-05-06 11:02 1475这三个方法是java的基础类Object中定义的。 w ... -
Java nio 整理整理
2011-02-25 17:17 1113看了看Java的nio类库,整理一下思路。 1,Buf ... -
Java 内存的那些事
2011-02-22 10:38 5025虽然Java屏蔽了一下内存 ... -
一些有用的Web Service 地址
2011-02-11 11:11 2221这里记录一下比较有用的Web Service 地址,可能会有用 ... -
【Java】利用HTML生成PDF之问题整理
2011-01-06 14:38 3957首先,技术为apache 的FOP ... -
【转】如何在java程序中设置文件为“隐藏”属性
2010-10-19 10:55 1635引自http://linshiquan.iteye.com/b ... -
【转】字符,字节和编码
2010-10-18 10:09 1218引言 “字符与编码” ... -
Effective Java 第2版 笔记
2010-08-18 15:45 1880Item 1;Consider static factoriy ... -
Java, 那些美妙的书籍
2010-08-10 15:39 7223整理一下最近看过或者比较有兴趣的Java书籍,以供大家参考 ... -
Object的equals()与hashCode()的关系
2010-08-10 14:37 0笔者在以前Java项目中使用findbugs工具时,经常遇到一 ... -
学习JVM 之 class文件校验器
2010-07-21 11:29 1984JVM中的class文件校 ...
相关推荐
例如,public boolean equals(Object o) 是一个正确的重写方法,而 public boolean equals(String o) 是一个重载方法,而不是重写方法。 equals 方法的实现 ------------------------- equals 方法的实现需要遵循...
在Java编程语言中,`equals()` 和 `hashCode()` 方法是Object类中的两个核心方法,所有类都默认继承自Object类。这两个方法在处理对象比较和集合操作时起着至关重要的作用。当我们创建自定义类并需要对对象进行精确...
Java 对象的toString和equals方法重写 在 Java 中,每个对象都继承自 Object 类,而 Object 类中定义了两个重要的方法:toString() 和 equals()。这两个方法都是非常重要的,它们分别用于对象的字符串表示和对象...
// 重写object的equals方法 public boolean equals(Object obj) { if (this == obj) return true; if (obj == null) return false; if (this.getClass() != obj.getClass()) return false; Students other = ...
### C# Equals 和 GetHashCode 方法重写 在C#编程中,`Equals` 和 `GetHashCode` 方法是非常重要的成员方法,它们对于确保对象的正确比较以及高效地存储和检索对象至关重要。这两个方法通常需要在自定义类中进行...
首先,`equals()` 方法是Object类中的一个基础方法,用于比较两个对象是否相等。默认情况下,它比较的是对象的内存地址,也就是引用是否相同。但在实际开发中,我们往往需要根据对象的内容来判断它们是否相等,这时...
1. **使用`override`关键字**:在自定义类中,使用`override`关键字重写基类`Object`的`Equals`方法。 ```csharp public override bool Equals(object obj) ``` 2. **类型检查**:在`Equals`方法内部,首先检查...
关于重写equals、hashcode以及compareTo方法! equals()方法是Object类中的一个方法,它用于比较两个对象是否相等。然而,它的默认实现是比较对象的引用(地址),而不是比较对象的实际内容。因此,在某些情况下,...
这两个方法通常与`Object`类中的默认实现相关联,但为了在实际开发中实现正确的对象比较和哈希表操作,我们往往需要重写它们。以下是对这两个方法的详细解释以及在实际开发中的应用。 `equals()` 方法: `equals()`...
在Java编程中,`equals()` 和 `hashCode()` 方法是Object类中的两个重要方法,它们在处理对象相等性以及在哈希表(如HashSet、HashMap)中起到关键作用。当自定义类时,有时需要根据业务逻辑重写这两个方法以满足...
"关于Object中equals方法和hashCode方法判断的分析" 在 Java 中,Object 类提供了两个重要的方法:equals 方法和 hashCode 方法。这两个方法都是用于比较两个对象是否相等的,但它们的实现机理和作用域却有所不同。...
对于自定义对象,我们通常需要重写`equals()`和`hashCode()`方法,以确保根据对象的属性进行比较,而不仅仅是引用。这在处理大量数据时尤其重要,因为正确实现这些方法可以显著提高容器(如ArrayList、HashSet、...
在Java编程语言中,"方法重写equals"和"多态"是两个核心概念,尤其对于面向对象的设计和实现至关重要。下面将详细解释这两个概念及其相互关系。 **方法重写equals()** 在Java中,`equals()`方法是Object类的一个...
关于 Java 中重写 equals 方法的种种坑 Java 中的 equals 方法是一种用于比较对象是否相等的方法,它是 Object 类中的一个方法。然而,重写 equals 方法并不是一件简单的事情,因为它需要遵守一些约定,否则可能会...
如果我们只重写了 `equals()` 来比较姓名和年龄,而没有重写 `hashCode()`,那么即使两个 `Person` 实例具有相同的姓名和年龄,它们在哈希表中的位置也可能不同,导致不必要的比较和潜在的性能问题。 总结来说,...
- 在重写`equals()`时,通常也需重写`hashCode()`,以保持两个方法的一致性,遵循equals和hashCode约定,确保当两个对象相等时,它们的哈希码也应该相等。 总结来说,理解`Object`类及其提供的方法是Java开发的基础...
Java 中关于 == 和 equal 的区别 及其 equals() 方法重写 Java 语言是 Sun 公司的开发成果,其主要特点是可以执行强,与平台的无关性使其实用性更强。但是 Java 中的 == 与 equal 是有区别的。 == 操作符是 Java ...
当我们在自定义类中重写 `equals()` 方法时,通常也需要重写 `hashCode()` 方法,这是为了遵循一些重要的原则和保证数据结构如 `HashMap`、`HashSet` 的正确行为。 首先,`equals()` 方法用于比较两个对象是否相等...
Java中equals()方法重写实现代码详解 Java中equals()方法是Object类中定义的,作为所有类的父类,任何类都隐含地继承了该方法。 equals()方法用于判断两个对象的内容是否相同,如果没有重写该方法的类,需要重写该...
`Equals()`方法是Object类的一个成员,因此所有C#类都默认继承了这个方法。然而,对于自定义类,`Equals()`方法的行为可能需要根据具体需求进行重写,以实现更加精确的比较逻辑。 首先,我们来看一下基本类型的`...