面试篇(JavaSE):常用类部分
String str="i" 与 String str=new String("i")
两者不一样,因为内存的分配方式不一样。
String str="i"的方式,java 虚拟机会将其分配到常量池中;
而 String str=new String("i") 则会被分到堆内存中。
String s = new String("xyz")
创建了几个String Object? 二者之间有什么区别?
在常量池中查找是否有“xyz”对象,有则返回对应的引用实例,没有则创建对应的实例对象;
在堆中 new 一个 String("xyz") 对象; (将常量池中的对象复制一份放到堆内存中,并且把堆内存 中的这个对象的引用交给s持有) ;
将对象地址赋值给s,创建一个引用; 所以,常量池中没有“xyz”字面量则创建两个对象,否则创建一个对象;
创建了多少个对象?
String s1 = "a"; // 定义一个字符串常量
String s2 = s1 + "b"; // 这时引用的s1是一个变量,所以s2也是一个变量
String s3 = "a" + "b"; // 两个字符串常量相加,得到的s3依旧是一个常量
System.out.println(s2 == "ab"); // false
System.out.println(s3 == "ab"); // true
第一条语句打印的结果为false,第二条语句打印的结果为true,这说明javac编译可以对字符串常量直接相 加的表达式进行优化,不必要等到运行期去进行加法运算处理,而是在编译时去掉其中的加号,直接将其编译 成一个这些常量相连的结果。
String s = "a" + "b" + "c" + "d";
代码被编译器在编译时优化后,相当于直接定义了一个”abcd”的字符串,所以,上面的代码应该只 创建了一个String对象。
System.out.println(s == "abcd");
最终打印的结果应该为true。
Java 中操作字符串
操作字符串的类有:String、StringBuffer、StringBuilder。
String 和 StringBuffer、StringBuilder 的区别在于
String 声明的是不可变的对象,每次操作都 会生成新的 String 对象,然后将引用指向新的 String 对象。
而 StringBuffer、StringBuilder 可以在原有对象的基础上进行操作,所以在经常改变字符串内容的情况下最好不要使用 String。
StringBuffer 和 StringBuilder 最大的区别在于
StringBuffer 是线程安全的,而 StringBuilder 是非线程安全的
但 StringBuilder 的性能却高于 StringBuffer
所以在单线程环 境下推荐使用 StringBuilder,多线程环境下推荐使用 StringBuffer。
总结
操作少量的数据:String
单线程操作字符串缓冲区下操作大量数据:StringBuilder
多线程操作字符串缓冲区下操作大量数据:StringBuffer
BigDecimal 类
一般使用 java.math.BigDecimal 类来处理需要高精度的计算,如金钱之类的。
原因
浮点数(double,flot)因为精度问题, 容易出现不精确的计算结果
浮点数范围比较小
BigDecimal范围大, 并且比他们精确
hashCode 与 equals
hashCode()介绍
hashCode() 的作用是获取哈希码,也称为散列码;它实际上是返回一个int整数。这个哈希码的作用 是确定该对象在哈希表中的索引位置。hashCode() 属于Object类的方法,这就意味着Java中的任何类都 包含hashCode() 函数。
散列表存储的是键值对(key-value),它的特点是:能根据“键”快速的检索出对应的“值”。这其中就利 用到了散列码。(可以快速找到所需要的对象)。
为什么要有 hashCode
以“HashSet 如何检查重复”为例子来说明为什么要有 hashCode:
当把对象加入 HashSet 时,HashSet 会先计算对象的 hashcode 值来判断对象加入的位置,同时也会与其他已经加入的对象的 hashcode 值作比较,如果没有相符的hashcode,HashSet会假设对象没 有重复出现。但是如果发现有相同 hashcode 值的对象,这时会调用 equals()方法来检查 hashcode 相等的对象是否真的相同。如果两者相同,HashSet 就不会让其加入操作成功。如果不同的话,就会重新散列到其他位置。这样就大大减少了 equals 的次数,相应就的大大提高了执行速度。
hashCode()与equals()的相关规定
如果两个对象相等,则hashCode一定也是相同的
两个对象相等,对两个对象分别调用equals及hashCode方法都返回true
两个对象有相同的hashCode值,它们也不一定是相等的
因此,equals 方法被重写过,则 hashCode 方法也必须被重写
hashCode() 的默认行为是对堆上的对象产生独特值。如果没有重写 hashCode(),则该 class 的两个对象无论如何都不会相等(即使这两个对象指向相同的数据)