_01_Object类

/*
* java.util.Object Object类是最顶层的类,每个类都使用Object类作为父类
* 所有对象(包括数组)都实现这个类的方法
* 注:
* 使用toString方法返回值为地址值时,说明该对象没有重写toString方法。
* 返回值非地址值,则该对象重写了toString方法
*
*
* */
/*
* boolean equals(Object obj)
* Object obj :表示可以传递任何值
* 基本类型:比较数值
* 引用类型:比较地址值
* public boolean equals(Object obj) {
return (this == obj);
} 比较地址没有意义,所以对equals方法进行重写
* */
/*
* 1 Object :所有类的父类,一个类直接或间接的继承这个类,该类提供常用的方法
* 2 toString方法:
* 打印对象的信息
* 重写前:打印:包名@地址值
* 重写后:打印:对象中的属性值
* 3 equals方法:
* 比较两对象
* 重写前:比较对象地址值
* 重写后:比较对象中的属性值
*
* Objects类:
* equals方法:比较对象是否相同,添加了一些健壮性的判断
* */

_02_Date类

/*
*java.util.Date; //表示特点给的瞬间,精确到毫秒
* 毫秒:1000毫秒 = 1秒
* 毫秒值的作用:可以对时间和日期的计算
* 日期转毫秒,计算后毫秒转日期
* 0毫秒值:1970年1月1日 00:00:00(英国格林威治)
* 注:中国属于东八区,时间加8小时
* 1天 = 24h X 60min X 60 second = 86400s = 86400 X 1000 毫秒 = 8640000毫秒
* System.currentTimeMillis(); //返回当前之间到1970.1.1 的毫秒时间
* Date(); //获取当前日期和时间
*
* */
/*
* java.text.DateFormat; //日期/时间格式化子类的抽象类,完成日期和文本之间的转换,在Date对象和String对象之间转换
* 格式化:Date对象转String对象
* 解析:String对象转Date对象
* 成员方法:
* String format(Date date) //按照指定模式,将日期类型转化为符合模式的字符串输出
* Date parse(String source) throws ParseException// 把符合模式的字符串,解析为Date日期
* pause声明解析 异常
* 处理:1 继续抛出异常
* 2 try ……catch自己处理异常
* 注:DateFormat类是个抽象类,无法创建对象使用,所以使用其子类SimpleDateFormat类
* SimpleDatemat类的构造方法:java.text.SimpleDatemat extends DateFormat
* SimpleDateFormat (String pattern) //用给定的模式和语言环境的日期格式符号构造
* 参数 : String pattern //传递指定的参数
* 模式:区分大小写
* y 年
* M 月
* d 日
* H 时
* m 分
* s 秒
* 注:模式中的字母不可更改,连接符可以更改 例:“yyyy年MM月dd日 HH:mm:ss” //“yyyy-MM-dd HH时mm分ss秒”
*
*
* */

_03_Calendar类

/*
* java.util.Calendar; //日历类,替换许多Date方法 为抽象类 需创建子类对象进行使用
* //操作日期字段的方法(YEAR、MONTH、DAY_OF_MONTH、HOUR)
* 静态方法:getInstance();//返回Calendar类的子类对象
* static Calendar getIstance(); //使用默认时区和语言环境获得一个日历
* Calendar类的常用成员方法:
* public int get (int field){} //返回给定日历字段的值
* public void set (int field, int values){} //将给定字段设置给日历字段
* public abstract void add(int field , int amount) //给日历字段增加或减少某个值
* public Date getTime (); //将日历字段转换成Date对象
* */

_04_System类

/*
*java.lang.System 类中提供了大量静态方法,获取与系统相关的信息和系统级操作
* 常用方法:
* public static long currentTimeMillis(); //返回以毫秒为单位的当前时间
* public static void arrayCopy (Object src, int srcPos, Object dest, int desPos, int length);
* //src:源数组 srcPos:原数组起始位置 dest:目标数组 desPos:目标数组起始位置,length:替换长度
* */

_05_StringBuilder类

/*

StringBuilder类:字符串缓冲区,提高字符串的操作效率,(长度可以变化的字符串)
底层为数组,没有被final修饰,可改变长度
byte[] value = new byte[16]; //默认16
占用空间少,效率高
超出长度,会自动扩容 构造方法:
public StringBuilder();//构造一个空的StringBuilder容器
public StringBuilder(String str);//字符串添加到容器中
StringBuilder的成员方法:
public StringBuilder append();//添加任意类型数据的字符串形式,并返回对象自身
reverse(); //字母的反转
toString(); //StringBuilder和String之间的转换 */

_06_包装类

/*
* 包装类: int Integer
* byte Byte
* char Character 等
* 装箱:基本类型转换为对应的包装类对象
* 构造方法 :
* Integer(int value); //int 包装为 Integer
* Integer (String s); //String 包装为 int 转换的字符与int类型相对应,否则报错
* 静态方法:
* static Integer valueOf(int i);
* static Integer valueOf(String s);
*
* 拆箱:包装类 转 基本类型
* 成员方法:
* int intValue(); //以int类型返回该Integer的值
* 自动拆箱和自动装箱:
* Integer int3 = 9; //自动装箱:Integer int3 = new Integer(9);
int3 = int3 + 2;// int3+2 : int3.intValue() + 2 = 11 int3 = new Integer(11); //ArrayList无法直接存取整数,可以存储Integer包装类
System.out.println("=======================");
ArrayList<Integer> arrayList = new ArrayList<>();
arrayList.add(1); // add(new Integer(1));
arrayList.get(0); //获取0号索引上的Integer类型元素
int int5 = arrayList.get(0); //自动拆箱 int int5 = arrayList.get(0).valueOf();
*
* */

_07_Collection集合

/*
* 集合与数组的区别:
* 1 数组长度固定,集合长度可变
* 2 数组存储一类型元素且能存储基本数据类型,集合存储对象且对象类型可不一致。开发中对象多的时候,使用集合进行存储
*
* */
/*
学习集合的目的:
会使用集合存储数据
会遍历集合
掌握集合的特性
集合框架的学习方式:
学习顶层:学习顶层接口/抽象类中的共性的方法,所有子类的使用
使用底层:底层不是 接口就是抽象类,无法创建对象使用,需要使用底层的子类创建对象使用 Collection集合:
定义的是所有单列集合中共性的方法
所有单列集合都可以使用共性的方法
没有带索引的方法
List接口:Vector集合、ArrayList集合、LinkedList集合
有序的集合(存取顺序相同)
允许存储重复的元素
有索引,可以使用普通的for循环遍历
Set接口:Treeset集合(无序)、HashSet集合(LinkedHashSet集合(有序))
不允许存储重复的元素
没有索引(无法使用for循环遍历) List集合:有索引,可存储重复元素,保证存储顺序
ArrayList:底层数组实现,查询快,增删慢
LinkedList:底层是链表实现,查询慢,增删快
Set集合:无索引,不可存储重复元素,存取无序
HashSet:底层是哈希表+(红黑树)实现,无索引,不可存储重复元素,存取无序
LinkedHashSet:底层是哈希表+链表实现,无索引,不可存储重复元素,存取无序
TreeSet:底层是二叉树实现,一般用于排序 */
/*
* Collection集合共性常用方法:
boolean add(E e); //向集合中添加元素
boolean remove(E e);//删除集合中的某个元素
void clear(); //清空集合
boolean contains(E e);//查看集合是否包含某个元素
boolean isEmpty();//判空
int size();//获取集合的长度
Object[] toArray();//将集合转换成数组 * */
/*
* Iterator接口(Iterator迭代器):Collection集合元素的通用获取方式,取前判空,有则取,循环往复,无则停止。该方法称之为:迭代
*
* java.util.Iterator接口;迭代器(对集合进行遍历)
* 常用方法:
* boolean hasNext();//判断是否还有下一个元素,有返回true,没有返回false
* E next();返回迭代的下一个元素
* 注意事项:
* Iterator迭代器是一个接口,无法直接使用,需要使用Iterator接口的实现类对象,
* Collection集合中有个方法iterator(),这个方法返回的是迭代器的实现类对象
* Iterator<E> iterator();//返回在collectiond的元素上进行迭代的 迭代器
* 迭代器的使用步骤:
* 使用集合中的方法iterator()获取迭代器的实现类对象,使用Iterator接口接收
* 使用Iterator接口中的方法hasNext判断是否还有下一个元素
* 使用Iterator接口中的方法next方法取出集合中的下一个元素
*
* */
/*
* 增强for循环:底层使用迭代器,使用for循环格式,简化了迭代器的书写
* Collection<E> extends Iterator<E> //所有单列集合都可以使用增强for循环
* public interface Iterator<T> //实现这个接口允许对象成为 foreach 语句的目标
* 作用:用来遍历数组和集合
* 格式:
* for(集合/数组的数据类型 变量名: 集合名/数组) {
* System.out.println(变量名);
* }
* */

_08_泛型

/*
* 泛型:一种未知的数据类型,使用泛型
* 泛型也可看做一个变量,用来接收数据
* E e:Element元素
* T t:Type类型
* 例如:public class ArrayList<E> {
* public boolean add(E e) {};
* public E get (int index) {};
* }
* 注:创建集合对象的时候,确定泛型的数据类型
* public class ArrayList<String> {
* public boolean add(String e) {};
* public String get (int index) {};
* }
* //将数据类型作为参数传递给泛型
* public class ArrayList<Student> {
* public boolean add(Student e) {};
* public Student get (int index) {};
* }
*
* 集合对象与泛型的利弊:
* 集合对象:
* 好处:集合不使用泛型,默认类型为Object类型,可以存储任意类型的数据
* 弊端:不安全,会发生异常
* 泛型:
* 好处:避免了类型转换的麻烦,存储什么类型就是什么类型
* 弊端:只能存储一种数据类型
*
* */
/*含泛型的方法定义  格式:
修饰符 <E> 返回值类型 方法名 (参数列表(使用泛型)) {
方法体;
}
*
* */
/*
* 泛型的通配符:
* ? //代表任意数据类型
* 使用方法:
* 不能创建对象使用
* 只能作为方法的参数使用
*
* 通配符高级使用:(受限泛型)
* 泛型的上限:
* 格式:类型名称 <? extends 类> 对象名称 //只能接收该类型及其子类
* 泛型的下限:
* 格式:类型名称 <? super 类> 对象名称 //只能接收该类型及其父类型
* 注:已知:Object类,String类,Number类,Integer类,其中Number是Integer的父类
*
* */

_10_数据结构

/*
* 数据存储的常用结构:栈、队列、数组、链表、红黑树
* 栈:先进后出
* 队列:先进先出
* 数组:查询快:首地址 + 索引 快速找到元素
* 增删慢: 数组创建长度固定,增删需重新创建素组,将元素重新加入
* 链表:查询慢: 链表地址不连续,查询元素需要从头开始查询
* 增删快: 链表的增删元素对链表的整体结构没有影响
* 链表状态: 地址1|元素1|地址2 ———— 地址2|元素2|地址3 ————
* 单向链表(无序):链表中只有一条链子,不能保证元素的顺序(存取元素的顺序有可能不同)
* 双向链表(有序):链表中有两条链子,一条专门记录元素的顺序,是一个有序的集合
* 红黑树:
* 排序树/查找树:左子小,右子大
* *衡树:左右孩子数相等
* 不*衡树:右孩子!=左孩子
* 红黑树:趋*于*衡树,查询速度非常快,查询叶子结点的最大次数和最小次数不能超过2倍
* 约束:
* 1 结点可红可黑
* 2 根节点是黑色
* 3 叶子节点(空结点)是黑色
* 4 每个红色的结点的子节点是黑色
* 5 任何一个结点到其每个叶子节点的所有路径上黑色结点数相同
*
* */
/*List接口:
* Vector集合、LinkedList集合、ArrayList集合
* */
* java.util.List接口 extends Collection集合
* List接口的特点:
* 有序的集合,存取顺序一致,存123 取123
* 有索引,包含一些带索引的方法
* 允许存储重复的元素
*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); //指定元素替换指定位置元素,返回替换前的元素
* 注意事项:防止索引越界异常
* ArrayList集合:存储的结构是数组结构,增删慢,查找快
* LinkedList集合 implements List接口
* 特点:1 底层是一个链表结构,查询慢,增删快
* 2 包含大量操作首尾元素的方法
* 注:使用LinkedList集合特有的方法,不能使用多态
* public void addFirst(E e);
* public void addLast(E e);
* public void push(E e);//同addFirst(E e)
*
* public E getFirst(E e);
* public E getLast(E e);
*
* public E removeFirst(E e);
* public E removeLast(E e);
* public E pop(E e);
*
* public boolean isEmpty();
* Vector集合:实现可增长的对象数组
* 单线程,速度较慢。同ArrayList集合
* */
/*
* Set接口:Treeset集合(无序)、HashSet集合(LinkedHashSet集合(有序))
* HashSet集合: 有序,不重复
* 哈希值:十进制整数,由系统给出(即对象的地址,是个逻辑地址,并非物理地址)
* Object类中int hashCode()方法返回该对象的哈希值
* public native int hashCode(); //native代表该方法调用本地操作系统的方法
* HashSet集合存储数据的结构:(哈希表)
* 哈希表 = 数组 + 链表
* 哈希表 = 数组 + 红黑树(提高查询的速度)
* 特点:速度快
* 数据结构:把元素先 进行分组(相同哈希值的元素是一组),由哈希值组成数组机构,链表/红黑树结构把哈希值相同的元素连接在一起
* 存储数据:先计算元素的哈希值,哈希值相同的连接在同一个哈希值数组元素上
* 注:连接的链表长度超过8,自动转换为红黑树结构
* 哈希冲突:元素不同,哈希值相同。例如:重地 通话 //元素不同,哈希值相同1179395
* Set集合元素不重复原理:
* HashSet集合存储元素时:调用add方法时会调用hashCode方法和equals方法,判断元素是否重复
* 注:空集合时,先计算元素1的哈希值,集合中没有时添加元素到集合,再计算元素2的哈希值,集合中有相同哈希值时,再调用
* equals方法,比较元素1和元素2是否相同,返回ture时,认定重复元素2不进数组,否则添加到数组。保证HashSet集合中
* 元素不重复
* HashSet集合存储自定义元素:
* Set集合存储的数据(String,Integer,……,Student,Person)时,必须重写hashCode和equals方法,否则不能查重
* */
/*
* java.util.LinkedHashSet集合 extends HashSet集合 无序,不重复
* LinkedHashSet集合特点:底层是哈希表(数组 + 链表 /红黑树) + 链表:多了一条链表(记录元素存储顺序),保证元素有序
* */
/*
* 可变参数定义格式:
* 使用:只能在方法参数中使用
* 格式:修饰符 返回值类型 方法名 (参数类型 ... 参数变量) {}; //返回值是地址值,底层为数组
* public static int method(Object...obj){} //可变参数终极写法 任意参数,任意类型
* 注意事项:
* 1 可变参数只能有一个,且类型相同
* 2 可变参数与其他类型参数同时使用时,放在最后
* */
/*
*java.util.Collections;
* public static <T> boolean addAll (Collection<T> c, T ... elements); //集合中添加一些元素
* public static void shuffle (List<?> list); // 打乱集合顺序
*
* Public static <T> void sort(List<T> list); //将集合中元素按照默认规则排序
*
* Comparable接口跟Compatator接口中方法的区别
* public static <T> void sort (List<T> list, Comparator <? super T>); //将集合中元素按指定规则排序
* Comparable:自己(this)和别人(参数)比较,需要实现Comparable接口中CompateTo方法
* Comparator:相当于找一个第三方裁判,比较两个
* */

