问题

面试时经常会问起字符串比较相关的问题,

总结一下,大体是如下几个:

1.字符串比较时用的什么方法,内部实现如何?

2.hashcode的作用,以及重写equal方法,为什么要重写hashcode方法?

现在对以上几个问题,彻底做一个研究和小结.

PS:本文使用jdk1.7

解析

1.Object类 的equals 方法

   /**
* Indicates whether some other object is "equal to" this one.
* <p>
* The {@code equals} method implements an equivalence relation
* on non-null object references:
* <ul>
* <li>It is <i>reflexive</i>: for any non-null reference value
* {@code x}, {@code x.equals(x)} should return
* {@code true}.
* <li>It is <i>symmetric</i>: for any non-null reference values
* {@code x} and {@code y}, {@code x.equals(y)}
* should return {@code true} if and only if
* {@code y.equals(x)} returns {@code true}.
* <li>It is <i>transitive</i>: for any non-null reference values
* {@code x}, {@code y}, and {@code z}, if
* {@code x.equals(y)} returns {@code true} and
* {@code y.equals(z)} returns {@code true}, then
* {@code x.equals(z)} should return {@code true}.
* <li>It is <i>consistent</i>: for any non-null reference values
* {@code x} and {@code y}, multiple invocations of
* {@code x.equals(y)} consistently return {@code true}
* or consistently return {@code false}, provided no
* information used in {@code equals} comparisons on the
* objects is modified.
* <li>For any non-null reference value {@code x},
* {@code x.equals(null)} should return {@code false}.
* </ul>
* <p>
* The {@code equals} method for class {@code Object} implements
* the most discriminating possible equivalence relation on objects;
* that is, for any non-null reference values {@code x} and
* {@code y}, this method returns {@code true} if and only
* if {@code x} and {@code y} refer to the same object
* ({@code x == y} has the value {@code true}).
* <p>
* Note that it is generally necessary to override the {@code hashCode}
* method whenever this method is overridden, so as to maintain the
* general contract for the {@code hashCode} method, which states
* that equal objects must have equal hash codes.
*
* @param obj the reference object with which to compare.
* @return {@code true} if this object is the same as the obj
* argument; {@code false} otherwise.
* @see #hashCode()
* @see java.util.HashMap
*/
public boolean equals(Object obj) {
return (this == obj);
}

看代码,Object的equals方法,采用== 进行比较,只是比较对象的引用,如果引用的对象相同,那么就返回true.

看注释,Object的equals方法,具有如下特性

1.reflexive-自反性  

x.equals(x)  return true

2.symmetric-对称性

x.equals(y)  return true

y.equals(x)  return true

3.transitive-传递性

x.equals(y)  return true

y.equals(z)  return true

x.equals(z)  return true

4.consistent-一致性

x.equals(y)  return true //那么不管调用多少次,肯定都是返回true

5.与null的比较

x.equals(null) return false //对于none-null的x对象,每次必然返回false

6.于hashcode的关系

     * Note that it is generally necessary to override the {@code hashCode}
     * method whenever this method is overridden, so as to maintain the
     * general contract for the {@code hashCode} method, which states
     * that equal objects must have equal hash codes.

      需要注意的是,一般来说,如果重写了equals方法,都必须要重写hashcode方法,

      来确保具有相同引用的对象,能够具有同样的hashcode值

好了,看到这里,我们就明白了,为什么重写了equals方法,一般来说就需要重写hashcode方法,

虽然这个不是强制性的,但是如果不能保证相同的引用对象,没有相同的hashcode,会对系统留下很大隐患

2.String类的equals方法

   /**
* Compares this string to the specified object. The result is {@code
* true} if and only if the argument is not {@code null} and is a {@code
* String} object that represents the same sequence of characters as this
* object.
*
* @param anObject
* The object to compare this {@code String} against
*
* @return {@code true} if the given object represents a {@code String}
* equivalent to this string, {@code false} otherwise
*
* @see #compareTo(String)
* @see #equalsIgnoreCase(String)
*/
public boolean equals(Object anObject) {
if (this == anObject) {
return true;
}
if (anObject instanceof String) {
String anotherString = (String) anObject;
int n = value.length;
if (n == anotherString.value.length) {
char v1[] = value;
char v2[] = anotherString.value;
int i = 0;
while (n-- != 0) {
if (v1[i] != v2[i])
return false;
i++;
}
return true;
}
}
return false;
}

看源码,我们可以发现,这个比较分为两部分

1.先比较是否引用同一对象

2.如果引用对象不同,是否两个String的content相同

3,String 类的hashcode 方法

    /**
* Returns a hash code for this string. The hash code for a
* <code>String</code> object is computed as
* <blockquote><pre>
* s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]
* </pre></blockquote>
* using <code>int</code> arithmetic, where <code>s[i]</code> is the
* <i>i</i>th character of the string, <code>n</code> is the length of
* the string, and <code>^</code> indicates exponentiation.
* (The hash value of the empty string is zero.)
*
* @return a hash code value for this object.
*/
public int hashCode() {
int h = hash;
if (h == 0 && value.length > 0) {
char val[] = value; for (int i = 0; i < value.length; i++) {
h = 31 * h + val[i];
}
hash = h;
}
return h;
}

