黑马程序员技术交流社区
标题: 【石家庄校区】就业班Day 3 - 6学习资料 [打印本页]
作者: cwb.. 时间: 2018-9-20 15:52
标题: 【石家庄校区】就业班Day 3 - 6学习资料
本帖最后由 小石姐姐 于 2018-9-21 08:56 编辑
就业班第三天
学习内容 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类
[Java] 纯文本查看 复制代码
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接口:
// 常用特有成员方法 (都是按照索引来操作的)
[Java] 纯文本查看 复制代码
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类: 链表结构, 查询慢, 增删快
// 特有成员方法(主要操作开头和末尾元素)
[Java] 纯文本查看 复制代码
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类: 操作集合的工具类
// 静态方法
[Java] 纯文本查看 复制代码
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
构造方法
[Java] 纯文本查看 复制代码
Thread Thread(): 创建Thead对象
Thread Thread(String threadName): 创建Thead对象并指定线程名
Thread Thread(Runnable target): 通过Runnable对象创建Thread对象
Thread Thread(Runnable target, String threadName): 通过Runnable对象创建对象并指定线程名
// 成员方法
[Java] 纯文本查看 复制代码
void run(): 用于让子类重写, 表示该线程要执行的任务.不能直接调用
void start(): 启动线程, 即让线程开始执行run()方法中的代码
String getName(): 获取线程的名称
void setName(String name): 设置线程名称
// 静态方法
[Java] 纯文本查看 复制代码
static Thread currentThread(): 返回对当前正在执行的线程对象的引用
static void sleep(long millis): 让所在线程睡眠指定的毫秒
java.lang.Object类:
// 成员方法 (只能通过"锁对象"调用)
[Java] 纯文本查看 复制代码
void notify(): 随机唤醒在同一个锁对象上的某一个处于等待状态的线程
void notifyAll(): 唤醒所有在同一个锁对象上处于等待状态的线程
void wait(): 让当前线程处于无限等待状态
void wait(long timeout): 让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态
void wait(long timeout, int nanos): 让当前线程处于计时等待状态, 时间到或被唤醒后结束此状态
欢迎光临 黑马程序员技术交流社区 (http://bbs.itheima.com/) |
黑马程序员IT技术论坛 X3.2 |