_11_Map集合

/*
* java.util.Map<k, v>接口
* Map集合的特点:
* 1 是一个双列集合,一个元素包含两个值(键key,值value)
* 2 Map集合中,key和value数据类型可以相同,也可以不同
* 3 key不允许重复,value可以允许重复
* 4 key和value是一一对应的
* Map接口常用子类:
* 1 java.util.HashMap<k, v> implements Map<k, v>接口
* 特点:
* HashMap底层是哈希表,查询速度快
* HashMap是无序 集合,存取顺序可能不一致
* 2 java.util.LinkedHashMap<k, v>集合 extends HashMap<k, v> 集合
* 特点:
* LinkedHashMap集合底层是哈希表+链表(保证迭代顺序)
* LinkedHashMap集合是有序集合,存取顺序一致
* Map接口常用方法:
* public V put (K key, V value);//将指定的键和指定的值添加到Map集合中
* public V remove(Object key);//指定键对应的键值对删除,返回被删除的值
* public V get(Object key);//根据键,获取对应的值
* boolean containsKey(Object key);//判断集合中是否包含指定的键
*
*
* */
/*
* Map集合的第一种遍历:
* Map集合中的方法:Set<k> keyset();//返回此映射中包含的键的视图(即取键变集合)
* 实现步骤:
* 使用Map集合中的keyset方法,将Map集合中的键取出来,存储在Set集合中
* 遍历set集合,遍历集合中每个key
* 通过Map集合中方法get(key),通过key找value
* Map集合的第二种遍历:
* Map.Entry<k, v> :在Map接口中有一个内部接口Entry
* 作用:Map集合创建的同时创建Entry对象,记录键与值得映射关系
* 步骤:
* Set<Map.Entry<k, v>> entryset :把Map集合内部多个entry对象取出存放在set集合中
* 遍历Set集合,获取集合中每个Entry对象
* Entry对象中得方法:getkey()//获取key
* getvalue()//获取value
*
* */
/*
* LinkedHashMap<k, v> extends HashMap<k, v>
* HashMap<k,v> ; //元素不允许重复,存储得是无序集合 存取顺序不一致
* LinkedHashMapM<k, v> ;//元素不允许重复,存储得是有序得集合 存取顺序一致 //哈希表 + 链表(记录元素顺序)的结构
* */
/*
* java.util.Hashtable<k, v> implements Map<k, v> 集合
* Hashtable:
* 底层是哈希表,一个线程安全的集合,单线程集合,速度慢
* 不能存储null键,null值
* Hashtable的子类Properties集合是唯一和I/O流相结合的集合
* HashMap:
* 底层是哈希表,一个线程不安全的集合,多线程集合,速度快
* 能存储null键,null值
*
*
* */
/*
* 分析:
* 使用Scanner获取字符串
* 创建Map集合,key是字符,value是字符出现次数
* 遍历字符串,获取每个字符
* 使用获取到的字符,Map集合中判断key是否存在
* key存在:
* 通过字符key,获取value(字符个数)
* value++
* put(key, value) 新的value存储在集合中
* key不存在:
* put(key, 1)
* 遍历Map集合,输出结果
* */
//public class _07_JDK9_of方法 {
// public static void main(String[] args) {
// List<String> list = List.of("a", "b", "c", "d");
// System.out.println(list);
//// list.add("e");//of方法添加元素后,集合不可使用add再添加元素UnsupportedOperationException
// //Set集合和Map集合不可有重复元素
//// Set<String> set = Set.of("a", "a", "b", "c", "d");//IllegalArgumentException: duplicate element: a
// Set<String> set = Set.of("a", "b", "c", "d");//无序集合
// System.out.println(set);
//
//// Map<String, Integer> map = Map.of("张三",15,"李四",15,"王五",15,"张三",15);//IllegalArgumentException: duplicate key: 张三
// Map<String, Integer> map = Map.of("张三",15,"李四",15,"王五",15,"赵六",15);//无序集合
// System.out.println(map);
// }
//}
/*
* List接口,Set接口,Map接口:增添的新静态方法of,可以个集合一次性添加多个元素
* static <E> List<E> of(E……element)
* 使用前提:当集合中的元素确定后,不能再修改(添加元素)
* 注意事项:
* of方法只适用于List接口、Set接口、Map接口,不适用于接口的实现类
* of方法的返回值是一个不能改变的集合,不能在使用add/put方法添加元素,会抛出异常
* Set和Map接口在调用of方法时,不能有重复的元素,否则会抛出异常
*
*
* */

_12_DeBug程序调试

public class _01_Debug程序调试 {
public static void main(String[] args) {
show();
} private static void show() {
for (int i = 0; i < 4; i++) {
System.out.println(i);
}
}
}
/*
* Debug程序调试:让代码逐行执行,查看代码执行过程,调试程序中出现的debug
* s使用方法:
* 行号的左边鼠标点击,添加断点(每个方法的第一行)
* 右键,点击DeBug执行程序
*注意事项:
* F8:逐行执行程序
* F7:进入当方法中
* shift+F8:跳出方法
* F9:跳到下一个断点,没有则退出程序
* ctrl+F2:退出debug模式,停止程序
* Console:切换到控制台
*
* */

_13_斗地主案例

package _01_知识点总结._13_斗地主案例;
/*
* 斗地主案例:
* 准备牌
* 洗牌
* 发牌
* 排序
* 看牌
*
* */ import java.util.*; public class _01_斗地主案例 {
public static void main(String[] args) {
//1 准备牌
//创建Map集合,存储牌的索引和牌的组合
HashMap<Integer, String> poker = new HashMap<>();
//创建ArrayList集合,存储牌的索引
ArrayList<Integer> pokerIndex = new ArrayList<>();
//创建2个List集合,存储花色和数字
List<String> color = List.of("", "", "", "");
List<String> number = List.of("2", "A", "K", "Q", "J", "10", "9", "8", "7", "6", "5", "4", "3");
//存储大王小王
Integer index = 0;
poker.put(index,"大王");
pokerIndex.add(index);
index++;
poker.put(index,"小王");
pokerIndex.add(index);
index++;
//遍历循环存储剩余牌
for (String colors : color) {
for (String numbers : number) {
poker.put(index, colors + numbers);
pokerIndex.add(index);
index++;
}
}
System.out.println(poker);
System.out.println(pokerIndex); //2 洗牌
Collections.shuffle(pokerIndex);
System.out.println(pokerIndex); //3 发牌
//定义四个集合,存储玩家123和 底牌
ArrayList<Integer> wanjia1 = new ArrayList<>();
ArrayList<Integer> wanjia2 = new ArrayList<>();
ArrayList<Integer> wanjia3 = new ArrayList<>();
ArrayList<Integer> dipai = new ArrayList<>(); for(int i = 0; i < pokerIndex.size(); i++){
Integer in = pokerIndex.get(i);
if(i >= 51) {
dipai.add(in);
}else if(i % 3 == 0) {
wanjia1.add(in);
}else if(i % 3 == 1) {
wanjia2.add(in);
}else if(i % 3 == 2) {
wanjia3.add(in);
}
}
System.out.println(wanjia1);
System.out.println(wanjia2);
System.out.println(wanjia3);
System.out.println(dipai); //4 排序
Collections.sort(wanjia1);
Collections.sort(wanjia2);
Collections.sort(wanjia3);
Collections.sort(dipai); //5 看牌 通过索引集合查看Map集合的方法
lookPoker("张三",poker,wanjia1);
lookPoker("李四",poker,wanjia2);
lookPoker("王五",poker,wanjia3);
lookPoker("底牌",poker,dipai);
/* //6 抢地主
System.out.println("抢地主:(Y/y)");
for(int i = 0 ;i < 3 ;i++) {
Scanner scanner = new Scanner(System.in);
String next = scanner.next();
if(next == "Y" || next == "y"){
if(i == 0) {
for (int i1 = 0; i1 < dipai.size(); i1++) {
wanjia1.add(i1);
}
}else{
if(i == 1) {
for (int i1 = 0; i1 < dipai.size(); i1++) {
wanjia2.add(i1);
}
}else {
if(i == 2) {
for (int i1 = 0; i1 < dipai.size(); i1++) {
wanjia3.add(i1);
}
}
}
break;
}
}
*/
} private static void lookPoker(String name , HashMap<Integer, String> poker , ArrayList<Integer> list) {
System.out.print("姓名:" + name + " ");
for (Integer key : list) {
String value = poker.get(key);
System.out.print(value + " ");
}
System.out.println();//一个玩家结束后 换行
}
}

_14_异常

/*
* 异常:程序执行过程中,出现非正常的情况,导致JVM的非正常停止的
* 面向对象编程中,异常本身是一个类,产生异常就是创建异常对象并抛出一个异常对象
* Java异常的方式是中断异常
* 异常分类:
* java.util.Throwable;//该类是所有异常和错误的超类
* Exception:编译异常,
* RunTimeException:运行异常
* 程序的小毛病,处理异常后能正常运行
* Error:错误
* 程序的错误,需修改程序
* 异常产生过程:
* JVM处理产生的异常
* JVM根据异常创建异常对象,包括异常产生的:内容原因位置 new ArrayIndexOutOfBoundsException(“3”);
* 在异常产生的方法中不能处理异常 抛出给main方法解决
* main方法处理异常:
* main方法接收异常处理逻辑,不能处理抛出给JVM处理
* JVM接收异常:
* 把异常对象红色打印给控制台
* JVM中断当前执行的java程序
*
*
/*
* throw关键字:
* 作用:使用throw关键字在指定的方法中抛出指定的异常
* 格式:throw new xxxException(“异常产生的原因”);
* 注意事项:
* throw关键字必须写在方法的内部
* throw关键字后边new的对象必须是Exception或者其子类对象
* throw关键字抛出指定的异常对象,就必须处理这个异常
* RunTimeException或其子类对象,可以不处理,欧默认JVM处理(打印异常,中断程序)
* throw后创建编译异常(写代码报错),必须处理异常。throws 或者 try …… catch
* */
/*
* throws关键字:异常处理的第一种方式
* 作用:
* 当方法内部抛出异常对象的时候,那么必须处理这个异常
* throws处理异常,抛出给调用者(调用者不处理,抛出给JVM),最终交给JVM,中断处理
* 使用格式:
* 修饰符 返回值类型 方法名(参数) throws AAAException, BBBException {
* throw new AAAException(“产生原因”);
* throw new BBBException(“产生原因”);
* }
* 注意事项:
* throws必须写在方法声明处
* throws关键字后边声明的异常必须是Exception或其子类对象
* 抛出多个异常,就要处理多个异常
* 如果抛出的异常有子类关系,直接声明父类异常即可
* 调用声明异常的方法,就必须处理异常
* throw给调用者,不处理后给JVM,中断处理
* try……catch自己处理
*
* */
/*
* try……catch:异常处理第二种,自己处理
* 格式:
* try{
* //可能产生异常的代码
* }catch(异常类型参数){
* //异常处理逻辑,一般写入日志中
* }
* ……
* catch(异常类型 变量名){
*
* }
* 注意事项:
* try抛出多个异常,用多个catch处理这些异常
* try中抛出异常,catch处理异常后继续执行后续代码
* try不跑出异常,catch不执行,执行后续代码
* */
/*
* Throwable类中定义了3个异常处理的方法 :
* String getMessage();//返回throwable 的简短描述
* String toString();//返回此throwable的详细消息字符串
* void printStackTrace();//JVM打印异常对象,默认此方法,打印信息最全
* */
/*
* finally代码块:
* try{
* //可能出现异常的代码
* }catch(异常类型 参数){
* //异常处理逻辑
* }finally{
* //无论是否出现异常都会执行的代码
* }
*
*注意事项:
* 不能单独使用,必须和try一起使用
* 一般用于资源释放(资源回收),无论程序是否出现异常,都会资源释放
* */
/*
*1 多个异常处理方式:
* 多个异常分别处理
* 多个异常一次捕获,多次处理
* 注意事项:
* catch定义的异常变量,存在子父类关系,子类异常变量需放在上边
* 上述:ArrayIndexOutOfBoundsException extends IndexOutOfBoundsException //正确定义,不报错
* 若调换位置,出现报错
* 多个异常一次捕获一次处理
*2 如果finall有return语句,一定返回finally中的内容
*
*3 子父类异常注意事项:
* 父类抛出多个异常,子类重写父类方法时,抛出和父类相同的异常/父类异常的子类/不抛出异常
* 父类方法没有抛出异常,子类重写该方法时也不能抛出异常,若抛出异常,只能捕获处理,不能声明抛出
* 注:父类异常什么样,子类异常就什么杨
* */
/*
* 自定义异常类 extends RuntimeException 方法中异常无需处理,异常交给JVM中断处理
* */

_15_多线程

