关于String类的一些要点
-
string对象用于保存字符串,也就是一组字符序列,
-
"jack"字符串常量,双引号括起来的字符序列
3,字符串使用的是Unicode字符编码,一个字符(不分中英文)占两个字节
4,String类有很多构造器,构造器的重载,
5,String类实现了接口Serializable(String 可以串行化:可以在网络传输) 接口Comparable(String对象可以比较大小)
6,String类被final关键字修饰,所以该类不能被继承,
7,String类用于存放字符串类容的属性private final char value[];
8,一定要注意:value是一个final类型,不可修改,即它不能重新指向新的地址,但是value[]中的单个字符内容可以改变,
关于StringBuffer的要点
1,StringBuffer的直接父类是AbstractStringBuffer。
2,StringBuffer实现了Serializable,即对象可以串行化。
3,在直接父类中,有属性 char[] value 没有被final修饰。该value数组用于存放字符串类容,因为是数组所以创建在堆中,
4,StringBuffer类被final修饰,所以该类不能被继承。
5,因为StringBuffer类存放字符串,是在char[] value中,没有被final修饰,所以在变化时(增加\删除)不用每次都跟换地址(即不是每次创建对象),所以效率高于String。
String对比StringBuffer
1,String保存的时字符串常量,里面的值不能更改,每次String类的跟新,实际上是指向的地址的更新(在常量池创建新的对象)。效率较低private final char[] value; //被final修饰的变量不能更改,便是常量
2,StringBuffer保存的是字符串变量,里面的值可以更改,每次StringBuffer的更新都是跟新它的内容,而不用每次更新地址(不用创建新的对象),效率较高,char[] value->没有被修饰,是变量,放在堆中
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-GFWZXCYM-1619913403335)(C:\Users\47669\AppData\Roaming\Typora\typora-user-images\image-20210428142147058.png)]
三者对比
StringBuilder与StringBuffer非常相似,均代表可变字符序列,而且方法也一样、
-
String为不可变字符序列,它在常量池中即复用率高
-
StringBuffer可变字符序列,效率较高(增删)线程安全
-
StringBuilder可变字符序列,效率最高,但线程不安全
collection集合类
ArrayList的一些要点
- 不使用指定大小的构造器,则初始大小为0,未分配空间,第一次添加的时候分配10的空间,超过后扩大为原来的1.5倍,也可以使用指定大小的构造器,每次添加都会判断是否需要扩容
set集合
- 无序:添加顺序与遍历顺序不一致,
- 无下标,没有下标所以不能用froi
- 不可重复:重复添加一个对象,会添加失败,返回false
HashSet集合源码步骤
1,HashSet底层是HashMap。把添加的元素放入key中,value存放固定值:PRESENT
2,添加一个元素时,先得到他的Hash值—》然后转换为—》索引值(由索引值确定放入哪个链表(对该链表中的节点进行equals方法比较,不同则添加在尾节点),当该链表已经达到8,而数组大小没有达到64时,就对数组进行扩容,如果达到64时,则对该链表进行树化,链表转换为红黑树)
3,找到存储数据表table,看这个索引位置是否已经存放有别的元素
4,如果没有,则直接加入,
5,如果有,则调用equals进行比较,如果相同,就放弃添加,如果不相同,则添加到最后。
6, 在JDK8中,如果一条数据表的元素个数超过TREEIFY_THRESHOLD(默认是8),并且table的大小>=MIN_TR…(默认64),就会树化为(红黑树)--------如果链表到8,但数组未到64,则会对数组进行扩容。
linkederHashSet实在HashSet集合的基础上实现了全部节点的双向关联,也就是汇聚成了一个大的双向链表
Map集合接口的特点
- Map与Collection并列存在,用于保存具有特定映射关系的数据:Key–Value的双列元素
- Map中的Key–Value可以存放任意的引用类型的数据,其中的key是不允许重复的,根据hashcode与equals来判断是否重复,Map发现重复就覆盖前者,set重复会添加失败。(value是可以重复的)
老汉解读:
- 1, `K-V 最后是 HashMap$Node node = newNode(hash, key,value,null)
- 2, K-v为了方便程序员遍历,还会 创建EntrySet集合,该集合存放的元素的类型Entry,而一个Entry对象就有一个K,V EntrySet<Entry<K,V>> 即: transient Set<Map.Entry<K,V>> entrySet;
- 3,entrySet中,定义的类型是Map.entry,但实际上还是存放的是 HashMap$Node,因为该接口被实现了。
HashMap与HashSet的扩容机制完全一样,因为HashSet底层是用HashMap实现的
Map接口实现类–HashTable
1,存放的元素是键值对:
2,hashtable的键值对不能为空,否则会抛出NullPointerException空指针异常。
3,hashtable使用的方法基本上和HashMap一样
4,hashTable是线程安全的,hashmap是线程不安全的。
总结:开发中如何选择集合实现类(切记)
选择什么集合实现类主要取决于业务操作特点,然后根据集合的特性进行选择,分析如下
1,先判定存储的类型(一组对象【单列】或一组键值对【双列】
2,一组对象【单列】:Collection接口
-
允许重复:List
- 增删多:LinkedList【底层维护了一个双向列表】
- 改查多:ArrayList【底层维护了Object类型可变数组】
-
不允许重复:set
- 无序:HashSet【底层是HashMap,维护了一个哈希表,即(数组+链表+红黑树)】
- 排序:TreeSet【实现匿名内部类,自定义排序规则】
- 插入和取出顺序一致:LinkedHashSet,维护数组叫双向链表。
3,一组键值对【双列】:Map
- 建无序:HashMap【底层是:哈希表,JDK8数组+链表+红黑树】
- 建排序:TreeMap
- 键插入和取出顺序一致:LinkedHashMap
- 读取文件:properties