就业班第三天
学习内容 List、Set、Collections
第一章:数据结构
1.栈:栈的特点:
先进后出 (FILO, First In Last Out) 入口和出口在同一侧
入栈(压栈): 将元素存入栈
出栈(弹栈): 从栈中取出元素
栈的适用场景:
栈内存 (main方法先进栈调用, main方法中的其他方法都调用完毕后, main才能出栈)
反转内容 (车尾变车头, 进去再出来就反转了)
2.数组: 数组的特点:
查询快: 通过 (第一个元素地址值 + 索引) 可以快速计算出该索引元素的地址值
增删慢: 增加一个元素, 要创建长度+1的新数组, 然后将原数组元素复制到新数组, 然后存入新元素; 删除类似
数组的适用场景:
查询多, 增删少的数据存储场景 国内城市
3 .链表:链表的特点:(分为单向链表与双向链表)
查询慢: 要找到其中某个节点, 只能从第一个节点一个一个向后寻找
增删快: 只需要修改保存的下一个节点的地址值, 就可以快速完成增删
链表的适用场景:
查询少, 增删多的场景
链表可以实现栈和队列的结构, 因为栈和队列增删频繁
4 .队列: 队列的特点:
先进先出 (FIFO, First In First Out)
入口和出口在两端
队列的适用场景:
秒杀, 抢购
在线售票
处理高并发场景
5 .红黑树: 是一种 平衡 二叉 查找 树
平衡: 左子节点和右子节点数量相等
二叉: 每个节点最多有2个子节点
查找: 节点存储的元素是按照大小顺序存储的
特点:
元素存储过程中就完成了大小排序
查询比链表快, 增删比数组快 (数组和链表的折中)
红黑树的适用场景:
查询和增删都有, 需要元素自动排序的场景
第二章:List 集合(接口)
特点:有索引,有序,允许储存重复元素
List 集合的实现类:
ArrayList :(底层是数组结构,查询快增删慢)适用查询较多
LinkedList(接口的链表实现):查询慢增删快。方便元素添加与删除的集合
Java.utll.Set
Vector 集合:已不用被ArrayList替代了(理解)
第二章:Set 集合(接口)
特点: 没有索引(不能使用普通for循环),不能存储重复元素
HashSet 集合(实现了Set接口):特点-(底层是哈希表结构):查询速度快; 没有顺序,没有索引
HashSet原理:哈希值
hashCode方法:返回该对象的哈希值
native:代表该方法调用的是本地操作系统的方法(了解)
HashSet存储自定义类型元素
能够说出哈希表的特点: 哈希表 = 数组 + 链表/红黑树 先调用 hashCode()算出哈希值, 根据哈希值判断数组中是否有重复元素 如果要没有, 就添加 如果有元素, 哈希值冲突 则调用元素的 equals() 遍历 链表/红黑树 依次比较 如果有重复的, 则不添加 如果没有重复的, 则添加 LinkeHashSet (有序不允许重复)集合(继承HashSet)
特点:底层是哈希表(数组+链表/红黑树)+链表:多了一条链表(记录元素的储存顺序),保证元素有序补充:如果想去重又想对其进行排序可以使用TreeSet集合.
第三章:可变参数
可变参数的格式
方法名(参数类型... 变量名) { // 当作数组来使用 } 方法名(); // 数组 注意事项: 只能有1个可变参数, 必须放在最后
使用前提: 当方法的参数列表数据类型已经确定,但是参数的个数不确定,就可以使用可变参数
第四章 : 操作集合的工具类Collections
Collections类
static addAll(Collection c, T... t) static shuffle(List list) static sort(List list) static sort(List list, Comparator c) 能够使用Comparator比较器进行排序 static sort(List list, Comparator c)
传递Comparator实现类对象, 重写 compare(T o1, T o2) 规则: o1 - o2 升序 o2 - o1 降序
今日所学集合总结: Collection接口: 单列集合的根接口, 规定了公共的功能 | |_ List接口: 元素存取有序, 可重复, 有索引 | |_ Vector类: 底层数组, 有索引, 内存空间连续分配, 查询快, 增删慢, 线程安全, 效率低 | |_ ArrayList类: 底层数组, 有索引, 内存空间连续分配, 查询快, 增删慢, 线程不安全, 效率高 | |_ LinkedList类: 底层链表, 查询慢, 增删快 | |_ 遍历 | - toArray(): 可以 | - 普通for: 可以 | - 增强for: 可以 | - 迭代器: 可以 | |_ Set接口: 元素不可重复, 无索引 |_ HashSet类: 底层哈希表, 元素无序, 元素不可重复(用hashCode()和equals()方法来判断) | |_ LinkedHashSet类: 哈希表+链表, 同时具有HashSet的元素不重复, 链表存取有序的特点 | |_ TreeSet类: 底层红黑树结构(存入元素时就会按照元素自然顺序排序). | |_ 遍历 - toArray(): 可以 - 普通for: 不可以, 没有索引, 不能用! - 增强for: 可以
- 迭代器: 可以 今日常用API java.util.List接口: // 常用特有成员方法 (都是按照索引来操作的) public void add(int index, E element): 将指定的元素, 添加到该集合中的指定位置上 public E get(int index): 返回集合中指定位置的元素 public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素 public E set(int index, E element): 用指定元素替换集合中指定位置的元素, 返回值的更新前的元素 java.util.LinkedList类: 链表结构, 查询慢, 增删快 // 特有成员方法(主要操作开头和末尾元素) void addFirst(E e): 将指定元素插入此列表的开头 void addLast(E e): 将指定元素添加到此列表的结尾 E getFirst(): 返回此列表的第一个元素 E getLast(): 返回此列表的最后一个元素 E removeFirst(): 移除并返回此列表的第一个元素 E removeLast(): 移除并返回此列表的最后一个元素 E pop(): (其实就是removeFirst())从此列表所表示的堆栈处弹出一个元素 栈stack void push(E e): (其实就是addFirst())将元素推入此列表所表示的堆栈 java.util.Collections类: 操作集合的工具类 // 静态方法 static <T> boolean addAll(Collection<T> c, T... elements) :往集合中添加一些元素 static void shuffle(List<?> list) :打乱集合顺序 static <T> void sort(List<T> list) :将集合中元素按照默认规则排序 static <T> void sort(List<T> list,Comparator<? super T> ) :将集合中元素按照指定规则排序 就业班第四天 学习内容 Map、HashMap 1、Map双列集合总结 Map集合概述: 特点:1.Map集合是一个双列集合,一个元素包含两个值(key,vatue) 2.Key和 vatue的数据可以相同也可以不同 1. Key不可以重复,value可以重复 2. Key和 vatue是一一对应的,一个键只能对应一个值 成员方法: V put(K key, V value): 添加/修改键值对. 如果键存在, 则用新值替换已有值 V remove(Object key): 根据键删除键值对, 返回被删除元素的值 V get(Object key): 根据键获取值. 如果键不存在, 则返回null boolean containsKey(Object key): 判断是否包含指定的键 遍历方法: Set<K> keySet(): 获取Map集合中所有的键, 存储到Set集合中 Set<Map.Entry<K,V>> entrySet(): 获取到Map集合中所有的键值对对象的集合(Set集合)
Map接口: 双列集合的根接口, 规定了共性的方法 |_ HashMap类: 哈希表=数组+链表+红黑树. key无序不可重复, 可存null键null值, 线程不安全效率高 | |_ LinkedHashMap类: 哈希表+链表. 哈希表实现key不可重复, 链表实现key存取有序 | |_ Hashtable类: 哈希表. Hash特性针对key, key无序不可重复, 不可存null键null值, 线程安全效率低 |_ TreeMap类: 红黑树结构(存入时就排序). Tree特性针对key, 可以按照key排序, 要求key具备比较性 |_ 遍历 |_ keySet(): 获取所有key组成的Set集合, 遍历Set集合拿到key, 通过Map的get(key)得到value,也叫做“键找值” | |_ 对于Set<Key>的遍历 | |_ 增强for | |_ 迭代器 |_ entrySet(): 获取所有的key和value组成的Entry对象的Set集合, 遍历出entry对象, 通过entry对象的getKey()获取对应的key, 通过Entry对象的getValue方法获取对应的value 也叫做“键值对” |_ 对Set<Entry>的遍历 |_ toArray() |_ 增强for |_ 迭代器/
HashMap(集合)储存自定义类型的键值 Map集合保证key是唯一的: 作为key的元素,必须重写hashCode方法和equals方法,以保证key唯一
2、Debug调试模式介绍 断点: breakpoint, 在debug模式下, 程序运行到断点会暂停住, 便于我们在程序运行过程中查看 Debug调试程序: 可以让代码逐行执行,查看代码执行的过程,调试程序中出现的bug 使用方式: 在行号的右边,鼠标左键单击,添加断点(每个方法的第一行,哪里有bug添加到哪里) 右键,选择Debug执行程序 程序就会停留在添加的第一个断点处 执行程序: f8:逐行执行程序 f7:进入到方法中 shift+f8:跳出方法 f9:跳到下一个断点,如果没有下一个断点,那么就结束程序 ctrl+f2:退出debug模式,停止程序 Console:切换到控制台
今日常用API java.util.Map接口: 双列集合的顶层 // 成员方法 V put(K key, V value): 添加/修改键值对. 如果键存在, 则用新值替换已有值 V remove(Object key): 根据键删除键值对, 返回被删除元素的值 V get(Object key): 根据键获取值. 如果键不存在, 则返回null 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 集合
就业班第五天 学习内容 异常类的处理 第一章 1、异常的分类
Java.lang Throwable:类 是 java 语言中所有错误异常的超类 Exception:编译期异常,进行编译 java出现的问题 RuntimeException:运行期异常,java运行过程中出现的问题 Error:错误 错误必须修改源代码,程序才能继续执行(可以比喻成无法治愈的病) //异常的体系结构 java.lang.Throwable // 体系最顶层 |_ Error // 错误 |_ Exception // 编译时异常 |_ RuntimeException // 运行时异常 2、JVM对于异常的默认处理方式是: 1. 将异常信息(内容, 原因, 位置)打印到控制台 2. 终止当前的程序 3、异常的处理方式 1.throw关键字作用:可以使用throw关键字在指定的方法中抛出指定的异常. 2.throws声明异常 格式: 修饰符 返回值类型 方法名() throws 异常类名1, 异常类名2, ... { } 3.捕获异常: try { // 可能产生异常的代码 } catch (异常类名 变量名) { // 处理异常的代码 // 一般会将异常信息存储到日志中 } ... } catch (异常类名 变量名) { // 处理异常的代码 // 一般会将异常信息存储到日志中 }
5.finally 代码块 finally: 有一些特定的代码无论异常是否发生,都需要行,另外,因为异常会引发程序的跳转,导致有些语句执行不到.而finally就是解决这个问题的,在finally代码块中存放的代码都是一定会执行的.
4、异常注意事项1: 捕获多个异常的3种方式 捕获多个异常: 1. 多个异常分别 try...catch 处理 2. 一个 try 多个 catch 如果异常存在继承关系, 子类异常在上, 父类异常在下 3. 多个异常, 一次捕获一次处理。用Exception多态捕获 4.如果 finally 代码块中有 return 语句, 则永远返回 finally 中的return 语句的值,应该避免在 finally 中写 return 语句
5. 子父类继承关系下, 子类重写父类带有throws的方法: 1. 如果父类抛出多个异常, 子类重写父类方法时可以有3种方式: a: 抛出和父类相同的异常 b: 抛出父类异常的子类 c: 不抛出异常 2. 父类方法没有抛出异常, 子类重写父类该方法时也不可抛出异常 此时子类产生该异常, 只能捕获处理, 不能声明抛出 父类方法声明的异常是什么样的, 子类重写的方法声明异常就什么样, 保持一致即可。
自定义异常类: Java 提供的异常类,不够我们使用,需要自己定义一些异常类 格式:public class XXXExcepiton exteds(继承) Excepiton 或者 extends(继承) RuntimeExcepiton{ 添加一个空参的构造方法
第二章 5、多线程计算机基本概念: 并发与并行 并发: (交替执行) 指两个或多个事件在"同一时间段内"发生 并行: (同时执行) 指两个或多个事件在"同一时刻"发生 (同时发生) 并发的实现, 是依靠电脑CPU快速地在多个任务之间切换执行实现的
进程与进程 进程: 一个应用程序在内存中的一次执行过程,一个应用程序可以同时运行多个进程,是系统运行的基本单位,系统运行一个程序即是一个进程创建、运行到消亡的过程 线程:线程是进程中的一个执行单元,负责当前进程中程序的执行,一个进程中至少有一个线程,一个进程中是可以有多个线程的,这个应用程序也可以成为多线程程序 线程的调度 分时调度:所有线程轮流使用CPU的使用权,平均分配每个线程占用CPU的时间 抢占式调度:优先让优先级搞得线程使用CPU,如果线程的优先级相同,那么会随机选择一个(线程随机性),java使用的为抢占式调度
}
就业班第六天 学习内容 多线程与同步 第一章 两种创建线程的方法 1.使用继承类的方式创建多线程 继承Thread 1. 定义类继承Thread类 2. 重写run()方法 3. 创建子类的对象 4. 调用start()方法启动线程 2.使用实现接口的方式创建多线程任务 实现Runnable接口 1. 定义类实现Runnable接口 2. 重写run() 3. 创建Runnable实现类对象 4. 创建Thread对象, 并将Runnable实现类对象传入
5. 调用Thread对象的start() Thread 和 Runnable的区别: 实现 Runnable接口创建多线程程序的好处: 1. 避免了单继承的局限性 一个类只能继承一个类(一个人只能有一个亲爹),类继承了Thread类就不能继承其他的类 实现了Runnable 接口,还可以继承其他的类,实现其它接口 2. 增强了程序的扩展性,降低了程序的耦合性(解耦) 实现了Runnable接口的方式,把设置线程任务和开启心线程进行了分离(解耦)
匿名内部类方式实现线程的创建 匿名:没有名字 内部类:写在其他类的内部的类 匿名内部类作用:简化代码 把子类继承父类,重写父类的方法,创建子类对象合一步完成 把实现类实现类接口,重写接口中的方法,创建实现类对象合成一步完成 匿名内部类的最终产物:子类/实现类对象,而这个类没有名字 格式:new 父类/接口(){ 重复父类/接口中的方法};
第二章 线程安全 线程的同步 为了保证每个线程都能正常执行原子操作,java引入了线程同步机制. 那么怎么去使用呢?有三种方式完成同步操作: 1.同步代码块 2.同步方法 3.锁机制(Lock) 1.同步代码块解决线程安全问题 synchronized (锁对象) { // 操作共享变量的代码(可能发生安全问题的代码) }
2.同步方法解决线程安全问题 非静态: public synchronized 返回值类型 方法名(参数列表) { // 操作共享变量的代码(可能发生安全问题的代码) } 锁对象: this 静态: public static synchronized 返回值类型 方法名(参数列表) { // 操作共享变量的代码(可能发生安全问题的代码) } 锁对象: 当前类的字节码对象 Class对象 (同一个类, 字节码对象只有唯一的一个) 对象.getClass() 类名.class Class.forName("类的全名字符串") 3.锁对象(Lock): 1. 类型可以是任意类型 2. 锁对象必须是多个线程共享的唯一的同一个对象 方法: void lock ( ) 获取锁; Void unlock() 释放锁
多线程安全问题的出现的原因 多线程操作共享变量
线程6个状态的名称 NEW 新建 RUNNABLE 可运行 BLOCKED 锁阻塞 WAITING 无限等待 唤醒的方法: 1. Void notify() 唤醒在此对象监视器上等待的单个线程 2. Void notifyAll 唤醒在此对象监视器上等待的所有线程 TIMED_WAITING 计时等待: 两种计时等待方式: 1. 使用sleep(long m)方法,在毫秒值结束之后,线程睡醒进入到Runnable/Blocked状态 2. 使用wait(long m)方法,wait方法如果在毫秒值结束之后,还没有被notify唤醒,就会自动醒来,线程睡醒进入到Runnable/Blocked状态 TERMINATED 终止 今日常用API 构造方法 Thread Thread(): 创建Thead对象 Thread Thread(String threadName): 创建Thead对象并指定线程名 Thread Thread(Runnable target): 通过Runnable对象创建Thread对象 Thread Thread(Runnable target, String threadName): 通过Runnable对象创建对象并指定线程名 // 成员方法 void run(): 用于让子类重写, 表示该线程要执行的任务.不能直接调用 void start(): 启动线程, 即让线程开始执行run()方法中的代码 String getName(): 获取线程的名称 void setName(String name): 设置线程名称 // 静态方法 static Thread currentThread(): 返回对当前正在执行的线程对象的引用 static void sleep(long millis): 让所在线程睡眠指定的毫秒 java.lang.Object类: // 成员方法 (只能通过"锁对象"调用) void notify(): 随机唤醒在同一个锁对象上的某一个处于等待状态的线程 void notifyAll(): 唤醒所有在同一个锁对象上处于等待状态的线程 void wait(): 让当前线程处于无限等待状态 void wait(long timeout): 让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态 void wait(long timeout, int nanos): 让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态
|