/*
* 并发:两个或多个事件在同一时间段内发生(交替执行)
* 并行:两个或多个事件在同一时刻发生(同时执行)
*
* 进程:内存中运行的程序
* 硬盘ROM(永久存储) :程序文档存储的地方
* 内存RAM(临时存储) :程序文档调用到内存,占用内存空间执行程序,称为:进程
* 任务管理器:关闭进程后,进程占用内存空间释放
* 线程(Thread):进程中的一个执行单元,一个进程至少一个线程,一个进程可有多个线程,该应用程序称多线程程序
* 注:一个程序至少一个线程,一个进程可包含多个线程
* 单线程CPU:执行过程,在多个线程之间高速切换执行
* 4核8线程:执行过程,8个线程
* 多个任务之间高速切换执行(速度是单线程的8倍)
* 线程调度:
* 分时调度:所有线程轮流使用CPU使用权,*均分配每个线程占用时间
* 抢占式调度:优先让优先级高的线程使用CPU,优先级相同时随机选择一个线程执行,Java使用的为抢占式调度
* 线程优先级可设置:任务管理器,找到线程右击进行设置优先级
* 主线程:执行主方法(main)的线程
* 单线程程序:java程序只有一个线程,从main方法开始,从上到下执行
* JVM执行main方法,main方法进入栈内存
* JVM找操作系统开辟一条main方法到CPU的执行路径
* CPU通过路径执行main方法,该路劲称:主线程
* */
/*
*创建多线程第一种:创建Thread类的子类
* java.util.Thread类:描述线程 的类,实现多线程,必须继承Thread类
* 实现步骤:
* 创建一个Thread类的子类
* 在该子类中重写Thread类中的run方法,设置线程任务
* 创建该子类对象
* 调用Thread类中的方法start方法,开启新的线程,执行run方法
* start()方法使得该线程执行:JVM调用run()方法
* main线程和创建的线程(run方法) 同时并发执行
* 多次启动一个线程时非法的,特别时线程结束后不能再重新启动
* java程序的抢占式调度
*
* */
/*
* 获取线程的名称:
* 使用Thread类中的方法getname(); //返回该线程的名称
* 可以先获取当前执行的线程,使用线程getname()获取线程名称
* 设置线程的名字:
* 使用Thread类中的方法setName
* void setName(String name) 改变线程名称,使用与参数name相同
* 创建一个带参数的构造方法,参数传递线程的名字,调用父类的带参构造方法让父类给子类分配一个Thread对象
* 线程睡眠方法:
* public static void sleep(long millis);//使得当前执行的线程暂停指定毫秒数后执行
*
* */
/*
* 创建多线程第二种:实现Runnable接口
* java.util.Runnable; //接口应该由那些打算通过某一线程执行其示例的类实现,类必须定义一个称为run的无参数方法
* java.util.Thread类的构造方法
* Thread(Runnable target) ;// 分配新的Thread对象
* Thread(Runnable target, String name);//分配新的Thread对象
* 实现步骤:
* 创建一个Runnable接口的实现类
* 实现类中重写接口Runnable中的run方法,设置线程任务
* 创建一个Runnable接口的实现类对象
* 创建Thread类对象,构造方法中传递Runnable接口的实现类对象
* 调用Thread类中的start方法,开始新的线程执行run方法
*
*
*
* 实现Runnable接口创建多线程程序的好处:
* 避免了单线程的局限性:
* 一个类只能继承一个类,类继承了Thread类后就不能继承其他的类
* 实现了Runnable接口,还可以继承其他的类,实现其他的接口
* 增强了程序的扩展性,降低了程序的耦合性(解耦)
* 实现Runnable接口的方式,将设置线程任务和 开启新的线程进行了分离
* 实现类中,重写run方法,用来设置线程
* 创建Thread类对象,调用start()方法,用来开启线程任务
* */
public class _06_匿名内部类创建多线程 {
public static void main (String[] args) {
//创建Thread类对象,重写run()方法设置新线程任务,调用start()方法开启新线程任务
new Thread(){
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}.start(); //实现Runnable接口,创建匿名Thread对象,传递Runnable实现类,调用start开启新线程
Runnable runnable = new Runnable() { //创建Runnable接口匿名实现类
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
};
new Thread(runnable).start(); //Runnable接口实现类合Thread类对象的合并线程创建
new Thread(new Runnable(){
@Override
public void run() {
for (int i = 0; i < 10; i++) {
System.out.println(Thread.currentThread().getName() + " " + i);
}
}
}).start();
}
}
/*
* 匿名内部类实现线程的创建:
* 匿名内部类:简化代码
* 把子类继承父类,重写父类方法,创建子类对象合一步完成
* 把实现类实现接口,重写接口中的方法,创建实现类对象合成一步完成
* 最终产物:子类/实现类对象,没有名字
* 格式:
* new 父类/接口(){
* 重写父类/接口方法;
* };
*
*
* */

_16_线程安全问题

/*
* 线程安全性问题:多线程访问了共享的数据,会产生线程安全性问题
* 产生的原理:调用单个线程时,依次执行,但Thread类start()方法运行run()方法时,线程进入run()执行if语句时,就失去了CPU的控制权
* 便由下一个线程抢到Cpu控制权执行下一个线程,当线程抢占完毕后,均进入run()方法中。
* 程序还要继续执行,进程依次完成后,其中数据利用的时上一个进程产生的结果继续运行
* 所以会出现线程安全性问题(即:t0 出票1 t1出票0 t3出票-1 的情况)
* 解决线程安全性问题的方法:
* 同步代码块
* 解决线程安全性问题的第一种方案:使用同步代码块
* 格式:
* synchronized(锁对象){
* //可能会出现线程安全问题的代码(访问了共享数据的代码)
* }
* 注意事项:
* 通过代码块中的锁对象,可以使用任意的对象
* 必须保证多个线程使用的锁对象是同一个
* 锁对象作用:把同步代码块锁住,只让一个线程在同步代码快中执行
* 同步技术的原理:
* 使用了一个锁对象,锁对象叫同步锁,又叫 对象监视器
* 同步中的线程,没有执行完毕不会释放锁,同步外的线程没有锁进不去线程,需等待上一个线程释放锁才能获取锁执行锁对象
* 同步方法
* 解决线程安全性问题的第二种方案:同步方法
* 格式:定义方法的格式
* 修饰符 synchronized 返回值类型 方法名(参数列表) {
* //可能会出现线程安全问题的代码(访问了共享数据的代码)
* }
* 使用步骤:
* 把访问了共享数据的代码抽取出来,放到一个方法中
* 在方法上添加 synchronized 修饰符
* 静态同步方法:
* 锁对象:不是this,因为this是创建对象后产生的,静态方法优先于对象
* 静态方法的锁对象是本类的class属性,(class文件对象(反射))
* 锁机制(Lock)
* 解决线程安全性问题的第二种方案:使用Lock锁
* java.util.concurrent.locks.Lock接口
* Lock实现提供了比使用synchronized方法和语句可获得更广泛的锁定操作
* Lock接口中的方法:
* void lock();//获取锁
* void unlock();//释放锁
* java.util.concurrent.locks.ReentrantLock implments Lock接口
* 使用步骤:
* 在成员位置创建Lock接口的ReentrantLock实现类对象
* 在可能会出现问题的代码前调用Lock接口中的方法lock获取锁
* 在可能会出现问题的代码后调用Lock接口中的方法unlock释放锁
*
* */
/*
* NEW 新建状态 至今尚未启动的线程 例:new Thread(); new Thread子类();
* RUNNABLW 运行状态 正在java虚拟机上执行的线程
* BLOCKED 阻塞状态 受阻塞并等待 某个监视器锁的线程处于该状态
* WAITING 无限等待状态 无限期等待另一个线程来执行某一特定的线程
* TIMED_WAITING 休眠状态 等待另一个线程来执行取决于指定等待时间的操作的线程
* TERMINATED 死亡状态 已退出的线程
*
* */
/*
* 线程之间的通信:
* 创建一个顾客线程:高速老板要买包子,调用wait方法,放弃CPU的执行,进入WAITING状态
* 创建一个老板线程:花5s做包子,做好后调用notify方法,唤醒顾客吃包子,
* 注:
* 两个线程用同步代码块抱起来,保证等待和唤醒只能有一个在执行
* 同步使用的锁对象必须保证唯一
* 只有锁对象才能调用wait和notify方法
* Object类中的方法:
* void wait();//在其他线程调用该对象的notify()或notifyAll()方法前,导致当前线程等待
* void notify();//唤醒在此对象监视器上等待的单个线程,继续执行wait方法之后的代码
* */
/*
* 进入TimeWaiting(计时等待状态)由两种方式
* sleep(long m) ; //毫秒值结束,进入Runnable/BLOCKEDz状态
* wait(long m) ; //毫秒值结束,没有被notify唤醒,就自动醒来,线程睡醒进入Runnable/Blocked状态
*/
public static void main(String[] args) {
Object o = new Object(); //消费者
new Thread(){
@Override
public void run() {
while(true){
synchronized(o){
System.out.println("老板我要吃包子");
System.out.println("正在等包子的顾客……");;
try {//进入无限等待状态
o.wait();
} catch (InterruptedException e) {
e.getStackTrace();
}
}
System.out.println("顾客拿到了包子,开始吃");
System.out.println("++++++++++++++++++++++");
}
}
}.start();
//老板类
new Thread(){
@Override
public void run() {
while(true){
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.getStackTrace();
}
synchronized(o){ System.out.println("包子做好了,可以吃包子了");
o.notify();
// o.notifyAll();
}
} }
}.start(); } }

_17_等待唤醒机制

public class _01_线程间通信 {
}
/*
* 线程间通信:多个线程处理同一资源,但处理的动作不一样
* 处理线程间通信的原因:多线程并发执行,CPU随机切换线程,希望多线程有规律的完成一件任务,需要的一些协调通信
* 等待与唤醒机制:多个线程之间的协作机制
* 常用方法:
* wait
* notify
* notifyAll
* 注意事项:
* wait方法和notify方法必须由同一个锁对象调用(对应的锁对象可通过notify唤醒使用同一个锁对象调用的wait方法后的线程)
* wait和notify方法属于Object类(锁对象可以是任意对象,任意对象的所属类都继承于Object类)
* wait和notify要在同步代码块或同步函数中使用(必须通过锁对象调用这两个方法)
*
* */
/*
* 线程池:JDK1.5后提供:
* java.util.concurrent.Executors:线程池的工厂类,用来生成线程池
* Executors类中的静态方法:
* static ExecutorSerive newFixedThreadPool(int nThreads); //创建固定线程数的线程池
* 参数:创建线程池中的线程数量
* 返回值:ExecutorSerive接口,返回的时ExecutorSerive接口的实现类对象,可以使用ExecutorSerive接口接收
* java.util.concurrent.ExecutorSerive:线程池接口
* 用来从线程池中获取线程,调用start方法 ,执行线程任务
* submit(Runnable task); //提交一个Runnable任务用于执行
* 关闭/销毁线程池的方法:
* void Shutdown();
* 线程池的使用步骤:
* 使用线程池的工厂类Executors里提供的静态方法newFixedThreadPool生产一个固定线程数的线程池
* 创建一个类,实现Runnable接口,重写run方法,设置线程任务
* 调用ExecutorSerive接口中的方法submit,传递线程任务,开启线程,执行run方法
* 调用ExecutorSerive接口中的方法shutdown,销毁线程池(不建议使用) 销毁后线程无法调用 * */ import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors; public class _06_线程池{
public static void main(String[] args) {
//线性池工厂类Executors。中静态方法newFixedThreadPool创建线性池
ExecutorService ex = Executors.newFixedThreadPool(2); //调用ExecutorSerive接口中的方法submit,传递线程任务,开启线程,执行run方法
ex.submit(new _07_RunnableIMP());
ex.submit(new _07_RunnableIMP());
ex.submit(new _07_RunnableIMP());
ex.submit(new _07_RunnableIMP()); ex.shutdown(); //不建议使用,一但销毁线性池,线程就不能使用
// ex.submit(new _07_RunnableIMP());//销毁池子后创建线程会报错 }
} /*
* 线程池的概念:一个容器,容纳多个线程,其中线程可以反复多次使用。省掉了频繁创建线程的步骤,
* 线程池的优点:
* 降低资源消耗。减少创建销毁线程的次数。
* 提高响应时间。任务到达时,不许等待线程的创建就能立即执行
* 提高线程的可管理性。根据系统承受能力,调整线程池中工作线程数目,防止消耗过多内存。(每个线程约1MB内存)
*
*
* */
public class _08_函数式编程思想 {
public static void main(String[] args) {
inVokeCook(new _09_Cook接口测试类() {
@Override
public void Cook() {
System.out.println("匿名接口重写抽象方法执行了");
}
}); //使用Lambda表达式
System.out.println("===================================");
inVokeCook(() -> { System.out.println("匿名接口重写抽象方法执行了");}); //使用Lambda表达式简写格式
System.out.println("===================================");
inVokeCook(() -> System.out.println("匿名接口重写抽象方法执行了") );
} public static void inVokeCook(_09_Cook接口测试类 cook) {
cook.Cook();
}
}
/*
* 面向对象的思想:做一件事情,找能解决这个事情的对象,完成事情
* 函数式编程思想:只要获取到结果,谁做怎么做不中要,重视结果,不重视过程
*
* Lambda标准格式:
* 一些参数
* 一个箭头
* 一段代码
* 格式:(参数列表)->{重写方法的代码};
* 解释:
* () :接口中抽象方法的参数列表,无参空着,有参多参数逗号隔开
* -> : 传递,把参数传递给方法体
* {} :重写接口的抽象方法
* */
}
/*
* Lambda表达式:可推到,可省略
* 注:凡是根据上下文推到出来的内容,都可以省略书写
* 可省略的内容:
* (参数列表) : 括号中参数列表的类型可以省略不写
* 括号中参数就一个,那么类型和()都可以省略
* {一些代码} : {}中代码只有一行,无论是否有返回值,都可以省略{} return ; 三个元素
* 注:要省略,上述三个元素均省略
*
*
* */

_18_File类

