| 
 类 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个方法。
 
 
  
 
  
重点:有效的利用资源     
比如(生产一个包子,吃一个包子,再生产一个,再吃掉一个包子)  
 
 
 
 
  
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 |