查看了公众号:java之间的整理的集和文章,文章地址
总结和搜索了一下网络知识,总结了一下:
1.String 的hashcode()方法
2.switch总结:
3.如何实现克隆
1.String 的hashcode()方法
String也是遵守equals的标准的,也就是 s.equals(s1)为true,则s.hashCode()==s1.hashCode()也为true。此处并不关注eqauls方法,而是讲解 hashCode()方法,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; }
为什么要选31作为乘数呢?
从网上的资料来看,一般有如下两个原因:
- 31是一个不大不小的质数,是作为 hashCode 乘子的优选质数之一。另外一些相近的质数,比如37、41、43等等,也都是不错的选择。那么为啥偏偏选中了31呢?请看第二个原因。
- 31可以被 JVM 优化,31 * i = (i << 5) - i。
链接:http://www.cnblogs.com/jinggod/p/8425182.html
2.switch总结:
- 底层的switch只能处理4个基本类型的值。其他三种类型需要通过其他方式间接处理,即转成基本类型来处理。
- 编译器对包装类的处理是通过 拆箱。
- 对枚举类型的处理,是通过枚举常量的序号及一个数组。
- 对字符串String的处理,是通过 String 的hash值。
3.常量池
常量 可分为 字面常量(也称为直接常量)和 符号常量。
字面常量: 是指在程序中无需预先定义就可使用的数字、字符、boolen值、字符串等。简单的说,就是确定值的本身。如 10,2L,2.3f,3.5,“hello”,‘a‘,true、false、null 等等。
符号常量: 是指在程序中用标识符预先定义的,其值在程序中不可改变的量。如 final int a = 5;
常量池(静态常量池,运行时常量池)
常量池引入的 目的 是为了避免频繁的创建和销毁对象而影响系统性能,其实现了对象的共享。这是一种 享元模式 的实现。
- 字符串常量池属于运行时常量池
- 常量池分为:静态常量池(class文件常量池),运行时常量池
享元模式:http://www.runoob.com/design-pattern/flyweight-pattern.html
3.如何实现克隆
浅克隆:
1. 被复制的类需要实现Clonenable接口(不实现的话在调用clone方法会抛出CloneNotSupportedException异常), 该接口为标记接口(不含任何方法)
2. 覆盖clone()方法,访问修饰符设为public。方法中调用super.clone()方法得到需要的复制对象。(native为本地方法)
深克隆
1.可以通过覆盖Object类的clone()方法实现,
2.也可以通过序列化(Serialization)等方式来实现。
使用序列化实现java的深拷贝
1 // deepClone()的方法实现 2 Person person = new Person("sunjs",100); 3 Person person1 =(Person) person.deepClone(); 4 5 //序列化方式 6 public class CloneUtils { 7 // 拷贝一个对象 8 @SuppressWarnings("unchecked") 9 public static <T extends Serializable> T clone(T obj) { 10 // 拷贝产生的对象 11 T clonedObj = null; 12 try { 13 // 读取对象字节数据 14 ByteArrayOutputStream baos = new ByteArrayOutputStream(); 15 ObjectOutputStream oos = new ObjectOutputStream(baos); 16 oos.writeObject(obj); 17 oos.close(); 18 // 分配内存空间,写入原始对象,生成新对象 19 ByteArrayInputStream bais = new ByteArrayInputStream( 20 baos.toByteArray()); 21 ObjectInputStream ois = new ObjectInputStream(bais); 22 // 返回新对象,并做类型转换 23 clonedObj = (T) ois.readObject(); 24 ois.close(); 25 } catch (Exception e) { 26 e.printStackTrace(); 27 } 28 return clonedObj; 29 } 30 }
深拷贝参考链接:https://time.geekbang.org/column/intro/82
原文地址:https://www.cnblogs.com/liguo-wang/p/10463863.html