/*
* java.io.File类
* 文件和目录路径名的抽象表示形式。
* java把电脑中的文件和文件夹分装在一个FIle类中,可以使用FIle类对文件和文件夹进行操作。
* File类的方法:
* 创建一个文件/文件夹
* 删除文件/文件夹
* 获取文件/文件夹
* 判断文件/文件夹
* 对文件夹进行遍历
* 获取文件的大小
* File类是一个与系统无关的类,任何的操作系统都可以使用这个类中的方法。
* 重点三个单词:
* file:文件
* directory:文件夹/目录
* path:路径
*
* File类的静态成员变量:
* static String pathSeparator 与系统有关的路径分隔符,它被表示为一个字符串
* static char pathSeparetorChar 于系统有关的路径分隔符
* static String separator 与系统有关的名称分隔符,被表示为一个字符串
* static char SeparetorChar 于系统有关的名称分隔符
* 操作路径:路径不能写死了
* C:\develop\a\a.txt windows
* C:/develop/a/a.txt Linux
* "C:"+ File.separator +"develop"+ File.separator +"a"+ File.separator +"a.txt"
*
* 绝对路径和相对路径:
* 绝对路径:完整的路径,以盘符开始的路径
* C:\\develop\\a\\a.txt
* 相对路径:简化的路径
* 当前项目的根路径C:\\develop\\a
* 使用当前项目的根路径,路径可以简写:a.txt(可省略项目的根路径)
* 注意:
* 路径不区分大小写
* 路径的文件名分隔符使用\,\为转义字符,\\代表一个普通的放斜杠
* */
/*
* File(String pathname); //通过将给定路径名称 ,转换为抽象路径名 来创建一个新File实例
* 参数:
* String pathname;//字符串的路径名称
* 路径可以以文件、文件夹结尾
* 路径可以是相对路径,或绝对路径
* 路径可存在,也可不存在
* 创建file对象,只是把字符串封装为File对象,不考虑路径的真假情况
* File(String parent,String child);
* 参数:
* 路径分为两部分
* 父路径和子路径,可单独写,
* File(File parent,String child);
* 参数:
* 路径分为两部分
* 父路径和子路径,可单独写
* 好处:父路径是File类型,可以使用File的方法对路径进行一些操作,再使用路径创建对象
*
* */
/*
* File类获取功能的方法
* public String getAbsolutePath(); //返回此File的绝对路径名字符串
* 注:无论路径是绝对路径,还是相对路径,该方法返回的是绝对路径。
* public String getPath(); //将File转换为路径名字符串
*
* public String getName(); //返回由此File表示的文件或目录的名称
* public long length(); //返回由此File 表示的文件的长度
*File判断功能的方法:
* public boolean exists(); //此File文件路径是否存在
* public Boolean isDirectory();//此File文件路径是否为文件夹结尾
* public Boolean isFile();// 此File文件路径是否以文件结尾
* 注:磁盘以文件夹或文件结尾,两种情况是互斥的,使用该方法文件路径必须存在
* File类创建删除功能得方法:
* public boolean createNewFile();//创建一个新的空 文件
* 返回值:true 文件不存在,创建文件,返回true
* false 文件存在,不创建文件,返回false
* 注:此方法只能创建文件,不是文件夹
* 创建文件的路径不许存在,否则会抛出异常
* public boolean mkdir();//创建单级空文件夹
* public boolean mkdirs();//即可以创建单级文件夹,也可以创建多级空文件夹
* 返回值:true 文件夹不存在,创建文件夹,返回true
* false 文件夹存在,不创建文件夹,返回false;构造方法中给出的路径不存在放回false
* 注:此方法只能创建文件夹,不是文件
* public boolean delete();//删除文件或目录
* 返回值:true 文件/目录删除成功,返回true
* false
* 注:
*File类中遍历(数组)方法:
* String[] list ; //遍历文件或目录
* File[] listFiles; //File封装对象,存入数组
* 注:隐藏文件/文件夹也可以遍历
* 文件/文件路径不存在,返回空指针异常NullPointerException
*
*
* */
public class _04_递归计算1到n的和 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入计算求和n的值:");
int n = scanner.nextInt();
System.out.println(n + "到1的和为:" + sum(n));
} private static int sum(int n) {
if( n == 1)
return 1;
return n + sum(n - 1);
}
}
public class _06_递归打印多级文件夹 {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
System.out.println("请输入需要遍历的磁盘文件夹:");
String string = scanner.next();
File file = new File(string);
getAllFiles(file);
} private static void getAllFiles(File file) { File[] files = file.listFiles();
for (File f : files) {
if(f.isDirectory()) {
getAllFiles(f);
} else {
System.out.println(f);
}
}
}
}
/*
* File类中由两个与listFiles重载的方法,方法的参数传递就是过滤器
*
* File[] listFiles(FileFilter filter);
* java.io.FileFilter接口:用于抽象路径名(File对象)的过滤器
* 作用:用来过滤文件(File对象)
* 抽象方法:用来过滤的方法
* boolean accept(File pathName); // 抽象路径是否包含在某个路径名列表中
* 参数:File pathName :使用ListFiles方法遍历目录,得到每一个文件对象
* File[] listFiles(FilenameFilter filter);
* java.io.FilenameFilter接口:实现此接口的类实例可用于过滤器文件名
* 作用:用来过滤文件名称
* 抽象方法:用来过滤的方法
* boolean accept(File dir,String name); // 指定文件是否包含在某一文件列表中
* 参数:File dir :构造方法中传递的被遍历的目录
* String name:获取的每个文件/文件夹的名称
*
*
* */

_19_字节流字符流

/*
* 字节流: 字节输入流:InputStream 字节输出流:OutputStream
* 字符流: 字符输出流:Reader 字符输出流:Writer
* 流:数据(字符、字节) ,1字符=2字节 ,1字节=8个二进制位
*
* java.io.OutputStream:字节输出流//此抽象类是表示输出字节流的所有类的超类
* 子类共有的方法:
* public void close();//关闭此输出流并释放与此流相关链的任何系统资源
* public void flush();//刷新此输出流并强制任何缓冲的输出字节被写出
* public void write(byte[] b);//将b.length字节从指定的字节数组写入此输出流
* public void write(byte[] b, int off, int len);//从指定字节数组写入len字节,从偏移量off开始输出到此输出流
* public abstract void write(int b);//将指定的字节输出流
* java.io.FileOutputStream extends OutputStream
* FileOutputStream:文件字节输出流
* 作用:把内存中的数据写入到磁盘文件中
* 构造方法:
* FileOutputStream(String name) //创建一个向具有指定名称的文件中写入数据的输出文件流
* FileOutputStream(File file) //创建一个向指定File对象表示的文件中写入数据的文件输出流
* 参数:
* String name :目的地是文件路径
* File file :目的地是文件
* 作用:
* 创建一个FileOutputStream对象
* 根据构造方法参数创建文件/文件路径,创建一个空的文件
* 会把FileOutputStream对象指向创建好的文件
* 写入数据的原理:java程序 -> JVM(java虚拟机) -> OS -> OS调用写数据的方法 -> 把数据写入到文件
* 字节输出流的使用步骤:
* 创建一个FileOutputStream对象,构造方法中写入传递数据的目的地
* 调用FileOutputStreamd对象中的方法write,把数据写入文件
* 释放资源(流使用会占用内存资源,使用完毕要内存清空,提高效率)
* 文件存储和打开的原理:硬盘中存储的都是字节(8比特位),文件打开的使用查询编码表(字节转换为字符)。
* 0~27:查询ASCII码表
* 其他值:查询系统默认的码表(中文系统GBK)
* 注:UTF-8 中 :3个字节为一个中文 , GBK中:2个字节为一个中文
* 字节输出流的续写和换行:
* FileOutputStream(String name, Boolean append); //指定name的文件写入数据的输出文件流
* FileOutputStream(File file, Boolean append); //指定File对象表示的文件写入数据的输出文件流
* 参数:append
* true :创建对象不覆盖原文件,在文件末尾续写数据
* false:创建一个新文件,覆盖源文件
* 换行:
* windows:\r\n
* linux:/n
* mac:/r
* java.io.InputStream:字节输入流 //此抽象类是表示字节输入流的所有类的超类
* 所有子类的公用方法:
* int read();//从输入流中读取数据的下一个字节
* int read(byte[] b);//从输入流中读取一定数量的字节,并将其存储到缓冲区数组b中
* void close()//关闭输入流并释放所有相关系统资源
* java.io.FileInputStream extends InputStream
* FileInputStream:文件字节输入流
* 作用:硬盘文件,读取到内存中使用
* 构造方法:
* FileInputStream(String name)
* FileInputStream(File file)
* 参数:读取文件的数据源
* String name:文件的路径
* File file : 文件
* 构造方法的作用:
* 创建一个FileInputStream对象
* 把FileInputStream对象指向构造方法中要读取的文件
* 读取数据原理:java程序 -> JVM -> os -> os读取数据的方法 -> 读取数据
* 字节输入流的使用步骤:
* 创建FileInputStream对象,构造方法中绑定要读取的数据源
* 使用FileInputStream对象中的方法read读取文件
*
*
* */
/*
* 字节输入流一次读取多个字节的方法:
* int read (byte[] b); //从输入流中一次读取一定数量的字节,将其存储在缓冲区数组b中
* 注:
* 方法参数byte[] 的作用:
* 起到缓冲作用,存储每次读取到的多个字节
* 数组 的长度一般定义为1024(1kb),或者1024的倍数
* 方法的返回值int值:
* 每次读取的有效字节个数
* String类中的构造方法:
* String(byte[] bytes); //字节数组转换为字符串
* String(byte[] bytes, int offset, int length);//字节数组一部分转换为字符串,offset:数组的开始索引,length:转换的字节个数
*
* */
public class _04_文件复制案例 {
public static void main(String[] args) throws IOException {
long starts = System.currentTimeMillis();
//创建输出流(写入),输入流(读取)
FileOutputStream fos = new FileOutputStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\1.jpg");
FileInputStream fis = new FileInputStream("E:\\Pictures\\屏保\\人物\\0b7ffd649a35f2a363495f1fd59c2d7d.jpg"); int len = 0 ; //记录有效字节数
byte[] bytes = new byte[1024]; //字节数组块,缓冲作用,提高效率
while((len = fis.read(bytes)) != -1) {
System.out.println(len); //每次数组读写的有效字节字数
fos.write(bytes, 0 , len);
} fis.close();
fos.close();
long ends = System.currentTimeMillis();
System.out.println("复制图片所用时间" + (ends-starts) + "毫秒" );
}
}
/*
* 字符流的使用:在字节输入流中读取中文产生不能一次读多字节的问题引用 字符流
* java.io.Reader;//字符输入流,是字符输入流最顶层的父类,定义了一些共性的成员方法,是一个抽象类
* 共性的成员方法:
* int read();//读取单个字符并返回
* int read(char[] cbuf); //一次读多个字符,将字符读入数组
* void close();//关闭该流,并释放相关系统资源
* java.io.FileReader extends InputStreamReader extends Reader
* FileReader:文件字符输入流
* 作用:硬盘文件数据读入内存
* 构造方法:
* FileReader(String filename);
* FileReader(File file);
* 参数:读取文件的数据源
* String filename:文件路径
* File file:文件
* FileReader构造方法的作用:
* 创建一个FileReader对象
* 会把FileReader对象指向要读取的文件
* 字符输入流的使用步骤
* 创建FileReader对象,参数绑定要读取的数据源
* 使用FileReader对象中的方法read读取文件
* 释放资源
*java.io.Write:字符输出流,所有字符输出流最顶层的父类,一个抽象类
* 共性方法:
* void write (int c) ;//写入单个字符
* void write (char[] cbuf);//写入字符数组
* abstract void write(char[] cbuf, int off, int len);// 写入字符数组的一部分
* void write(String str);//写入字符串
* void write (String str , int off, int len);//写入字符串的一部分
* void flush();//刷新该流的缓冲
* void close();关闭此流,但要先刷新它
* java.io.FileWrite extends OutputStreamWrite extends Write
* FileWrite:文件字符输出流
* 作用:内存字符写入文件
* 构造方法:
* FileWrite(File file);//根据给定的File对象构造一个FileWrite对象
* FileWrite(String filename);//根据给定的文件名构造一个FileWrite对象
* 构造方法的作用:
* 创建一个FileWrite对象
* 根据构造方法中传递的文件/文件路径,创建文件
* 会把FileWrite对象指向创建好的文件
* 字符输出流的使用步骤:
* 创建FileWrite对象,构造方法中绑定写入数据的目的地
* 使用FileWrite中的方法Write,把数据写入内存缓冲区中(字符转换为字节的过程)
* 使用FileWrite中的方法flush,把内存缓冲区中的数据,刷新到文件中
* 释放资源,(先把内存缓冲区中的数据刷新到文件中)
* */
/*
* flush:刷新缓冲区,流对象可以继续使用
* close:刷新缓冲区,通知系统是释放资源,流对象不能再使用
* */
/*
* 续写,换行:使用2个参数的方法
* FileWrite(String filename, boolean append)
* FileWrite(File file, boolean append)
* 参数:append:续写开关,true为续写不创建新文件,falsh创建新文件覆盖源文件
* 换行:
* windows:\r\n
* linux:/n
* mac:/r
* */
public class _08_try_catch_finally处理流异常 {

        public static void main(String[] args) {
FileWriter fw = null;
try{
fw = new FileWriter("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\f.txt");
for (int i = 0; i < 5; i++) {
fw.write("abc\r\n");
fw.flush();
} } catch (IOException e) {
System.out.println(e);
} finally {
if(fw != null) { //增加判断,注:fw=null时不能调用close方法,会抛出空指针异常
try {
fw.close(); //充当flush方法和close方法
} catch (IOException e) {
System.out.println(e);
}
}
}
}
}
/*
* Properties集合 extends Hashtable<k, v> implement Map<k, v>
* Properties类表示一个持久的属性集
* Properties集合是一个唯一和IO流相结合的集合
使用Properties集合中的方法store,把集合中的临时数据持久化的写入硬盘中存储
使用Proterties集合中的方法load,把硬盘文件读取到集合中是使用
操作字符串的特有方法:
Object setProperty(String key, String value);//调用hashtable的方法put
String getProperty(String key);//通过key找value,相当于Map集合中get(key)
Set<String> stringPropertyNames();//返回键集合,该键和对应值是字符串,相当于Map集合keyset方法
注:
属性列表中每个键及其对应值都是字符串
Properties集合是双列集合,key和value默认都是字符串
* */
/*
* store方法:集合中的临时数据持久化的写入硬盘文件
* void store(OutputStream out,String comments);
* void store(Write write,String comments);
* 参数:
* OutputStream out:字节输出流,不能写入中文
* Write write:字符输出流,可以写入中文
* String comments : 注释,解释说明保存的文件,不能使用中文,会产生乱码,一般使用‘’空字符串
* 使用步骤:
* 创建Properties集合对象,添加数据
* 创建字节输出流/字符输出流,参数绑定输出目的地
* 使用Properties集合中的方法store,把集合中的临时数据写入硬盘存储
* 释放资源
* */
/*
* Properties集合中方法load,把硬盘文件读取到j集合中使用
* void load(InputStream instream);
* void load(Reader reader);
* 参数:
* InputStream instream:字节输入流,不能读取含有中文的键
* Reader reader:字符输入流,可以读取含有中文的键
* 使用步骤:
* 创建Properties对象
* 使用Properties对象中的方法load
* 遍历Properties集合
* 注:存储键值对的文件中
* 键值对链接默认使用=,空格
* #进行注释,注释后不能再读取
* 键值对默认为字符串,文件中不加引号
*
* */

