String研究
=======================String===================================
String里的==和equals
Java String “equals”就是比较字符串的内容,由于以上程序中的所有字符串内容都是“test”,所以用equals比较它们都会相等。但是你是否知道Java中基类Obejct的equals方法跟“==”方法其实是一致的呢?只不过是String类继承Object类后,重载了equal的方法,使得其成为了比较字符串中的内容。
很好的理解了equals之后,现在让我们来研究一下“==”方法的扑朔迷离。
“==”是Java中的运算符,它比较的内容是两个对象的指针,也就是实际对象的地址(程序员无法重载)。
http://www.jb51.net/article/37899.htm
String里的+
String hello = "hello";
String hel = "hel";
String lo = "lo";
System.out.println(hello == "hel" + "lo");
System.out.println(hello == "hel" + lo);
第一个加法连接时,+号两边都是常量字符串,java就会将两者拼起来后到String Pool里找与之相等(用equals)的字符串,若存在则将其地址返回;不存在则在String Pool里新建一个常量对象,其值等于拼接后的字符串,并将其地址返回。
第二个加法连接时,+号两边有一个是变量,此时,java会在堆里新建一个对象,其值是两字符串拼接后的值,此时返回的地址是堆中新对象的地址。
http://unique5945.iteye.com/blog/177812
创建字符串的方式很多,归纳起来有三类:
其一,使用new关键字创建字符串,比如String s1 = new String("abc");
其二,直接指定。比如String s2 = "abc";
其三,使用串联生成新的字符串。比如String s3 = "ab" + "c";
Cliff:
其四,使用串联和变量生成新的字符串。比如String s1; String s3 = "ab" + s1;
String对象的创建
String对象的创建也很讲究,关键是要明白其原理。
原理1:当使用任何方式来创建一个字符串对象s时,Java运行时(运行中JVM)会拿着这个X在String池中找是否存在内容相同的字符串对象,如果不存在,则在池中创建一个字符串s,否则,不在池中添加。
原理2:Java中,只要使用new关键字来创建对象,则一定会(在堆区或栈区)创建一个新的对象。
原理3:使用直接指定或者使用纯字符串串联("+")来创建String对象,则仅仅会检查维护String池中的字符串,池中没有就在池中创建一个,有则罢了!但绝不会在堆栈区再去创建该String对象。Cliff:但是涉及到变量的时候,仍然会创建一个新的堆字符串。
原理4:使用包含变量的表达式或concat来创建String对象,则不仅会检查维护String池,而且还会在堆栈区创建一个String对象。
另外,String的intern()方法是一个本地方法,定义为public native String intern(); intern()方法的价值在于让开发者能将注意力集中到String池上。当调用 intern 方法时,如果池已经包含一个等于此 String 对象的字符串(该对象由 equals(Object) 方法确定),则返回池中的字符串。否则,将此 String 对象添加到池中,并且返回此 String 对象的引用。
参考:
http://zy19880423.iteye.com/blog/434118
* 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值。
虽然这个不是强制性的,但是如果不能保证相同的引用对象,没有相同的hashcode,会对系统留下很大隐患。
String类的equals方法
- 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;
- }
String 类的hashcode 方法
- 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方法来确保这个一致性
(Cliff:如果两个对象通过覆盖equals而相等,但不重写HashCode,那么会导致两个相同的数据有不同的HashCode值,从而存储两遍。)
String研究的更多相关文章
- Java复习3.变量.常量.String.
Java 中的变量常量数据类型 20131004 前言: 还是国庆节,无聊的很,就没事复习点Java的知识,其实C/C++基本上是现在大型企业面试的语言,但是多学习点Java是没有坏处的,而且,将来工 ...
- std::string的find问题研究
https://files-cdn.cnblogs.com/files/aquester/std之string的find问题研究.pdf 目录 目录 1 1. 前言 1 2. find字符串 1 3. ...
- Springboot 错误信息:Required String parameter 'loginname' is not present 引发的研究
@PostMapping("/reg/change")public CommonSdo change( @RequestParam(value = "oldPasswor ...
- JavaScript String 对象实例深入研究
本文主要介绍并分析JavaScript中String对象的具体用法,以及和String对象相关的方法,方便开发者在JavaScript开发中更好地处理字符串. 1. 介绍 String 对象,对字符串 ...
- C++标准库之string返回值研究
先说结论(不一定适用所有环境): 1) GCC默认开启了返回值优化(RVO),除非编译时指定“-fno-elide-constructors”: 2) 现代C++编译器一般都支持返回值优化: 3) s ...
- std::string的拷贝赋值研究
说明:以下涉及的std::string的源代码摘自4.8.2版本.结论:std::string的拷贝复制是基于引用计数的浅拷贝,因此它们指向相同的数据地址. // std::string类定义type ...
- java string字符拼接符"+"的研究
程序: public class Test { public static void main(String args[]) { String s1 = "abc"; String ...
- String和StringBuffer的一点研究
转载自:http://www.cnblogs.com/heshan664754022/archive/2013/03/15/2961463.html 首先请看下下面的这几个输出的结果,请仔细考虑,不要 ...
- 闲来无聊,研究一下Web服务器 的源程序
web服务器是如何工作的 1989年的夏天,蒂姆.博纳斯-李开发了世界上第一个web服务器和web客户机.这个浏览器程序是一个简单的电话号码查询软件.最初的web服务器程序就是一个利用浏览器和web服 ...
随机推荐
- 基于STC12C5A的MINI3216多功能点阵时钟
代码地址如下:http://www.demodashi.com/demo/12862.html 基于STC12C5A的MINI3216多功能点阵时钟 硬件详解 PCB 硬件原理图 主控模块 max72 ...
- iOS开发-XCode常用快捷键整理
前言:如果我们能够掌握并巧妙地使用快捷键,可以大大加快我们的工作效率,这个对经常使用快捷键的人们来说,应该很容易理解.因此我们需要做的是,针对于自己经常使用的快捷键去进行记忆.我不会推荐你们去把所有的 ...
- 【ASP.NET MVC系列】浅谈数据注解和验证
[ASP.NET MVC系列]浅谈数据注解和验证 [01]浅谈Google Chrome浏览器(理论篇) [02]浅谈Google Chrome浏览器(操作篇)(上) [03]浅谈Google C ...
- stm32时钟设置函数
这里涉及到一个很重要的寄存器,时钟配置寄存器:RCC_CFGR #if defined (STM32F10X_LD_VL) || (defined STM32F10X_MD_VL) || (defin ...
- CSS实现子级窗口高度随低级窗口高度变化及js控制左右容器高度一致
纯粹使用使用height:100%;或者height:auto;来定义内部容器自适应高度,都无法实现让内部容器高度随着外部父容器高度变化而变化,所以我们必需要使用position绝对定位属性来配合协助 ...
- Mac 上的传奇效率神器 Alfred 3
下载地址:https://www.alfredapp.com/ 第三方教程:https://www.jianshu.com/p/e9f3352c785f 一.内置快捷键介绍 1.默认快捷呼出热键是: ...
- 141. Linked List Cycle【easy】
141. Linked List Cycle[easy] Given a linked list, determine if it has a cycle in it. Follow up:Can y ...
- redhat5.8下oracle11g启动失败
# redhat5.8下oracle11g启动失败 ### 日志文件路径-----------------------------tail -f /u01/app/oracle/product/11. ...
- iOS 集成微信支付【转载】
目前项目里有微信支付的需求,调研过一段时间后,发现其实并没有想象中的那么困难.如果你只是想实现该功能,一个方法足以,但是若你想深入了解实现原理.就需要花费更多的功夫了.目前我只清楚微信支付需要做签名, ...
- 工业控制系统PLC、DCS、ESD
PLC:可编程逻辑控制系统.PLC是一种专为在工业环境应用而设计的数字运算电子系统. DCS:集散控制系统. ESD:紧急停车系统.