Java基础
集合类
- Collection
- List
- ArrayList
- 扩容1.5倍
- 线程不安全
- 例:A线程向list中添加1-10,B线程向list中添加11-20,最后list中元素是混乱的
- LinkList
- 双向链表节点对应的类Node的实例,Node中包含成员变量
- prev:该节点的上一个节点
- next:该节点的下一个节点
- item:该节点所包含的值,分两半查找,先判断index是在链表的哪一半,然后再去对应区域查找
- ArrayList
- Set
- HashSet:元素是无序的
- TreeSet:树形结构实现,元素是有序的
- Map
- HashMap
- 允许键和值是null
- 线程不安全
- 在put的时候,插入的元素超过了容量(由负载因子决定)的范围就会触发扩容操作,就是rehash,这个会重新将原数组的内容重新hash到新的扩容数组中
- A线程和B线程同时对同一个数组位置调用addEntry,两个线程会同时得到现在的头结点,然后A写入新的头结点之后,B也写入新的头结点,那B的写入操作就会覆盖A的写入操作造成A的写入操作丢失
- 当多个线程同时调用resize操作,各自生成新的数组并rehash后赋给该map底层的数组table,结果最终只有最后一个线程生成的新数组被赋给table变量,其他线程的均会丢失。而且当某些线程已经完成赋值而其他线程刚开始的时候,就会用已经被赋值的table作为原始数组,这样也会有问题
- 底层采用一个Node[]数组来保存所有的key-value对
- 存储一个Node对象时,会根据key的hash算法来决定其在数组中的存储位置,再根据key值决定其在该数组位置上的链表中的存储位置
- 初始长度为16,扩容必须是2的幂
- index = HashCode(Key) & (Length - 1)
- 16-1=15 的二进制就是1111,把1111看成四个通道,表示跟1111 做&运算后分布是均匀的,假如1010,这样就相当于有两个通道是关闭的,所以计算出来的索引重复的几率比较大
- hash冲突
- 键值的hashcode相同,它们的存储位置就相同。如果key不同,那么就会产生hash冲突
- HashMap的单个bucket里存储的不是一个 Entry,而是一个 Entry 链
- Hashtable
- 不允许键或者值是null
- remove,put,get方法都有synchronized修饰
- 底层使用数组实现,数组中每一项是个单链表,即数组和链表的结合体
- 底层采用一个Entry[]数组来保存所有的key-value对
- 存储一个Entry对象时,会根据key的hash算法来决定其在数组中的存储位置,在根据equals方法决定其在该数组位置上的链表中的存储位置
- 取出一个Entry时,也会根据key的hash算法找到其在数组中的存储位置,再根据equals方法从该位置上的链表中取出该Entry
- ConcurrentHashMap
- 将Map分段,每个段进行加锁
cookie、session
- cookie
- 客户端可以禁用cookie
- cookie只能存储String类型的对象
- session
- 客户端无法禁用服务端的session
- session能够存储任意的Java对象
final、finally、finalize
- final
- 修饰属性,属性不可变
- 修饰方法,方法不可覆盖
- 修饰类,类不可继承
- finally
- 异常处理语句结构的一部分,表示总是执行
- finalize
- Object类的方法,在垃圾收集器执行的时候会调用被回收对象的此方法
基本数据类型
- byte:Byte
- int:Integer
- char:Character
- long:Long
- float:Float
- double:Double
- boolean:Boolean
- short:Short
equals、==
- ==
- 用于基本数据类型,比较的是值发放
- 引用数据类型:比较的是在堆内存地址是否相等
- 凡是与new的对象比较,必须是同一对象,特殊情况是基本数据类型和String的常量池,String常量池里面的值唯一,因此值相同,地址相同,==成立
- 基本数据类型和其包装类比较,会自动拆装箱,值相同==就成立
- equals
- 没有覆写equals()方法时,比较的是值,与==一致
- 覆盖 equals() 方法来比较两个对象的内容是否相等
- hashCode
- equals()相等,hashCode一定相等
- equals()不相等,hashCode不一定不相等,可能存在地址冲突
- hashCode相等,对象不一定equals,因为可能存在地址冲突
- String s=“abc”
- 先在常量池中查找有没有一个值为"abcd"的对象
- 有,把它赋给当前引用。即原来那个引用和现在这个引用指点向了同一对象
- 没有,则在常量池中新创建一个
- 只要值相等,任何多个引用都指向常量池中同一对象
- String str=new String (“hello”)
- 不管堆空间是否已经有"hello"这个对象,都新建一个对象保存"hello"
- 如果常量池中已经存在"hello",那么就不会额外在常量池中生成引用
- intern()
- jdk1.6:检查字符串池里是否存在"hello"这么一个字符串,如果存在,就返回池里的字符串;如果不存在,该方法会把"hello"添加到字符串池中,然后再返回它的引用
- jdk1.7:https://blog.csdn.net/seu_calvin/article/details/52291082
Object下方法
- hashCode()
- equals()
- toString()
- notify()
- notifyAll()
- wait()
- finalize()