_20_缓冲流

/*
* 字节缓冲输入流:给输入流增加一个缓冲区(数组),提高基本输入流的读取效率
* BufferedInputStream(new FileInputStream())
*
*
*java.io.BufferedOutputStream extends OutputStream
* BufferedOutputStream:字节缓冲输出流
* 继承父类共性成员方法:
* public void close();//关闭此输出流并释放与此流相关链的任何系统资源
* public void flush();//刷新此输出流并强制任何缓冲的输出字节被写出
* public void write(byte[] b);//将b.length字节从指定的字节数组写入此输出流
* public void write(byte[] b, int off, int len);//从指定字节数组写入len字节,从偏移量off开始输出到此输出流
* public abstract void write(int b);//将指定的字节输出流
* 构造方法:
* BufferedOutputStream(OutputStream out) ;//创建一个新的缓冲输出流,将数据写入指定的底层输出流
* BufferedOutputStream(OutputStream out,int size) ;//创建一个新的缓冲输出流,将具有指定大小的缓冲数据写入指定的底层输出流
* 参数:
* OutputStream out:字节输出流
* 可传递FileOutputStream,缓冲流h会给FileOutputStream增加一个缓冲区,提高写入效率
* int size:指定缓冲区的大小
* 使用步骤:
* 创建FileOutputStream对象,构造方法中绑定要输出的文件/路径
* 创建BufferedOutputStream对象,构造方法中传递FileOutputStream对象,提高FileOutputStream的效率
* 使用BufferedOutputStream对象中方法write方法,将数据写入缓冲区中
* 使用BufferedOutputStream对象中方法flush方法,将缓冲区数据刷新到文件中
* 释放资源(先调用Flush,后调用close)
*
*java.io.BufferedInputStream extends InputStream
* BufferedInputStream:字节缓冲输入流
* 继承父类共性成员方法:
* int read();//从输入流中读取数据的下一个字节
* int read(byte[] b);//从输入流中读取一定数量的字节,并将其存储到缓冲区数组b中
* void close()//关闭输入流并释放所有相关系统资源
* 构造方法:
* BufferedInputStream(InputStream in) ;//创建一个新的缓冲输入流,将数据写入指定的底层输入流
* BufferedInputStream(InputStream in,int size) ;//创建一个新的缓冲输入流,将具有指定大小的缓冲数据写入指定的底层输入流
* 参数:
* InputStream in:字节输入流
* 可传递FileinputStream,缓冲流h会给FileInputStream增加一个缓冲区,提高读取效率
* int size:指定缓冲区的大小
* 使用步骤:
* 创建FileInputStream对象,构造方法中绑定要输出的文件/路径
* 创建BufferedInputStream对象,构造方法中传递FileInputStream对象,提高FileInputStream的效率
* 使用BufferedInputStream对象中方法read方法,将数据读取到缓冲区中
* 释放资源(先调用Flush,后调用close)
* */
/*
*java.io.BufferedWrite extends Writer
* BufferedWrite:字符缓冲输出流
* 继承父类共性成员方法:
* void write (int c) ;//写入单个字符
* void write (char[] cbuf);//写入字符数组
* abstract void write(char[] cbuf, int off, int len);// 写入字符数组的一部分
* void write(String str);//写入字符串
* void write (String str , int off, int len);//写入字符串的一部分
* void flush();//刷新该流的缓冲
* void close();关闭此流,但要先刷新它
* 构造方法:
* BufferedWrite(Write out) ;//创建一个使用默认大小输出缓冲区的缓冲字符输出流
* BufferedWrite(Write out,int sz) ;//创建一个使用指定大小输出缓冲区的新缓冲字符输出流
* 参数:
* Write out:字符输出流
* 可传递FileWriter,缓冲流会给FileWrite增加一个缓冲区,提高写入效率
* int sz:指定缓冲区的大小
* 特有方法 :
* void newLine();//写入一个行分隔符。根据系统,获取不同的分隔符
* 使用步骤:
* 创建字符缓冲输出流对象,构造方法传递字符输出流
* 调用字符缓冲输出流中方法,write,数据写入到缓冲区
* 调用字符缓冲输出流中flush方法,刷新缓冲区数据到文件
* 释放资源
*
*
*
*java.io.BufferedReader extends Reader
* BufferedReader:字符缓冲输入流
* 继承父类共性成员方法:
* int read();//读取单个字符并返回
* int read(char[] cbuf); //一次读多个字符,将字符读入数组
* void close();//关闭该流,并释放相关系统资源
* 构造方法:
* BufferedReader(Reader in) ;//创建一个默认大小缓冲区的缓冲字符输入流
* BufferedReader(Reader in,int sz) ;//创建一个指定大小输入缓冲区的缓冲字符输入流
* 参数:
* Reader in:字符输入流
* 可传递FileReader,缓冲流会给FileReader增加一个缓冲区,提高读取效率
* int sz:指定缓冲区的大
* 特有方法:
* String readLine();//读取一个文本行,读取一行数据
* 行的终止符:换行\n 回车\r 或者 回车后直接根换行
* 返回值:包含该行内容的字符串,不包含任何终止符,到达流末尾,返回null
* 使用步骤:
* 创建字符缓冲输入流,构造方法中传递基本字符输入流
* 使用字符缓冲输入流中的方法:read/readLine读取文本
* 释放资源
*
*
* */
public class _03_文件编码转换 {
public static void main(String[] args) throws IOException {
InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_20_缓冲流\\UTF-8.txt"), "utf-8");
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_20_缓冲流\\UTF-8转换的gbk文件.txt"), "gbk");
int len = 0 ;
while((len = isr.read()) != -1) {
osw.write(len);
}
isr.close();
osw.close();
}
public class _04_文本内容排序 {
public static void main(String[] args) throws IOException {
HashMap<String, String> hm = new HashMap<>();
BufferedReader br = new BufferedReader(new FileReader("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_20_缓冲流\\in.txt"));
BufferedWriter bw = new BufferedWriter(new FileWriter("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_20_缓冲流\\out.txt"));
String len ;
while((len = br.readLine()) != null) {
String[] arr = len.split("\\.");
hm.put(arr[0] , arr[1] );
}
for(String key : hm.keySet()) {
String value = hm.get(key);
len = key + "." + value;
System.out.println(len);
bw.write(len);
bw.newLine();
}
br.close();
bw.close();
}
}
/*
* 创建hashMap集合,存储key和value(序号,和文本)
* 创建字符输入流使用readLine读取文本
* 创建字符输出流
* 切割文本,获取序号和文本
* 切割好的内容存储到hashMap集合中去
* 遍历hashMap集合,key与value拼接
* 使用字符输出流Write方法写入文本
* 释放资源
* */

_21_转换流

package _01_知识点总结._21_转换流;

public class _01_字符编码和字符集 {
}
/*
* 编码:字符-->字节
* 节码:字节-->字符
* 字符编码:自然语言的字符与二进制数之间的对应规则
* 字符集:编码表。一套字符必须有一套编码。常见:ASCII,GBK,Unicode
* 编码引发的问题:读取编码时的不对应关系产生乱码
*
* java.io.OutputStreamWriter extends Writer
* OutputStreamWriter:字符流通向字节流的通道:使指定charset将要写入流中的字符编码写成字节(能看懂的-->看不懂)
* 继承自父类的共性方法:
* void write (int c) ;//写入单个字符
* void write (char[] cbuf);//写入字符数组
* abstract void write(char[] cbuf, int off, int len);// 写入字符数组的一部分
* void write(String str);//写入字符串
* void write (String str , int off, int len);//写入字符串的一部分
* void flush();//刷新该流的缓冲
* void close();关闭此流,但要先刷新它
* 构造方法:
* OutputStreamWriter(OutputStream out);//创建使用默认编码的OutputStreamWrite
* OutputStreamWrite(OutputStream out,String charsetName);//创建使用指定字符集的OutputStreamWrite
* 参数:
* OutputStream out:字节输出流,可以用来写转换之后的字节到文件中
* String charsetName:指定的编码表名称,不去分大小写,(utf-8 GBK)
* 使用步骤:
* 创建OutputStreamWrite对象,构造方法中传递字节输出流和指定的编码表名称
* 使用OutputStreamWrite对象中的方法Write,把字符转换为字节存储到缓冲区中
* 使用OutputStreamWrite对象中的方法flush方法,把缓冲区数据刷新到文件中
* 释放资源
*
* java.io.InputStreamReader extends Reader
* InputStreamReader:字符流通向字节流的通道:使指定charset读取字节并将其节码为字符(看不懂的-->看懂)
* 继承自父类的共性方法:
* int read();//读取单个字符并返回
* int read(char[] cbuf); //一次读多个字符,将字符读入数组
* void close();//关闭该流,并释放相关系统资源
* 构造方法:
* InputStreamReader(InputStream in);//创建使用默认编码的InputStreamReader
* InputStreamReader(InputStream in,String charsetName);//创建使用指定字符集的InputStreamReader
* 参数:
* InputStream in:字节输入流,读取文件中保存的字节
* String charsetName:指定的编码表名称,不去分大小写,(utf-8 GBK)
* 使用步骤:
* 创建InputStreanReader对象,参数传递字节输入流和z指定的编码表名称
* 使用InputStreamReader中read方法读取文件
* 释放资源
* 注意事项:
* 构造方法中的编码要与文件对应,否则发生乱码
*
* */
package _01_知识点总结._21_转换流;

import java.io.*;

public class _02_转换流 {
public static void main(String[] args) throws IOException {
OutputStreamWriter osw = new OutputStreamWriter(new FileOutputStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_20_缓冲流\\UTF-8.txt"),"utf-8");
osw.write("你好");
osw.close(); OutputStreamWriter osw2 = new OutputStreamWriter(new FileOutputStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_20_缓冲流\\GBK.txt"),"GBK");
osw2.write("你好");
osw2.close(); System.out.println("======================");
InputStreamReader isr = new InputStreamReader(new FileInputStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_20_缓冲流\\GBK.txt"), "gbk");
// int read = isr.read();
// System.out.println(read);
int len = 0 ;
while ((len = isr.read()) != -1) {
System.out.println((char)len);
}
isr.close();
}
}
package _01_知识点总结._21_转换流;

import java.io.*;

public class _03_序列化和反序列化 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_21_转换流\\1.txt"));
oos.writeObject(new _04_Person("张三",18));
oos.close(); System.out.println("===============================");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_21_转换流\\1.txt"));
Object o = ois.readObject();
System.out.println(o);
_04_Person o1 = (_04_Person) o;
System.out.println(o1.getName() + o1.getAge());
}
}
/*
* 对象序列化:把对象以流的方式,写入到文件中保存,叫写对象
* ObjectOutputStream:对象的序列化流
* 对象反序列化:文件中保存的对象以流的f方式读取出来,叫读对象
* ObjectInputStream:对象的反序列化
*
* java.io.ObjectOutputStream extends OutputStream
* ObjectOutputStream:对象的序列化流
* 作用:把对象以流的方式写入文件中保存
* 构造方法:
* ObjectOutputStream(OutputStream out);//创建写入指定OutputStream的ObjectOutputStream
* 参数:
* OutputStream out:字节输出流
* 特有方法:
* void writeObject(Object obj);//将指定对象写入到ObjectOutputStream
* 使用步骤
* 创建ObjectOutputStream对象,参数传递字节输出流
* 使用ObjectOutputStream对象中方法writeObject,把对象写入到文件中
* 释放资源
* 注意事项:
* 序列化和反序列化时,会抛出NotSerializableException 没有序列化对象
* 类通过实现java.io.Serializable接口启动序列化功能,未实现此接口的类无法使用序列化和反序列化
* Serializable也叫标记型接口:
* 进行序列化和反序列化时,必须实现Serializable,就会给l类添加一个标记
* 检测标记Serializable接口:
* 有:进行序列化和反序列化
* 无:抛出NotSerializable异常
*
*
*
* java.io.ObjectInputStream extends InputStream
* ObjectInputStream:对象的反序列化流
* 作用:把对象以流的方式从文件中读出
* 构造方法:
* ObjectInputStream(InputStream in);//创建写入指定InputStream的ObjectInputStream
* 参数:
* InputStream out:字节输入流
* 特有方法:
* void readObject(Object obj);//从ObjectInputStream读取对象
* 使用步骤
* 创建ObjectInputStream对象,参数传递字节输入流
* 使用ObjectInputStream对象中方法readObject,把对象从文件中读出
* 释放资源
* 使用读取出来的对象
* 注意事项:
* readObject方法声明抛出ClassNotFoundException(class文件找不到异常)
* 当不存在对象的class文件时抛出异常
* 反序列化的前提:
* 类必须实现Serializable
* 必须存在类对应的class文件
*
* */
package _01_知识点总结._21_转换流;

public class _05_static和transient关键字 {
}
/*
* static关键字:
* 静态优先于非静态加载到内存中(静态优先于对象进入内存中)
* 被static修饰的成员变量不能被序列化,序列化的都是对象
*transient:瞬态关键字
* 被transient修饰成员变量,不能被序列化
*
* 序列化冲突异常:
* JVM反序列化对象时,能找到class文件,但class文件在序列化对象之后发生修改,反序列化操作就会失败,抛出InvalidClassException异常
* 修改class文件后,文件中的序列号与class中的序列化不一致抛出异常
* 解决方法:
* 定义序列号
* private static final long serialVersionUID = 1L;
* */
package _01_知识点总结._21_转换流;

import java.io.*;
import java.util.ArrayList; public class _06_序列化集合 {
public static void main(String[] args) throws IOException, ClassNotFoundException {
ArrayList<_04_Person> arr = new ArrayList<>();
arr.add(new _04_Person("张三",15));
arr.add(new _04_Person("前朝",18));
arr.add(new _04_Person("万五",13)); ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_21_转换流\\2.txt"));
oos.writeObject(arr); ObjectInputStream ois = new ObjectInputStream(new FileInputStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_21_转换流\\2.txt"));
Object o = ois.readObject(); ArrayList<_04_Person> arrs = (ArrayList<_04_Person>)o;
for (_04_Person i : arrs) {
System.out.println(i);
}
}
}
/*
* 文件中保存多个对象到集合中,对集合进行序列化和反序列化
*
* 定义一个存储Person对象的ArrayList集合
* ArrayList集合中存储Person对象
* 创建序列化流ObjectOutputStream对象 ,使用writeObject方法,对集合进行序列化
* 创建反序列化流ObjectInputStream队形,使用readObject方法,进行反序列化
* 把Object类型转换未ArrayList类型
* 遍历ArrayList集合
* 释放资源
*
* */
package _01_知识点总结._21_转换流;

import java.io.*;

public class _07_打印流 {
public static void main(String[] args) throws FileNotFoundException {
PrintStream ps = new PrintStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_21_转换流\\3.txt");
ps.write(97);
ps.println(97);
ps.println('a');
ps.println("string");
ps.close(); System.out.println("我是控制台输出");
PrintStream ps2 = new PrintStream("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_21_转换流\\4.txt");
System.setOut(ps2); //改变输出目的地
System.out.println("我是输出流缪弟弟输出的内容");
ps2.close();
}
}
/*
* java.io.PrintStream; //打印流
* 特点:
* 只负责数据的输出,不负责数据的读取
* 永远不会抛出IOException
* 有特有的方法 print println
* 构造方法:
* PrintStream(File file);//输出目的地是一个文件
* PrintStream(OutputStream out);//输出目的地是一个字节输出流
* PrintStream(String filename);//输出目的地是一个文件路径
* PrintStream extends OutputStream
* 继承自父类的方法:
* public void close();//关闭此输出流并释放与此流相关链的任何系统资源
* public void flush();//刷新此输出流并强制任何缓冲的输出字节被写出
* public void write(byte[] b);//将b.length字节从指定的字节数组写入此输出流
* public void write(byte[] b, int off, int len);//从指定字节数组写入len字节,从偏移量off开始输出到此输出流
* public abstract void write(int b);//将指定的字节输出流
* 注意事项:
* 使用继承自父类方法write,就会查询编码表UTF-8
* 使用特有方法println,就会输入什么打印什么
*
*
*使用System.setOut方法改变输出语句的目的地
* static void setOut(PrintStream out); //参数传递打印流的目的地
* 默认输出在控制台,使用该方法改变输出目的地为打印流目的地
*
* */

_22_网络编程

package _01_知识点总结._22_网络编程;

public class _01_软件结构 {
}
/*
* C/S结构:客户端/服务器
* B/S结构:浏览器/服务器
* 网络通信协议:
* 位于同一网络链接和通信时需要遵守的规则,数据的传输速率,传输格式,传输步骤。通信双方同时遵守的规则完成数据交换
* TCP/IP协议:传输控制协议/因特网互联协议。定义计算机如何连接网络,以及数据传输标准。包含一系列处理数据通信的协议,采用4层分层模式,每一层呼叫下一层所3
* 提供的协议完成自己的需求
* 应用层:HTTP FTP TFTP SMTP SNMP DNS 负责应用程序的协议
* 传输层:TCP UDP 使用网络程序进行通信
* 网络层:ICMP IGMP IP ARP RARP 网络层时整个TCP/IP的核心,主要用于将传输的数据分组,将分组数据发送到计算机或者网络
* 数据链路层:
* 物理层:由底层网络定义的协议 链路层是用于定义物理传输通道
* 网络通信协议的分类:
* UDP:用户数据报协议。无连接通信协议,即在数据传输时,数据的发送端和接收端不建立逻辑连接
* UDP协议消耗资源小,通信效率高,偶尔 丢失几个数据包,不影响结果
* UDP无连接性,不能保证数据的完整性
* 数据被限制在64kb以内,超出范围不能发送
* 数据报:网络传输的基本单位
* TCP:传输控制协议。面向连接的通信协议,传输数据前发送端和接收端建立逻辑连接,然后传输数据,保证数据无差错
* 三次握手:客户端向服务器,等待服务器来凝结
* 服务器向客户端,通知客户端受到请求
* 客户端向服务器,发送确认信息,确认连接
* 网络编程三要素:
* 协议:计算机网络通信遵守的规则
* IP地址 :互联网协议地址,为网络中计算机设定唯一编号
* IP地址分类:
* IPV4:4字节,32位,a.b.c.d 范围:0~255 42亿至多
* IPV6:16字节,128位,
* 查看本机 IP地址:cmd窗口ipconfig
* 检查网络是否联通:ping IP地址
* 端口号:逻辑端口,用软件查看
* 使用网络软件时,操作系统会给网络软件分配随机端口号,或者网络软件打开时向系统要指定的端口号
* 端口号由两个字节组成,0-65535之间
* 注:
* 1024之前端口号不能使用,已分配给已知的网络软件
* 网络软件的端口号不能重复
* 常用端口号:
* 80端口 http:www.baidu.com:80
* 数据库 mysql:3306 oracle:1521
* Tomcat服务器:8080
* TCP协议:
* 通信步骤:
* 服务器端先启动
* 使用客户端请求服务器端
* 客户端和服务器端建立一个逻辑连接
* 连接中包含的对象IO对象
* 客户端服务器通过IO对象进行通信
* IO对象是字节流
* 客户端:Socket类 服务器端:ServeSocket类
* 客户端于服务器端进行一次数据交互,需要四个IO流对象
* 客户端:OutputStream InputStream
* 服务器端:InputStream OutputStream
* 服务器端注意事项:
* 多客户端与服务器端交互,服务器端accept方法获取请求 的客户端对象
* 服务器没有IO流,通过accept方法 获取客户端队形后使用客户端的流与客户端交互
* */
package _01_知识点总结._22_网络编程;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket; public class _02_TCPClient代码实现 {
public static void main(String[] args) throws IOException {
//创建客户端对象Socket
Socket socket = new Socket("192.168.43.9",6666); OutputStream outputStream = socket.getOutputStream();
outputStream.write("你好服务器".getBytes()); InputStream inputStream = socket.getInputStream(); byte[] bytes = new byte[1024];
int len = 0;
while ((len = inputStream.read(bytes)) != -1) { System.out.println(new String (bytes,0,len));
}
socket.close();
}
}
/*
* 表示客户端的类:
* java.net.Socket;//套接字:两台机器通信的端口 包含了IP地址和端口号的网络单位
* 构造方法:
* Socket(String host, int port)
* 参数:
* String host:服务器主机的名称/服务器的IP地址
* int port :服务器的端口号
* 成员方法:
* OutputStream getOutputStream();//返回此套接字的输出流
* InputStream getInputStream();//返回此套接字的输入流
* void close();//关闭此套接字
* 实现 步骤:
* 创建客户端对象Socket,构造方法绑定服务器IP地址和端口号
* 使用Socket对象getOutputStream()获取网络字节输出流OutputStream对象
* 使用OutputStream队形中方法Write,
* 使用Socket对象getinputStream()获取网络字节输出流InputStream对象
* 使用InputStream队形中方法read,读取服务器会写的数据
* 释放资源(Socket)
* 注意事项:
* 客户端和服务器端进行交互,必须使用Socket中提供的网络流,不能使用自己创建的流对象
* 创建客户端对象Socket时,去请求服务器和服务器进行三次握手连接通路
* 服务器未启动,抛出异常
* 服务器启动,则进行交互
*
* */
package _01_知识点总结._22_网络编程;

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket; public class _03_TCPServe代码实现 {
public static void main(String[] args) throws IOException {
//创建服务器端
ServerSocket serverSocket = new ServerSocket(6666);
Socket accept = serverSocket.accept(); /*InputStream inputStream = accept.getInputStream();
byte[] bytes = new byte[1024];
int len = 0;
while((len = inputStream.read(bytes)) != -1) {
System.out.println(new String(bytes, 0,len));
}*/ OutputStream outputStream = accept.getOutputStream();
outputStream.write("受到,你好客户端01".getBytes()); accept.close();
serverSocket.close();
}
}
/*
* 表示服务器的类:
* java.net.ServerSocket;//此类实现服务器套接字
* 构造方法:
* ServerSocket(int port);
* 参数:特定端口服务器套接字
* 服务器端使用方法accept获取哪个客户端在请求服务端
* c成员方法:
* Socket accept();监听并接收到此套接字的连接
* 服务器使用步骤:
* 创建服务器端ServerSocket对象并和系统要指定端口号
* 使用ServerSocket的方法accept,获取客户端对象Socket
* 使用getOutputStream,获取输出流,使用方法Write向客户端会消息
* 使用getInputStream,获取输入流,使用方法read读取客户端发来的请求
* 释放资源(Socket,ServerSocket)
* */
package _01_知识点总结._22_网络编程;

public class _04_TCP文件上传案例 {
}
/*
* 客户端使用本地字节输入流,读取本地文件
* 客户端使用网络字节输出流,把文件上传到服务器
* 服务器使用网络字节输入流,读取本地上传的文件
* 服务器使用本地 字节输出流,把文件保存到服务器硬盘上
* 服务器使用网络字节输出流,给客户端会写消息,上传成功
* 客户端使用网络字节输入流,读取服务器发来的消息
* 释放资源
*
*
* 注意事项:
* 客户端与服务器进行本地硬盘的读写,使用本地字节流(本地流)
* 客户端与服务器之间进行读写,必须使用Socket提供的字节流对象(网络流 )
*文件上传本质:文件复制
* */
package _01_知识点总结._22_网络编程;

import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket; public class _05_TCPClient案例 {
public static void main(String[] args) throws IOException { FileInputStream fis = new FileInputStream("E:\\Pictures\\屏保\\车辆\\2002012.jpg");//创建本地字节输入流 Socket socket = new Socket("192.168.43.9",5555); //创建Socket对象 OutputStream os = socket.getOutputStream();//获取网络输出流
System.out.println("33333333333333333333333333333333");
byte[] bytes = new byte[1024];
int len = 0;
while((len = fis.read(bytes)) != -1) {
os.write(bytes,0,len);
}
socket.shutdownOutput();//终止上传 InputStream is = socket.getInputStream(); //获取网络输入流
byte[] byte2 = new byte[1024];
int len2 = 0;
while((len2 = is.read(byte2)) != -1) {
System.out.println(new String(byte2));;
} System.out.println("4444444444444444444444444444444444"); fis.close();
socket.close();
}
}
package _01_知识点总结._22_网络编程;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket; public class _06_TCPServer案例 {
public static void main(String[] args) throws IOException { ServerSocket serverSocket = new ServerSocket(5555);//创建服务器对象 while(true) { //服务器始终开启状态
Socket accept = serverSocket.accept(); //获取客户端对象 new Thread(new Runnable() { //多线程,提高文件上传效率
@Override
public void run() {
try{
//判断文件夹是否存在
File file = new File("E:\\IJ 项目练习\\Java 进阶\\02_进阶\\src\\_01_知识点总结\\_22_网络编程\\模拟服务器硬盘");
if(!file.exists()) {
file.mkdirs(); //创建文件夹
} InputStream is = accept.getInputStream();//获取网络输入流 System.out.println("111111111111111111111111111111111111"); //自定义命名规则
String filename = "Zjj" + System.currentTimeMillis() + ".jpg";
FileOutputStream fos = new FileOutputStream(file + "\\" +filename);//创建本地输出流
byte[] bytes = new byte[1024];
int len = 0;
while((len = is.read(bytes)) != -1) {
fos.write(bytes,0,len);
} System.out.println("222222222222222222222222222222222222");
OutputStream os = accept.getOutputStream();
os.write("上传成功".getBytes()); accept.close();
fos.close();
} catch (IOException e) {
System.out.println(e);
}
}
}).start();
} }
}
/*
* 注意事项:
* read方法,读取不到数据会进入死循环状态
* ServerSocket网络输入流read读取不到文件末尾-1,进去死循环
* Socket网络输入流read读取不到服务器消息,进入死循环
* 解决方法:
* 文件读取完毕后,添加方法shutdownOutput();//终止文件的写入,结束文件上传
* */
package _01_知识点总结._22_网络编程;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket; public class _07_模拟BS服务器 {
public static void main(String[] args) throws IOException {
ServerSocket ss = new ServerSocket(8080); while(true){
Socket socket = ss.accept();
new Thread(new Runnable() {
@Override
public void run() {
try{
InputStream is = socket.getInputStream();
/* byte[] bytes = new byte[1024];
int len = 0;
while ( (len = is.read(bytes)) != - 1)
System.out.println(new String(bytes ,0, len)); //GET /WEB/123.htm HTTP/1.1*/ BufferedReader bis = new BufferedReader(new InputStreamReader(is)); // 读取字符流GET /WEB/123.htm HTTP/1.1
String s = bis.readLine();//读取第一行 GET /WEB/123.htm HTTP/1.1
String[] arr = s.split(" ");//空格切割字符串
String htmname = arr[1].substring(1);//切割字符串 获取从数组1开始到结束 FileInputStream fis = new FileInputStream(htmname); //创建本地字节输入流
OutputStream os = socket.getOutputStream();//获取网络输出流 //写入http协议
os.write("HTTP/1.1 200 OK\r\n".getBytes());
os.write("Content - Type:text/html\r\n".getBytes());
os.write("\r\n".getBytes()); byte[] bytes = new byte[1024];
int len =0;
while ((len = fis.read(bytes)) != -1) {
os.write(bytes,0,len);
} fis.close();
socket.close(); }catch(IOException e){
System.out.println(e);
}
}
}).start();
} // fis.close();
// socket.close();
// ss.close();
} }