可以看到hashcode的计算公式为:s[0]*31^(n-1) + s[1]*31^(n-2) + ... + s[n-1]

因此,对于同一个String,得出的hashcode必然是一致的

另外,对于空的字符串,hashcode的值是0

小结

至此,我们可以对本文开头的疑问做一个小结.

1.字符串比较时用的什么方法,内部实现如何?

使用equals方法,先比较引用是否相同,后比较内容是否一致.

2.hashcode的作用,以及重写equal方法,为什么要重写hashcode方法?

hashcode是系统用来快速检索对象而使用,equals方法是用来判断引用的对象是否一致,所以,当引用对象一致时,必须要确保其hashcode也一致,因此需要重写hashcode方法来确保这个一致性

1.字符串比较时用的什么方法,内部实现如何?

2.hashcode的作用,以及重写equal方法,为什么要重写hashcode方法?

Java equals 和 hashcode 方法的更多相关文章

  1. java :equals()和hashcode()方法的结合使用

    哈希表这个数据结构想必大多数人都不陌生,而且在很多地方都会利用到hash表来提高查找效率.在Java的Object类中有一个方法: 1 public native int hashCode(); 根据 ...

  2. java equals和hashcode方法

    equals()方法比较两个对象的引用是否相同 hashcode()方法比较两个对象的哈希码是否相同

  3. Java equals() 和hashCode()方法详解

    Java的Object类中定义了equals方法,Object类中的equals方法源代码如下,从源代码中可以看出Object类中的equals方法是用来返回判断两个对象是否指向同一个对象(引用地址) ...

  4. Java中的equals和hashCode方法

    本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...

  5. Java提高篇——equals()与hashCode()方法详解

    java.lang.Object类中有两个非常重要的方法: 1 2 public boolean equals(Object obj) public int hashCode() Object类是类继 ...

  6. Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例(转)

    Java中==.equals.hashcode的区别与重写equals以及hashcode方法实例  原文地址:http://www.cnblogs.com/luankun0214/p/4421770 ...

  7. 【转】Java中==、equals、hashcode的区别与重写equals以及hashcode方法实例

    原文地址:http://www.cnblogs.com/luankun0214/p/4421770.html 感谢网友的分享,记录下来只为学习. 1.重写equals方法实例   部分代码参考http ...

  8. java集合(3)- Java中的equals和hashCode方法详解

    参考:http://blog.csdn.net/jiangwei0910410003/article/details/22739953 Java中的equals方法和hashCode方法是Object ...

  9. java基础(十六)----- equals()与hashCode()方法详解 —— 面试必问

    本文将详解 equals()与hashCode()方法 概述 java.lang.Object类中有两个非常重要的方法: public boolean equals(Object obj) publi ...

随机推荐

  1. Mac 10.10 下安装jdk 1.7 以上

    mac 会默认的给用户安装1.6,1.6 以上的版本安装的时候就总是会提示错误问题 根据网上的安装方法,这里也总结下 首先确定挂载在mac上了 然后输入命令 (目前使用的jdk1.7Update67) ...

  2. Enterprise Solution 企业管理软件开发框架

    Enterprise Solution 开源项目资源汇总 Visual Studio Online 源代码托管 企业管理软件开发框架 Enterprise Solution 是一套管理软件开发框架,在 ...

  3. Oracle Autonomous Transactions(自治事务)

    Oracle Autonomous Transactions Autonomous transactions allow you to leave the context of the calling ...

  4. mysql基础: mysql列类型--字符串

    mysql列类型:整型   http://blog.csdn.net/jk110333/article/details/9342283 mysql列类型--时间和日期  http://blog.csd ...

  5. 使用 Nginx 创建服务器的负载均衡

    译序         Nginx 的负载均衡配置看上去很简单.以下是 Nginx 官方给的一个简单的负载均衡的例子: http {   upstream myproject {     server ...

  6. Mac必备软件推荐

    阅读原文http://littlewhite.us/archives/245 随着IOS的流行.Mac电脑也越来越多的进入人们的视野,和iPhone系列一样,苹果的Mac产品线也是软硬件完美结合.有着 ...

  7. COCOS2D中对精灵的操作、对图片的各种操作

    内容简要: 1.初始化 2.创建无图的精灵 3.设置精灵贴图大小  4.添加入层中 5.对精灵进行缩放  6.对精灵宽或高进行缩放  7.旋转精灵 8.设置精灵透明度  9.精灵的镜像反转  10.设 ...

  8. SQL中如何将一个表中的某一列的数据复制到另一个表中的某一列里

    表一: SPRD PRD_NO      SPC 001                NULL 002               NULL 003               NULL ...   ...

  9. DTD学习笔记

    1.  DTD基本介绍 xml文件分为两种类型,一个是在好形式,这是well-formed,还有一个合法有效,这是valid. XML文件遵循-called"好形式"各种语法规则要 ...

  10. 动态创建按钮的JS

    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN"> <HTML>  <HEA ...