从String到==和hashcode
public static void main(String[] args) {
String s1 = "ni";
String s2 = "hao";
String s3 = "nihao";
String s4 = "ni" + "hao";
String s5 = s1 + s2;
System.out.println(s3 == s4);
System.out.println(s3 == s5);
System.out.println(s3.equals(s5));
System.out.println(s3.hashCode() == s5.hashCode());
}
执行结果
true
false
true
true
第一个输出结果大伙应该都知道,String在常量池里找到"nihao"就直接返回地址引用
第二个是因为等号后面有变量(假设是String s5 = s1 + "hao"结果也是一样),他都必须new一个新的String对象出来,就不回去常量池里找了
第三个大伙应该也知道String的equals方法被重写了,比较的是值一不一样而不是地址值
第四个就是典型地验证了 == 不相等的哈希值可能相等,估摸着就是算着俩对象一样哈希值一样拉链法给s5扔s3那颗红黑树里了(更可能是链表,就这么小的世界不会那么巧8 ^ ^_ )
根据第四个延申会不会两个对象长一样哈希值就一样呢,立刻实验
public class WhatEver implements Cloneable{
public static void main(String[] args) {
WhatEver o1 = new WhatEver();
WhatEver o2 = null;
try {
o2 = (WhatEver) o1.clone();
} catch (CloneNotSupportedException e) {
e.printStackTrace();
}
System.out.println(o1.hashCode() == o2.hashCode());
}
}
执行结果
false
clone出来基本保证俩对象一样,结果却是false,俺也不知道咋回事了,懂的评论一下,去研究hashcode了
看了一下深入理解JVM,发现一个更有趣的String是否相等问题
String str1 = new StringBuilder("Hello").append("World").toString();
System.out.println(str1 == str1.intern());
String str2 = new StringBuilder("ja").append("va").toString();
System.out.println(str2 == str2.intern());
在JDK6中结果为false false ,JDK7中结果为 true false
JDK6中字符常量池在永久代,StringBuilder创建的"HelloWorld"实例在堆中,并复制一份扔到字符常量池中,两个引用指向不同地方所以不等;JDK7中字符常量池移回堆中,用StringBuilder创建'HelloWorld"没有了复制的步骤,常量池里扔的是StringBuilder创建对象的引用,指向的是同一个,为true;第二个为false是因为jvm初始化的时候就创建过"java"这个字符串到常量池中了,所以和StringBuilder新创建对象不一样,啥时候创建的可以看一下R大的知乎回答。
一言以蔽之,JDK7之后字符串常量池移回堆了,StringBuilder等创建新字符串对象时,如果这个字符串在常量池没有就往常量池扔这个新对象的引用,而不是JDK6中再复制一份字符串到常量池中
从String到==和hashcode的更多相关文章
- 关于Java中String类的hashCode方法
首先来看一下String中hashCode方法的实现源码 public int hashCode() { int h = hash; if (h == 0 && value.lengt ...
- 关于String重写的hashcode的代码分析
public int hashCode() { int h = hash; if (h == 0 && value.length > 0) { char val[] = valu ...
- 浅谈 String 的 hashCode() 方法
Java 中 hash 值的含义 hash 值主要是用来在散列存储结构中确定对象的存储地址的,提高对象的查询效率,如HashMap.HashTable等: 如果两个对象相同,那么这两个对象的 hash ...
- String源码中hashCode算法
针对java中String源码hashcode算法源码分析 /** The value is used for character storage. */ private final char val ...
- Java String引起的常量池、String类型传参、“==”、“equals”、“hashCode”问题 细节分析
在学习javase的过程中,总是会遇到关于String的各种细节问题,而这些问题往往会出现在Java攻城狮面试中,今天想写一篇随笔,简单记录下我的一些想法.话不多说,直接进入正题. 1.String常 ...
- 深度解析对象的hashcode和equals的差异,以及String的内存分配方式
Q:Java对象的hashcode是怎么得到的 A:Java对象的hashcode是native方法,不是通过Java实现的.hashcode的值是根据对象的内存地址得到的一串数字. Q:如果两个对象 ...
- 计算机程序的思维逻辑 (29) - 剖析String
上节介绍了单个字符的封装类Character,本节介绍字符串类.字符串操作大概是计算机程序中最常见的操作了,Java中表示字符串的类是String,本节就来详细介绍String. 字符串的基本使用是比 ...
- Java中的equals和hashCode方法
本文转载自:Java中的equals和hashCode方法详解 Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要 ...
- HashCode
如果一个类的对象要用做hashMap的key,那么一定要注意覆盖该类的equals和hashCode方法. equals()是基类Object的方法,用于判断对象是否有相同地址及是否为同一对象 pub ...
随机推荐
- Helvetic Coding Contest 2019 差A3 C3 D2 X1 X2
Helvetic Coding Contest 2019 A2 题意:给一个长度为 n 的01序列 y.认为 k 合法当且仅当存在一个长度为 n 的01序列 x,使得 x 异或 x 循环右移 k 位的 ...
- 解决一个通过 WebReference 调用 WCF 时自定义 DataContract 类参数提交的问题
先看一下VS2013自动创建默认的IService1.vb,注意自定义的数据契约 CompositeType ' 注意: 使用上下文菜单上的“重命名”命令可以同时更改代码和配置文件中的接口名“ISer ...
- Fiddler发送post请求 出现503
- windows 不能在本地计算机启动apache2。有关更多信息,查阅系统事件日志。如果这是非Microsoft服务,请与服务厂商联系,并参考特定服务错误代码1
今天使用apache的时候又无法启动了,之前也遇到过,这次重点说这一次的情况,其他情况可以查看博主apache相关的其他博文:网上关于apache服务端的设置的很多,但是都不适合我的情况: 一般使用a ...
- JVM常见问题分析
JVM常见问题分析 启动,并且去查看日志 ./startup.sh && tail -f ../logs/catalina.out 常见有有以下几个问题: 1.java.lang.Ou ...
- mysql--sql_mode报错整理
1.在5.7版本以上mysql中使用group by语句进行分组时, 如果select的字段 , 不是完全对应的group by后面的字段 , 有其他字段 , 那么就会报这个错误 ERROR 1055 ...
- laravel-事件
1.注册事件以及监听器 首先我们需要在 app/Providers/目录下的EventServiceProvider.php中注册事件监听器映射关系,如下: /** * The event liste ...
- 吴裕雄--天生自然KITTEN编程:移动与旋转
- Maven和Ant简介以及两者的区别
Maven 一.Maven简介 Maven是基于项目对象模型(POM),可以通过一小段描述信息来管理项目的构建,报告和文档的软件项目管理工具. 目前,绝大多数开发人员都把 Ant 当作 Java 编程 ...
- console.log添加样式及图片
console.log在控制台打出css样式的文字及图片 谷歌开发者中心上面关于谷歌浏览器控制台console.log()的文档 Format Specifier %s Formats the val ...