_23_函数式接口

package _01_知识点总结._23_函数式接口;

@FunctionalInterface
public interface _01_函数实接口的概念 {
public abstract void method();
}
/*
* 函数式接口:有且仅有一个抽象方法的接口(可含有其他方法 默认 静态 私有)
* java中的函数式编程思想体现就是lambda
* 语法糖:指使用更加方便,但是原理不变的代码语法
* (例:遍历集合的for-each,底层实现原理任然是迭代器。java的lambda可作为匿名内部类的语法糖,但二者原理不同)
* 注:lambda表达式没有.class文件,效率比匿名内部类更高
* 格式:
* 修饰符 interface 接口名称 {
* public abstract 返回值类型 方法名称(可选参数信息);
* }
* 函数式接口的注解:@FunctionalInterface
* 检测接口是否时一个函数式接口
* 是:编译成功
* 否:编译失败 (对个抽象方法或没有抽象方法)
*
* */
package _01_知识点总结._23_函数式接口;

@FunctionalInterface
public interface _02_FunctionalFunction {
public abstract void method();
}
/*
* 函数式接口:有且仅有一个抽象方法的接口(可含有其他方法 默认 静态 私有)
* java中的函数式编程思想体现就是lambda
* 语法糖:指使用更加方便,但是原理不变的代码语法
* (例:遍历集合的for-each,底层实现原理任然是迭代器。java的lambda可作为匿名内部类的语法糖,但二者原理不同)
* 格式:
* 修饰符 interface 接口名称 {
* public abstract 返回值类型 方法名称(可选参数信息);
* }
* 函数式接口的注解:@FunctionalInterface
* 检测接口是否时一个函数式接口
* 是:编译成功
* 否:编译失败 (对个抽象方法或没有抽象方法)
*
* */
package _01_知识点总结._23_函数式接口;

