类 Object
类 Object 是类层次结构的根类。
每个类都使用 Object 作为超类。
所有对象(包括数组)都实现这个类的方法。
Object 是所有类的父类.
LinkedList集合
特点:
1底层是一个链表结构:查询快增删慢
2里面包含啦大量的操作首尾元素的方法
使用了LinkedList方法不能使用多态
Set集合体系 哈希表 HashSet哈希值
jdk1.8版本之前:哈希表 =数组+链表;
jdk1.8版本之后:哈希表 = 数组+红黑树(提高查询的速度)
哈希表的特点:速度快
数组结构:把元素进行了分组,(相同哈希值元素是一组)
链表/红黑树结构吧相同哈希值的元素链接到一起
什么是哈希值
哈希值是一个十进制的整数,由系统随机给出(就是对象是的地址值,是模拟出来得到的地址,不是数据实际存储的物理地址)
在Object类有一个方法,可以获取对象的哈希值
特点:
1不允许存储重复的元素
2没有索引,没有带索引的方法,也不能使用普通的for循环遍历
3是一个无序的集合 ,储存元素和取出元素的顺序有可能不一致
4底层是一个和哈希表结构(查询速度非常快)
单向链表结构
数据结构_链表:
链表:链表有多个节点()组成
特点:
查询慢:链表中地址不是连续的,每次查询元素,都是从头开始查询
增删快:链表结构,增加/删除一个元素,对链表结构没有影响,所以增删快.
链表中的每一个元素也称为一个节点
一个节点包含了一个数据源()储存数组,
两个指针域()储存地址
单项链表(无序的):链表中只有一条链子,不能保证元素的顺序,(存储元素和取出元素的顺序有可能不一致)
双向链表(有序的):链表中有两条链子,有一条链子专门记录元素的顺序,是一个有序的集合.
队列
数据结构_队列:先进先出
队列的特点:
先进先出(FIFO,First, In First Out)
入口出口在两端
队列的适用场景:
秒杀.抢购
在线售票
处理高并发场景
红黑树
①数据结构_树
约束:
1节点可以是红色或者黑色的
2根节点是黑色的
3叶子结点(空节点)是黑色的
4每个红色的节点的子节点都是黑色的
5任何一个节点到其每一个叶子节点
的所有历经上黑色节点数相同
②红黑树:是一种 平衡 二叉 查找 树
③平衡:左子节点和柚子节点数量相等
④特点:趋近于平衡树,查询速度非常快,
查询叶子节点最大次数和最小次数不能超过二倍
⑤二叉树:分支不能超过两个
⑥平衡树:左孩子和右孩子相等
⑦不平衡树:左孩子和右孩子不相等
⑧添加元素:
先和节点值进行比较
如果新添加的元素比当前节点元素值小,
则放在当前节点的左边
如果新添加的元素比当前节点元素值大,
则放在当前节点的右
⑨树的遍历(查找树)
往左右
返回当前节点的值
往右走
返回上一层节点
(按照规则依次返回值)
值是从小到大的(有序的查找树)
⑩节点:
2-节点:节点最多只有两个子节点
3-节点:节点最多只有三个子节点
数组
数据结构_数组:
查询快:数组的地址是连续的,我们通过数组的首地址可以找到数组,通过数组的索引可以快速查找某一个元素
增删慢:数组的长度是固定的,我们想要增加/删除一个元素,必须创建一个新数组,把原数组的数据复制过来
要把数组中索引是3的元素删除
必须创建一个新的数组,长度是原数组的长度-1
把原数组的其他元素复制到新数组中
在新数组的地址值赋值给变量arr
原数组会在内存中销毁(垃圾回收)
在对内存中,频繁的创建数组,复制数组中的元素,销毁数组,效率低下
数组适用的场景:
查询多,增删少的数据储存场景
比如国内的城市,班级内的学生
栈
数据结构_栈:先进后出
入栈(压栈):将元素入栈
出栈(弹栈):从栈中取出元素
main方法先入栈(压栈)main里面的方法运行完了main才能出栈
出入口同一侧
Hashtable集合
Hashtable<K ,V>集合imaplements Map<K,V>
Hashtable底层是一个哈希表
Hashtable是一个单线程集合(速度慢)(安全)
Hashtable不能存储(null值,null键)
HashMap可以储存(null值,null键)
Hashtable的子类Properties依旧活跃在历史的舞台
Properties集合是唯一一盒与IO流相结合的集合
Map集合
java.util.Map接口: 双列集合的顶层
// 成员方法
V?put(K?key,?V?value): 添加/修改 键值对.
如果键存在, 则用新值替换已有值, 返回被替换的值; 如果键不存在, 则添加键值对, 返回null
V?remove(Object?key): 根据键删除键值对, 返回被删除元素的值
如果键不存在, 返回null
V?get(Object?key): 根据键获取值.
如果键不存在, 则返回null
boolean containsKey(Object key): 判断是否包含指定的键
boolean containsKey(Object key): 判断是否包含指定的键
Set<K>?keySet(): 获取Map集合中所有的键, 存储到Set集合中
Set<Map.Entry<K,V>>?entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)
// JDK 9对于集合初始化的优化
java.util.List
// 静态方法
static List<E> of(E... e): 返回包含指定元素的 不可变List 集合
java.util.Set
// 静态方法
static Set<E> of(E... e): 返回包含指定元素的 不可变Set 集合
java.util.Map
// 静态方法
static Map<K, V> of(K k1, V v1): 返回包含指定键值对的 不可变Map 集合
debug调试模式
断点:
breakpoint, 在debug模式下, 程序运行到断点会暂停住, 便于我们在程序运行过程中查看
Debug调试程序:
可以让代码逐行执行,查看代码执行的过程,调试程序中出现的bug
使用方式:
在行号的右边,鼠标左键单击,添加断点(每个方法的第一行,哪里有bug添加到哪里)
右键,选择Debug执行程序
程序就会停留在添加的第一个断点处
执行程序:
f8:逐行执行程序
f7:进入到方法中
shift+f8:跳出方法
f9:跳到下一个断点,如果没有下一个断点,那么就结束程序
ctrl+f2:退出debug模式,停止程序
Console:切换到控制台
线程间的通信
概念:多个线程在处理同一个资源,但是处理的动作(线程的任务)却不相同
为什么要处理线程间通信:
多个线程并发执行时, 在默认情况下CPU是随机切换线程的,当我们需要多个线程来共同完成一件任务,并且我们希望他们有规律的执行, 那么多线程之间需要一些协调通信,以此来帮我们达到多线程共同操作一份数据。
如何保证线程间通信有效利用资源:
多个线程在处理同一个资源,并且任务不同时,需要线程通信来帮助解决线程之间对同一个变量的使用或操作。 就是多个线程在操作同一份数据时, 避免对同一共享变量的争夺。也就是我们需要通过一定的手段使各个线程能有效的利用资源。而这种手段即—— 等待唤醒机制。
线程之间需要合作
等待唤醒机制
什么是等待唤醒机制
这是多个线程间的一种协作机制。谈到线程我们经常想到的是线程间的竞争(race),比如去争夺锁,但这并不是故事的全部,线程间也会有协作机制。就好比在公司里你和你的同事们,你们可能存在在晋升时的竞争,但更多时候你们更多是一起合作以完成某些任务。
就是在一个线程进行了规定操作后,就进入等待状态(wait()), 等待其他线程执行完他们的指定代码过后 再将其唤醒(notify());在有多个线程进行等待时, 如果需要,可以使用 notifyAll()来唤醒所有的等待线程。
wait/notify 就是线程间的一种协作机制。
等待唤醒中的方法
等待唤醒机制就是用于解决线程间通信的问题的,使用到的3个方法的含义如下:
- wait:线程不再活动,不再参与调度,进入 wait set 中,因此不会浪费 CPU 资源,也不会去竞争锁了,这时的线程状态即是 WAITING。它还要等着别的线程执行一个特别的动作,也即是“通知(notify)”在这个对象上等待的线程从wait set 中释放出来,重新进入到调度队列(ready queue)中
- notify:则选取所通知对象的 wait set 中的一个线程释放;例如,餐馆有空位置后,等候就餐最久的顾客最先入座。
- notifyAll:则释放所通知对象的 wait set 上的全部线程。
调用wait和notify方法需要注意的细节
- wait方法与notify方法必须要由同一个锁对象调用。因为:对应的锁对象可以通过notify唤醒使用同一个锁对象调用的wait方法后的线程。
- wait方法与notify方法是属于Object类的方法的。因为:锁对象可以是任意对象,而任意对象的所属类都是继承了Object类的。
- wait方法与notify方法必须要在同步代码块或者是同步函数中使用。因为:必须要通过锁对象调用这2个方法。
重点:有效的利用资源
比如(生产一个包子,吃一个包子,再生产一个,再吃掉一个包子)
|