A股上市公司传智教育(股票代码 003032)旗下技术交流社区北京昌平校区

 找回密码
 加入黑马

QQ登录

只需一步,快速开始

© 859182973 中级黑马   /  2018-12-17 09:33  /  1024 人查看  /  0 人回复  /   0 人收藏 转载请遵从CC协议 禁止商业使用本文

类 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个方法。



重点:有效的利用资源   

比如(生产一个包子,吃一个包子,再生产一个,再吃掉一个包子)





















0 个回复

您需要登录后才可以回帖 登录 | 加入黑马