public class _03_FunctionalFunctionIMPL implements _02_FunctionalFunction{

    @Override
public void method() {
System.out.println("函数式接口的实现类");
}
}
/*
* 函数式接口:有且仅有一个抽象方法的接口(可含有其他方法 默认 静态 私有)
* java中的函数式编程思想体现就是lambda
* 语法糖:指使用更加方便,但是原理不变的代码语法
* (例:遍历集合的for-each,底层实现原理任然是迭代器。java的lambda可作为匿名内部类的语法糖,但二者原理不同)
* 格式:
* 修饰符 interface 接口名称 {
* public abstract 返回值类型 方法名称(可选参数信息);
* }
* 函数式接口的注解:@FunctionalInterface
* 检测接口是否时一个函数式接口
* 是:编译成功
* 否:编译失败 (对个抽象方法或没有抽象方法)
*
* */
package _01_知识点总结._23_函数式接口;

/*
* 一般作为方法的参数和返回值类型
* */
public class _04_函数式接口的使用 {
//定义方法,参数使用函数式接口
public static void show (_02_FunctionalFunction F) {
F.method();
} public static void main(String[] args) {
//方法的参数是一个接口,所以可以传递接口的实现类对象
show(new _03_FunctionalFunctionIMPL()); show(new _02_FunctionalFunction() {
@Override
public void method() {
System.out.println("函数式接口的匿名参数");
}
}); //匿名方法的lambda表达式
show(() -> System.out.println("函数式接口的匿名参数lambda表达式"));
}
}
package _01_知识点总结._23_函数式接口;

public class _05_lambda延迟特性 {
public static void main(String[] args) { String s1 = "hello ";
String s2 = "word ";
String s3 = "Java"; Show(2, () ->{
System.out. println("不满足不执行字符串凭借");
return s1 + s2 + s3;
});
} private static void Show(int level , _06_MessageBuider messageBuider) {
if(level == 1) {
String s = messageBuider.buiderMessage();
System.out.println(s);
}
}
}
/*
* 注:使用lambda表达式,只是把参数传递给show方法中
* 满足条件,接口_06_才会调用其中方法,返回字符串拼接的参数 输出
* 不满足条件,接口_06_ ,不会执行其中抽象方法,不会执行抽象方法中的代码,即不会的到返回值
* 所以不存在性能浪费的问题
* */
package _01_知识点总结._23_函数式接口;

@FunctionalInterface
public interface _06_MessageBuider {
public abstract String buiderMessage();
}
package _01_知识点总结._23_函数式接口;

public class _07_Runnable函数式方法案例 {
public static void ThreadShow(Runnable run) {
new Thread(run).start();
} public static void main(String[] args) {
ThreadShow(new Runnable() {
@Override
public void run() {
System.out.println(Thread.currentThread().getName() + "线程启用了");
}
}); //注:参数使用lambda表达式的前提是,调用的方法传递参数要求是一个函数式接口
ThreadShow(() -> System.out.println(Thread.currentThread().getName() + "线程启用了")
);
}
}
/*
* 注:
* java.lang.Runnable;//就是一个函数式接口
* 方法参数是一个函数是接口是,传递的参数可以使用lambda表达式,否则不能
* */
package _01_知识点总结._23_函数式接口;

import java.util.Arrays;
import java.util.Comparator; //java.util.Comparator;是一个函数式接口类型
public class _08_函数式接口做返回值类型 {
public static Comparator<String> Compare() {
// return new Comparator<String>() {
// @Override
// public int compare(String o1 , String o2) {
// return o2.length() - o1.length(); //降序排排列
// }
// }; //lambda表达式
return (String o1 , String o2) -> {return o2.length() - o1.length(); };//降序排排列 //使用lambda表达式(极简)作为返回值
// return ( o1 , o2) ->
// o2.length() - o1.length(); //降序排排列 } public static void main(String[] args) {
String[] arr = {"e","bbb","cc","aaaaa","dddd"};
//输出排序前的数组
System.out.println(Arrays.toString(arr));
//调用方法排序
Arrays.sort(arr,Compare());
System.out.println(Arrays.toString(arr));
}
}
package _01_知识点总结._23_函数式接口;

import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier; public class _09_常用的函数式接口 {
public static String getString(Supplier<String> sup ) { // Supplier接口作为参数(函数式接口)
return sup.get();
} public static void method (String name, Consumer<String> consumer) {// Consumer接口作为参数(函数式接口)
consumer.accept(name);
} public static boolean method2 (String s, Predicate<String> pre) {// Predicate接口作为参数(函数式接口)
return pre.test(s);
} public static void methods (String num, Function<String, Integer> fun) { // Function接口作为参数(函数式接口)
Integer apply = fun.apply(num);
System.out.println(apply);
} public static void main(String[] args) {
System.out.println(getString(new Supplier<String>() {
@Override
public String get() {
return "胡歌";
}
}));
String string = getString(() -> {
return "胡歌";
}
);
System.out.println(string); System.out.println("===========================");
method("zhaoliyin", ( name) ->{
// System.out.println(name);
String reverseName = new StringBuffer(name).reverse().toString(); // 字符串翻转
System.out.println(reverseName);
}); System.out.println("=============================");
boolean result = method2("abcd", (s) -> {
boolean b = s.length() > 5;
return b;
});
System.out.println(result); System.out.println("========================");
methods("1234" , (String s)->{
return Integer.parseInt(s); //包装类Integer的拆箱函数
}); }
}
/*
*java.util.function.Supplier<T>接口仅不包含一个无参方法:T get()。用来获取一个泛型参数指定类型的队形数据
* 生产型接口(生产一个数据)
*java.util.Consumer<T>接口与Supplier接口相反,是消耗一个数据
* 抽象方法:void accept(T t);//消费一个指定泛型的数据
*java.util.Predicate<T>接口:对指定泛型的数据进行判断,结果返回一个boolean值
* 抽象方法:boolean(T t);//用来指定泛型数据进行判断
* 符合:返回ture
* 不符合:返回flase
*java.util.function.Function<T,R>;//将T类型数据转换为R类型数据
* 抽象方法:R apply(T t);//
* 例:将String转Integer
*
* */
package _01_知识点总结._23_函数式接口;

import java.util.function.Supplier;

public class _10_Supplier求最大值案例 {
public static int getMax(Supplier<Integer> supplier ) {
return supplier.get();
} public static void main(String[] args) {
int[] arr = { 40, 50 , -10 , 100};
int max1 = getMax(() -> {
int max = arr[0];
for (int i : arr) {
if (i > max) {
max = i;
}
}
return max;
});
System.out.println(max1);
}
}
package _01_知识点总结._23_函数式接口;

import java.util.function.Consumer;

public class _11_Consumer接口中andThen方法 {
public static void method (String name, Consumer<String> consumer, Consumer<String> consumer2) {
// consumer.accept(name);
// consumer2.accept(name);
consumer.andThen(consumer2).accept(name); //andThen方法使用同上两句代码 } public static void main(String[] args) {
method("zhaoliyin", ( name) ->{
// System.out.println(name);
String reverseName = new StringBuffer(name).reverse().toString(); // 字符串翻转
System.out.println(reverseName);
}, (name) ->{
String s = name.toLowerCase();
System.out.println(s); }); /*
* 注:lambda表达式作为参数传递注意事项:
* 是先传递,后执行代码
* 体现了lambda表达式延后执行的特点(提高了代码执行的效率)
* 避免了资源浪费(先执行代码后,没有使用参数,就存在资源的浪费)
* */
}
}
package _01_知识点总结._23_函数式接口;

import java.util.function.Consumer;

public class _12_Consumer接口字符串切割案例 {
public static void method (String[] arr, Consumer<String> con1, Consumer<String> con2) {
for (String message : arr) {
con1.andThen(con2).accept(message);
}
} public static void main(String[] args) {
String[] arr = {"赵丽颖,女","迪丽热巴,女","胡亥,男"};
method(arr,
(s)->{
String[] name = s.split(",");
System.out.print("姓名:" + name[0] + "\t\t\t");
},
(s)->{
String[] name = s.split(",");
System.out.println("年龄:" + name[1]);
}
);
/*
* 注:lambda表达式作为参数传递注意事项:
* 是先传递,后执行代码
* 体现了lambda表达式延后执行的特点(提高了代码执行的效率)
* 避免了资源浪费(先执行代码后,没有使用参数,就存在资源的浪费)
* */ }
}
package _01_知识点总结._23_函数式接口;

import java.util.function.Predicate;

public class _13_Predicate接口中and方法 {
public static boolean method (String s, Predicate<String> pre1, Predicate<String> pre2 ) {
// return pre1.test(s) && pre2.test(s);
return pre1.and(pre2).test(s);
} public static void main(String[] args) {
String s1 = "abcdef"; boolean resulet = method(s1, (String s) -> {
return s.length() > 5;
}, (String s) -> {
return s.contains("a");
});
System.out.println(resulet);
/*
* 注:lambda表达式作为参数传递注意事项:
* 是先传递,后执行代码
* 体现了lambda表达式延后执行的特点(提高了代码执行的效率)
* 避免了资源浪费(先执行代码后,没有使用lambda参数,就存在资源的浪费)
* */ }
}
package _01_知识点总结._23_函数式接口;

import java.util.function.Predicate;

/*
* neagte:结果取反函数 相当于逻辑判读!的意思
* */ public class _14_Predicate接口中or和negate {
public static boolean method (String s, Predicate<String> pre1, Predicate<String> pre2 ) {
// return pre1.test(s) && pre2.test(s);
// return !pre1.or(pre2).test(s); // 整体结果取反
return pre1.negate().test(s) || pre2.test(s); // pre1结果取反
} public static void main(String[] args) {
String s1 = "abcdef"; boolean resulet = method(s1, (String s) -> {
return s.length() > 5;
}, (String s) -> {
return s.contains("a");
});
System.out.println(resulet);
/*
* 注:lambda表达式作为参数传递注意事项:
* 是先传递,后执行代码
* 体现了lambda表达式延后执行的特点(提高了代码执行的效率)
* 避免了资源浪费(先执行代码后,没有使用lambda参数,就存在资源的浪费)
* */ }
}
package _01_知识点总结._23_函数式接口;

import java.util.ArrayList;
import java.util.function.Consumer;
import java.util.function.Predicate; public class _14_Predicate接口筛选案例 {
public static ArrayList<String> method (String[] arr, Predicate<String> con1, Predicate<String> con2) {
ArrayList<String> arrayList = new ArrayList<>();
for (String s : arr) {
boolean test = con1.and(con2).test(s);
if(test == true) {
arrayList.add(s);
}
}
return arrayList; } public static void main(String[] args) {
String[] arr = {"赵丽颖,女","迪丽热巴,女","胡亥,男"};
ArrayList<String> arrayResult = method(arr,
(String s) -> {
String[] sex = s.split(",");
if (sex[1].equals("女")) {
return true;
} else {
return false;
}
},
(String s) -> {
return s.split(",")[0].length() == 4;
}
); for (String s : arrayResult) {
String[] message = s.split(",");
System.out.println("姓名:" + message[0] + "\t年龄:" + message[1]);
}
/*
* 注:lambda表达式作为参数传递注意事项:
* 是先传递,后执行代码
* 体现了lambda表达式延后执行的特点(提高了代码执行的效率)
* 避免了资源浪费(先执行代码后,没有使用参数,就存在资源的浪费)
* */ }
}
package _01_知识点总结._23_函数式接口;

import java.util.function.Function;

public class _15_Function接口andThen方法 {
public static void methods (String num, Function<String, Integer> fun1 , Function< Integer,String> fun2) { // Function接口作为参数(函数式接口)
String s = fun1.andThen(fun2).apply(num);
System.out.println(s);
} public static void main(String[] args) {
methods("1234" , (String s)->{
return Integer.parseInt(s) +10; //包装类Integer的拆箱函数
} ,(Integer s)->{
return s + "";
}); }
}
package _01_知识点总结._23_函数式接口;

import java.util.function.Function;

public class _16_Function接口案例 {
public static void methods (String num, Function<String, String> fun1 , Function< String ,Integer> fun2,
Function< Integer,Integer> fun3) { // Function接口作为参数(函数式接口)
Integer numResult = fun1.andThen(fun2).andThen(fun3).apply(num);
System.out.println(numResult);
} public static void main(String[] args) {
methods("照例因,1234" , (String s)->{
return s.split(",")[1]; //包装类Integer的拆箱函数
} ,(String string)->{
return Integer.parseInt(string);
}, (Integer integer)-> {
return integer + 100;
}); }
}

_24_Stream流

package _01_知识点总结._24_Stream流;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.List; public class _01_传统方式遍历集合 {
public static void main(String[] args) {
ArrayList<String> lists = new ArrayList<>();
lists.add("张三丰");
lists.add("张无极");
lists.add("张和");
lists.add("利斯峰");
lists.add("毛开往"); ArrayList<String> list2 = new ArrayList<>();
for (String list : lists) {
if (list.startsWith("张")) {
list2.add(list);
}
} ArrayList<String> list3 = new ArrayList<>();
for (String s : list2) {
if(s.length() == 3)
list3.add(s);
} for (String s : list3) {
System.out.println(s);
}
}
}
package _01_知识点总结._24_Stream流;

import java.util.ArrayList;

public class _02_Stream流方式遍历集合 {
public static void main(String[] args) {
ArrayList<String> lists = new ArrayList<>();
lists.add("张三丰");
lists.add("张无极");
lists.add("张和");
lists.add("利斯峰");
lists.add("毛开往"); lists.stream().filter( name -> name.startsWith("张"))
.filter(name -> name.length() == 3 )
.forEach(name -> System.out.println(name));
}
}
package _01_知识点总结._24_Stream流;

