字符串面试知识点

一、字符串的创建和存储

常量池:
String s1 = new String(“abc”); //把“abc”放到常量池中,在编译时产生
String s2 = “abc”; //把“ab” + “c”转换为字符串常量“abc”放在常量区中
String s3 = “ab” + “c”; //在运行时把“abc”放在堆里

String s1 = new String(“abc”)可以看做两部分:1)创建新的对象即new String(“abc”);2)赋值:String s1 =;
第一部分new String(“abc”)会调用String类的构造函数(传入一个字符串常量),所以new String(“abc”)又可以等价于“abc”和new String()两个操作.
若在字符串常量中不存在”abc”,则会创建一个字符串常量”abc”,并将其存入到常量池中;若存在,则不创建,然后new String()会在堆中创建一个新的对象.
字符串存储

题目1:new String(“abc”)创建了几个对象?
答案:1个或者2个. => 1)当常量池中已有”abc”,那么只创建一个对象;2)若常量池中没有字符串”abc”,那么会创建两个对象.

题目2: String s = new String(“abc”)创建几个对象?
答案:2个或者3个. => String s为一个对象;1)当常量池中已有”abc”,那么只创建一个对象;2)若常量池中没有字符串”abc”,那么会创建两个对象.

二、比较String:“==” OR “equals” ?

对于基本类型的数据
“==”:用于比较两个变量的值是否相等. 即比较的是变量对应内存中所存储的数值是否相同.
复合数据类型(对象)
在没有覆写equals方法时,使用”==”比较和用equals比较的都是它们的在内存中的存放地址的首地址(即两个对象是否指向同一存储空间);
在类覆写了equals方法时,则按照覆写的内容进行比较.
比如String类覆写了equals方法,用于比较两个String对象的字符串内容是否相等(即堆中的内容是否相等).

equals和hashCode方法的渊源
当集合要添加新的对象时,先调用这个对象的hashCode方法,得到对应的hashcode值,实际上在HashMap的具体实现中会用一个table保存已经存进去的对象的hashcode值,如果table中没有该hashcode值,它就可以直接存进去,不用再进行任何比较了;如果存在该hashcode值,就调用它的equals方法与新元素进行比较,相同的话就不存了,不相同就散列其它的地址,所以这里存在一个冲突解决的问题,这样一来实际调用equals方法的次数就大大降低了,说通俗一点:Java中的hashCode方法就是根据一定的规则将与对象相关的信息(比如对象的存储地址,对象的字段等)映射成一个数值,这个数值称作为散列值.

如果x.equals(y)返回true,即两个对象根据equals方法比较是相等的,那么调用这两个对象中的任意一个对象的hashCode()方法都必须产生
同样的整数返回值;如果x.equals(y)返回false,即两个对象根据equals()方法比较是不相等的,那么x和y的hashCode()返回值有可能是相等的,也有可能是不相等的.

So:若hashCode()方法返回值不相等,一定能推出equals()方法的返回值也不相等,而hashCode()方法的返回值相等,equals方法的返回值则可能相等也有可能不相等.
hashCode()方法返回的是将对象在内存中的地址转换成一个int值.(这个hash地址不一定是真正的物理地址)