Java知识点学习(第6天)
Posted 风斩晚霞
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java知识点学习(第6天)相关的知识,希望对你有一定的参考价值。
说一下HashMap的Put方法
1.7和1.8版本的具体实现方式是不同的,但它们的大体流程是相似的:
- 根据key通过哈希算法与运算得出数组下标。
- 如果数组下标的位置元素为空,则将key和value封装成为Entry对象(1.7为Entry对象,1.8为Node对象)并放入该位置。
- 如果数组下标元素不为空,则要分情况进行讨论:
如果是1.7版本,则先判断是否需要扩容,如果需要扩容就进行扩容,如果不需要扩容就直接生成Entry对象,并使用头插法添加到当前位置的列表中。
如果是1.8版本,则先判断当前位置上的Node类型,看是红黑树Node,还是链表Node
- 如果是红黑树Node,则将key和value封装成为一个红黑树节点并添加到红黑树中,这个过程会判断红黑树中是否存在当前的key,如果存在则更新value。
- 如果此位置上的Node节点为链表节点,则将key和value封装为一个链表Node并通过尾插法插入链表的最后位置,因为是尾插法,需要遍历整个链表,在遍历的过程中会判断是否存在当前的key,如果存在则更新value值,在遍历完链表后,将新的链表Node插入链表中,插入链表后,会看当前链表的节点个数,如果大于等于8,那么会将链表变为红黑树。
- 将key和value封装为Node插入链表和红黑树后,再判断是否需要进行扩容,如果需要扩容就扩容,不需要就直接结束PUT方法。
深拷贝和浅拷贝
浅拷贝是指,只拷贝基本的数据类型的值,以及实例对象的引用地址,内部属性类指向的是同一个对象。简单来说,就是原数据发生变更,新数据也会发生变更。
深拷贝是值,既会拷贝基本数据类型的值,也会针对实例对象的引用地址所指向的对象进行复制,内部的属性指向的不是同一个对象。简单说,就是原数据发生变更,数据仍保持不变。
HashMap的扩容机制原理
1.7版本:
- 生成新的数组
- 遍历老数组中的每个位置上的链表上的每个元素
- 取每个元素的key,并基于新的数组长度计算出在新数组中的下标
- 将元素添加到新数组中
- 所有元素转移完后,将新数组赋值给HashMap对象的table属性中
1.8版本:
- 生成新的数组
- 遍历老数组中的每个位置上的列表或红黑树
- 如果是链表,则直接将链表中的每个元素重新计算下标,并添加到新数组中
- 如果是红黑树,则先遍历红黑树,先计算出红黑树每个元素对应在新数组的下标位置,统计每个下标的元素个数,如果元素个数超过了8个,则生成一个新的红黑树,并将根节点添加到新数组的对应位置;如果元素的个数没有超过8,则生成一个链表,并将链表的头节点添加到新数组的对应位置
- 所有元素转移完后,将新数组赋值给HashMap对象的table属性中
CopyOnWriteArrayList的底层原理是怎样的
因为ArrayList是线程不安全的,所以引入线程安全的CopyOnWriteArrayList。
- 首先CopyOnWriteArrayList内部是通过数组进行实现的,在添加元素时,会复制一个新的数组,写操作在新数组中,读操作在原数组中。
- 写操作会加锁,防止出现并发写入丢失数据,写操作结束后,会将原数组指向新数组。
- CopyOnWriteArrayList允许在写操作时读取数据,大大提高读的性能,因此适合读多写少的应用场景,但是CopyOnWriteArrayList会比较占内存,同时可能读到的数据不是最新的数据,所以不适合实时性要求很高的场景。
第262天学习打卡(知识点回顾 Java集合框架中的接口)
知识点回顾
java集合框架中的接口
集合有两个基本接口:Collection和Map。可以用以下方法在集合中插入元素: boolean add(E element), 不过由于映射包含键/值对,所以要用put方法来插入:V put(K key, V value) 要从集合读取元素,可以用迭代器访问元素。但是,从映射中读取值则要使用get方法:V get(K key)
Collection: List 、 Set(sortedSet NagigableSet) 、 Queue(Deque)
Map:SortedMap (NavigableMap)
List是一个有序集合。元素会增加到容器中的特定位置。可以采用两种方式访问元素:使用迭代器访问,或者使用一个整数索引来访问。后一种方法称为随机访问,因为这样可以按任意顺序访问元素,与之不同,使用迭代器访问时,必须顺序访问元素。List接口定义了多个用于随机访问的方法:
void add(int index, E element)
void remove(int index)
E get(int index)
E get(int index, E element)
ListIterator接口是Iterator的一个子接口。它定义了一个方法用于在迭代器位置前面增加一个元素:
void add(E element)
由数组支持的有序集合可以快速的随机访问,因为适合用List方法并提供一个整数索引来访问。与之不同,链表尽管是有序的,但是随机访问很慢,所以最好使用迭代器来遍历。
Set 接口等同于Collection接口,不过其方法的行为有更严谨的定义。集(set)的add方法不允许增加重复的元素。要适当的定义集的equals方法,只要两个集包含同样的元素就认为是相等的,而不要求这些元素有同样的顺序。hashCode方法的定义要保证相同元素的两个集会得到相同的散列码。
Java库中具体集合
ArrayList:一种可以动态增长和缩减的索引序列
LinkedList:一种可以在任何位置进行高效地插入和删除操作的有序序列
ArrayDeque:一种用循环数组实现的双端队列
HashSet:一种没有重复元素的无序集合
TreeSet: 一种有序集
EnumSet: 一种包含枚举类型值的集
LinkedHashSet: 一种可以记住元素插入次序的集
PriorityQueue: 一种允许高效删除最小元素的集合
HashMap: 一种键值关联的数据结构
TreeMap:一种键值有序排列的映射表
EnumMap: 一种监视属于枚举类型的映射表
LinkedHashMap: 一种可以记住键值项添加次序的映射表
WeakHashMap:一种其值无用武之地后可被垃圾回收的映射表
IdentityHashMap: 一种用==而不是用equals比较键值的映射表
-------- 摘至 《Java 核心技术 卷 I》 仅做知识点回顾
以上是关于Java知识点学习(第6天)的主要内容,如果未能解决你的问题,请参考以下文章
第288天学习打卡(知识点回顾 java创建对象的方式 Hashtable和ConcurrentHashMap的区别 )
第288天学习打卡(知识点回顾 java创建对象的方式 Hashtable和ConcurrentHashMap的区别 )