import java.util.*;
import java.util.stream.Stream; public class _03_获取Stream的方式 {
public static void main(String[] args) {
List<String> list = new ArrayList<>();//ArrayList集合转换为Stream流
Stream<String> listStream = list.stream(); Set<String> set = new HashSet<>(); //HashSet集合转换为Stream流
Stream<String> setStream = set.stream(); Map<String, String> map = new HashMap<>();
Set<String> mapSet = map.keySet(); //Map集合key的Set集合转换为Stream流
Stream<String> mapSetStream = mapSet.stream(); Collection<String> values = map.values(); //Map集合value的Collection集合转换为Stream流
Stream<String> mapValuesStream = values.stream(); Set<Map.Entry<String, String>> entries = map.entrySet(); //Map集合映射关系的Set集合转换为Stream流
Stream<Map.Entry<String, String>> mapEntriesStream = entries.stream(); Integer[] integers = {1, 2, 3, 4}; //可变参数转换为Stream流
Stream<Integer> integers1Stream = Stream.of(integers); String[] strings = {"a","abc","dd"};
Stream<String> strings1Stream = Stream.of(strings); Stream<Integer> integerStream = Stream.of(1, 2, 3); //数组转换为Stream对象
}
}
/*
* 使用一个流的三个基本步骤:
* 获取一个数据源
* 数据转换
* 执行操作获取想要的结果
*
* 获取流的两种方式:
* java.util.stream.Stream<T>是java 最常用的流接口(不是函数式接口)
* 两种方式:
* 所有Collection集合都可以通过stream默认方法获取
* default stream<E> stream()
* Stream接口的静态方法of可以获取数组对应的流
* static<T> Stream<T> of (T……values)
*
* */
package _01_知识点总结._24_Stream流;

import java.util.ArrayList;
import java.util.stream.Stream; public class _04_Stream流中foreach {
public static void main(String[] args) {
System.out.println("================================");
// Stream<String> stringStream = Stream.of("张三","赵六","王五"); // stringStream.forEach((name) -> { //遍历流中的数据 forEach
// System.out.println(name);
// }); System.out.println("================================");
// Stream<String> streamFilter = stringStream.filter(name -> name.startsWith("张"));//过滤流中的数据 filter
// streamFilter.forEach(name -> System.out.println(name)); // System.out.println("================================");
// Stream<String> stringStream1 = Stream.of("1", "2", "3"); //转换流中的数据类型 map方法
// Stream<Integer> integerStream = stringStream1.map((String s) -> {
// return Integer.parseInt(s);
// });
// integerStream.forEach(i -> System.out.println(i)); // System.out.println("================================");
// ArrayList<Integer> arrayList = new ArrayList<>();
// arrayList.add(1);
// arrayList.add(2);
// arrayList.add(3);
// arrayList.add(4);
// Stream<Integer> stream = arrayList.stream();
// long count = stream.count(); //统计流中的数据个数 count方法
// System.out.println(count); System.out.println("================================");
String[] array = new String[3];
array[0] = "zhang";
array[1] = "an";
array[2] = "ke";
Stream<String> array1 = Stream.of(array);
// Stream<String> limit = array1.limit(2); //截取流中前n个的数据 limit方法
// limit.forEach(s -> System.out.println(s));
// Stream<String> skip = array1.skip(1); //跳过流中前n个的数据 skip方法
// skip.forEach(s -> System.out.println(s)); String[] array2 = new String[3];
array[0] = "zhang";
array[1] = "an";
array[2] = "ke";
Stream<String> array3 = Stream.of(array);
Stream<String> concat = Stream.concat(array1, array3);//连接Stream流 concat方法
concat.forEach(s -> System.out.println(s)); }
}
/*
* Stream流中for each方法
* void forEach(Consumer<? super T> action);
* 注:foreach方法遍历流中的数据
* 是一个终结方法,遍历后不能再使用Stream流中其他方法
* 注:延迟方法:返回值类类型是Stream接口自身类型的方法,支持链式调用
* 终结方法:返回值类型不是Stream接口自身类型的方法,(count forEach 除此均为延迟方法)
* Stream管道流的特点:
* 属于管道流,只能使用一次
* */
package _01_知识点总结._24_Stream流;

import java.util.ArrayList;

/*
* 集合元素处理:
* 两个ArrayList集合,存储多个名字,
* 集合一:名字3个字,到新集合
* 集合一:筛选前2个,到新集合
* 集合二:姓张的,到新集合
* 集合二:不要前2,到新集合
* 集合一二筛选后的合并到新集合
* 根据姓名创建person对象到新集合
* 打印person集合
* */
public class _05_传统方式筛选集合案例 {
public static void main(String[] args) {
ArrayList<String> array1 = new ArrayList<>();
array1.add("张三丰");
array1.add("胡海阁");
array1.add("罗宾和");
array1.add("王益");
array1.add("太祖风");
array1.add("张婵"); ArrayList<String> array11 = new ArrayList<>();
for (String i : array1) {
if(i.length()==3) {
array11.add(i);
}
} ArrayList<String> array12 = new ArrayList<>();
for (int i = 0; i < 2; i++) {
array12.add(array11.get(i));
} System.out.println("================================");
ArrayList<String> array2 = new ArrayList<>();
array2.add("张三丰");
array2.add("胡海阁");
array2.add("罗宾和");
array2.add("王益");
array2.add("太祖风");
array2.add("张婵");
array2.add("张无忌"); ArrayList<String> array21 = new ArrayList<>();
for (String s : array2) {
if(s.startsWith("张")) {
array21.add(s);
}
} ArrayList<String> array22 = new ArrayList<>();
for (int i = 2; i < array21.size(); i++) {
array22.add(array21.get(i));
} ArrayList<String> array = new ArrayList<>();
array.addAll(array12);
array.addAll(array22); ArrayList<Person> arrayPerson = new ArrayList<>();
for (String s : array) {
arrayPerson.add(new Person(s));
} for (Person person : arrayPerson) {
System.out.println(person);
} }
}
package _01_知识点总结._24_Stream流;

import java.util.ArrayList;
import java.util.stream.Stream; /*
* 集合元素处理:
* 两个ArrayList集合,存储多个名字,
* 集合一:名字3个字,到新集合
* 集合一:筛选前2个,到新集合
* 集合二:姓张的,到新集合
* 集合二:不要前2,到新集合
* 集合一二筛选后的合并到新集合
* 根据姓名创建person对象到新集合
* 打印person集合
* */
public class _06_Stream流筛选集合案例 {
public static void main(String[] args) {
ArrayList<String> array1 = new ArrayList<>();
array1.add("张三丰");
array1.add("胡海阁");
array1.add("罗宾和");
array1.add("王益");
array1.add("太祖风");
array1.add("张婵"); Stream<String> stream11 = array1.stream().filter(name -> name.length() == 3).limit(2); System.out.println("================================");
ArrayList<String> array2 = new ArrayList<>();
array2.add("张三丰");
array2.add("胡海阁");
array2.add("罗宾和");
array2.add("王益");
array2.add("太祖风");
array2.add("张婵");
array2.add("张无忌"); Stream<String> stream22 = array2.stream().filter(name -> name.startsWith("张")).skip(2); Stream.concat(stream11, stream22).map(name -> new Person(name)).forEach(p -> System.out.println(p)); }
}

_25_方法引用

package _01_知识点总结._25_方法引用;

public class _01_方法引用概述 {
public static void printString (Printable p) {
p.print("hello");
} public static void main(String[] args) {
printString(s -> System.out.println(s)); printString(System.out::println); //引用方法替代lambda表达式,两者效果相同
}
}
/*
* 方法引用符:
* :: 它所表达的表达式称方法引用,
* 使用条件:如果lambda要表达的函数方案已经存在于某个方法的实现中,则可以使用::来引用该方法作为lambda的替代
* 语义分析:
* 第一种:拿到参数后经lambda之手,继而传递给System.out.println方法处理
* 第二种:让System.out中println方法来取代lambda,
* */
package _01_知识点总结._25_方法引用;

public class _02_通过对象引用成员方法 {
public static void printString (Printable p) { //方法使用函数式接口
p.print("heool");
} public static void main(String[] args) {
// printString((String s)-> { //参数为函数式接口,所以可以使用lambda表达式
// RerObject rerObject = new RerObject();
// rerObject.method(s); //通过对象调用引用方法
// }); //方法引用优化lambda表达式
/*
* 使用方法引用前提:
* 对象已经存在RerObject
* 成员方法也是已经存在的method
* 所以可以使用对象名引用成员方法
* */
RerObject rerObject = new RerObject();
printString(rerObject::method);
}
}
package _01_知识点总结._25_方法引用;

public class _03_通过类名引用静态方法 {
public static void printMethod(int num, Calcable c) {
int calcable = c.calcable(num);
System.out.println(calcable);
} public static void main(String[] args) {
printMethod(-10, (int num)->{
return Math.abs(num);
}); /*
* Math类已经存在
* abs静态方法已经存在
* 可以通过类名引用静态方法
* */
printMethod(-10,Math::abs);
}
}
package _01_知识点总结._25_方法引用;

public class _04_通过super引用父类成员方法 {
}
package _01_知识点总结._25_方法引用;

public class _05_类的构造器 {
public static void method (String name, BuliderName bn) {
Person s = bn.buliderName(name);
System.out.println(s);
} public static void main(String[] args) {
method("迪丽热巴",(String name)->{
Person person = new Person(name);
return person;
}); /*
* 构造方法new Person(String name); 已知
* 对象new已知
* 使用Person引用new创建对象
* */
method("鼓励拉闸",Person::new);
}
}
package _01_知识点总结._25_方法引用;

public class _06_数组的构造器引用 {
public static int[] method(int len , Array a) {
int[] ints = a.buildArray(len);
return ints;
} public static void main(String[] args) {
int[] array = method(10, (int l) -> {
return new int[l];
});
System.out.println(array.length);
System.out.println(
method(11,int[]::new).length
);
}
}

END

00_java进阶笔记的更多相关文章

  1. Angularjs进阶笔记(2)-自定义指令中的数据绑定

    有关自定义指令的scope参数,网上很多文章都在讲这3种绑定方式实现的效果是什么,但几乎没有人讲到底怎么使用,本篇希望聊聊到底怎么用这个话题. 一. 自定义指令 自定义指令,是Angularjs用来实 ...

  2. javascript进阶笔记(2)

    js是一门函数式语言,因为js的强大威力依赖于是否将其作为函数式语言进行使用.在js中,我们通常要大量使用函数式编程风格.函数式编程专注于:少而精.通常无副作用.将函数作为程序代码的基础构件块. 在函 ...

  3. Android进阶笔记:Messenger源码详解

    Messenger可以理解为一个是用于发送消息的一个类用法也很多,这里主要分析一下再跨进程的情况下Messenger的实现流程与源码分析.相信结合前面两篇关于aidl解析文章能够更好的对aidl有一个 ...

  4. Android进阶笔记:AIDL内部实现详解 (二)

    接着上一篇分析的aidl的流程解析.知道了aidl主要就是利用Ibinder来实现跨进程通信的.既然是通过对Binder各种方法的封装,那也可以不使用aidl自己通过Binder来实现跨进程通讯.那么 ...

  5. javascript进阶笔记(1)

    学习js已经有一段时间了,大大小小还是能够做出一些东西来.不过觉得可惜的是,还是对js本身这门语言不是很熟悉,总有一点雾里看花的感觉,看得见,但是看不清楚.最近发现有一本关于js的叫做<忍者秘籍 ...

  6. object - c 语言基础 进阶笔记 随笔笔记

    重点知识Engadget(瘾科技)StackOverFlow(栈溢出)Code4Apprespon魏先宇的程序人生第一周快捷键: Alt+上方向键 跳到最上面  Alt+下方向键 跳到最下面      ...

  7. python进阶笔记 thread 和 threading模块学习

    Python通过两个标准库thread和threading提供对线程的支持.thread提供了低级别的.原始的线程以及一个简单的锁.threading基于Java的线程模型设计.锁(Lock)和条件变 ...

  8. Android进阶笔记20:Android手机屏幕坐标系

    1. 手机屏幕坐标系: 整个坐标系是以手机屏幕左上角为原点(0,0),如下:

  9. Android进阶笔记19:onInterceptTouchEvent、onTouchEvent与onTouch

    1.onTouch方法:onTouch方法是View的 OnTouchListener借口中定义的方法,处理View及其子类被touch是的事件处理.当一个View绑定了OnTouchLister后, ...

  10. Android进阶笔记18:选用合适的IPC方式

    1. 相信大家都知道Android进程间通信方式很多,比如AIDL.Messenger等等,接下来我就总结一下这些IPC方式优缺点. 2. IPC方式的优缺点和适用场景 3. 附加:使用Intent实 ...

随机推荐

  1. Hadoop详解(05) – MapReduce

    Hadoop详解(05) – MapReduce MapReduce概述 定义 MapReduce是一个分布式运算程序的编程框架,是用户 "基于Hadoop的数据分析应用" 开发的 ...

  2. Siri Shortcut

      AppDelegate.m         //#pragma mark - INUIAddVoiceShortcutButtonDelegate //新添加 - (void)presentAdd ...

  3. Docker 基础 - 1

    镜像 获取镜像 docker pull 查看镜像信息 docker images docker inspect <images id> # 获取镜像的详细信息 搜寻镜像 docker se ...

  4. JS循环类数组对象,获得页面所有的某个ClssaName,处理它的属性

    举例:获得所有的某个ClssaName,处理它的第一个子元素中的title赋值给内容 let links = Array.from(document.getElementsByClassName('m ...

  5. 修改hosts文件需要vi命令

    i 在光标前插入. 保存 按esc后 shift+: 输入wq! 保存

  6. java入门与进阶P-2.3

    判断 if语句 一个基本的if语句由一个关键字if开头,跟上在括号里的表示条件的逻辑表达式, 然后是一对大括号"{}"之间的若干条语句.如果表示条件的逻辑表达式的结果为true,那 ...

  7. Map集合概述-Map常用子类

    Map集合概述 现实生活中,我们常会看到这样的一种集合︰IP地址与主机名,身份证号与个人,系统用户名与系统用户对象等,这种--对应的关系,就叫做映射.Java提供了专门的集合类用来存放这种对象关系的对 ...

  8. 玩转web3第二篇——Web3UI Kit

    介绍 开发web2应用的时候,可以很方便找到很多优秀的UI库,比如antd,material ui,element ui等等,但web3应用对应的UI库却不多. 今天给大家介绍一款优秀的WEB3的UI ...

  9. 二、typora软件的安装与markdown语法

    目录 一.typora软件的安装与使用 1.软件的安装 2.破解使用的方法 3.功能描述(markdown语法讲解) 标题 小标题 语言环境 表格 表情 图片 查看源代码 数学公式 流程图 高亮文本 ...

  10. PX4源码地址和wiki

    [源码] https://github.com/987419640/Firmware [wiki] https://dev.px4.io/v1.9.0/zh/concept/architecture. ...