Java应用程序
约 9820 字大约 33 分钟
(1)字符串
1. 创建字符串
package model3.unit1;
public class Java01 {
public static void main(String[] args) {
// 创建字符串的方式和区别
// 通过字面值直接赋值的方式:推荐
// 优点:简洁。
// 原理:会先检查内存中是否存在、如果有则直接返回如果没有再创建新的。
String s1 = "张三";
String s2 = "张三";
System.out.println(s1 == s2); // true
// 通过new关键字创建:不推荐
// 原理:每次都会创建新的字符串。
String s3 = new String("李四");
String s4 = new String("李四");
System.out.println(s3 == s4); // false
}
}
2. 字符串的本质
package model3.unit1;
public class Java03 {
public static void main(String[] args) {
// 字符串的本质是字符数组(注意:1.8)
// String本质:char[]
String a = "abcde";
char[] b = {'a', 'b', 'c', 'd', 'e'};
// 以char[]为构造参数创建字符串
String c = new String(b);
System.out.println(c);
// 根据下标返回对应的字符
char d = a.charAt(2);
System.out.println(d); // 'c'
// 查找字符串、如果找到返回起始下标、如果找不到返回-1
int e = a.indexOf("张四");
System.out.println(e); // -1
}
}
3. 字符串常用方法
package model3.unit1;
public class Java04 {
public static void main(String[] args) {
// 字符串常用方法
// 长度
int a = "abcde".length();
System.out.println(a); // 5
// 截取
String b = "abcde".substring(2);
System.out.println(b); // "cde"
// 截取
String c = "abcde".substring(1, 4);
System.out.println(c); // "bcd"
// 去除空格
String d = " abc ".trim();
System.out.println(d); // "abc"
}
}
package model3.unit1;
public class Java05 {
public static void main(String[] args) {
// 字符串常用方法
// 大写
String a = "abcDE".toUpperCase();
System.out.println(a); // "ABCDE"
// 小写
String b = "BbC".toLowerCase();
System.out.println(b); // "bbc"
// 不区分大小写相等
boolean c = "aBc".equals("Abc");
boolean d = "aBc".equalsIgnoreCase("Abc");
System.out.println(c); // false
System.out.println(d); // true
// 判断开头
boolean e = "abcd".startsWith("ab");
System.out.println(e); // true
// 判断结尾
boolean f = "abcde".endsWith("de");
System.out.println(f); // true
}
}
package model3.unit1;
public class Java06 {
public static void main(String[] args) {
// 字符串常用方法
// 是否包含
boolean a = "abc".conTAIns("bc");
System.out.println(a); // true
// 替换
String b = "abcabcabc".replaceAll("b", "张三");
System.out.println(b); // "张三张三张三张三张三"
// 判断空字符串
boolean c = "".isEmpty();
System.out.println(c); // true
// 字符串转换char[]
char[] d = "abcde".toCharArray();
for (char x : d) {
System.out.println(x);
}
// 分割字符串
String[] arr = "张三,李四,王五".split(",");
for (String n : arr) {
System.out.println(n);
}
}
}
4. 字符串方法注意
package model3.unit1;
import java.lang.String;
public class Java08 {
public static void main(String[] args) {
// 字符串的方法都是返回一个新的字符串、而不是在原字符串中进行修改。
String a = "abcde";
String b = a.substring(0);
System.out.println(a.hashCode());
System.out.println(b.hashCode()); // 相同的哈希码
String c = a.toUpperCase();
System.out.println(c.hashCode()); // 不同的哈希码
System.out.println(a); // "abcde"
System.out.println(b); // "abcde"
System.out.println(c); // "ABCDE"
String d = a.replaceAll("a", "123");
System.out.println(d); // "123bcde"
System.out.println(d.hashCode()); // 另一个不同的哈希码
}
}
5. 字符串常量池
package unit2;
public class Java13 {
public static void main(String[] args) {
// 字符串常量池
// 是JVM为了提升性能针对字符串专门开辟的一个区域
// 目的为了避免创建重复的字符串对象
String s1 = "abc";
String s2 = "abc";
System.out.println(s1 == s2);
String s3 = new String("abc");
String s4 = new String("abc");
System.out.println(s3 == s4);
System.out.println(s1 == s3);
System.out.println(s1.equals(s3));
// 题:创建了几个字符串对象
String s5 = "你好";
String s6 = new String("你好");
}
}
6. 字符串的+运算符
package unit2;
public class Java14 {
public static void main(String[] args) {
// 字符串的+运算符
// 连接的意思、和其它类型使用会先把其它类型自动转换为字符串再进行连接
String s1 = "a";
String s2 = "b";
String s3 = s1 + s2; // 变量引用不会从字符串池中查找
String s4 = "a" + "b"; // 字面值+连接、java优化为String s4 = "ab";
String s5 = "ab";
System.out.println(s3 == s4); // false,因为s3和s4引用不同的对象
System.out.println(s3 == s5); // true
System.out.println(s4 == s5); // true
}
}
7. 字符串的+底层原理
package unit2;
import java.lang.StringBuilder;
public class Java15 {
public static void main(String[] args) {
// 字符串拼接+的底层原理
// String字符串+使用
String s1 = "ab";
String s2 = "cd";
String s3 = s1 + s2;
System.out.println(s3);
// String字符串+使用的底层原理
// jdk8问题:会产生大量的StringBuilder临时对象
// jdk9解决这个问题:通过一个动态方法解决这个问题了。9以后可以放心使用!
StringBuilder a = new StringBuilder("ab");
StringBuilder b = new StringBuilder("cd");
// 字符串a连接字符串b
String s = a.append(b).toString();
System.out.println(s);
}
}
(2)日期
1. 现在日期时间
package model3.unit2;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class Java01 {
public static void main(String[] args) {
// 获取当前日期
LocalDate a = LocalDate.now();
System.out.println("当前日期: " + a);
// 获取当前时间
LocalTime b = LocalTime.now();
System.out.println("当前时间: " + b);
// 获取当前日期时间
LocalDateTime c = LocalDateTime.now();
System.out.println("当前日期时间: " + c);
}
}
2. 指定日期时间
package model3.unit2;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class Java02 {
public static void main(String[] args) {
// 创建指定日期
LocalDate a = LocalDate.of(2016, 4, 15);
System.out.println("指定日期: " + a);
// 创建指定时间
LocalTime b = LocalTime.of(11, 34, 56);
System.out.println("指定时间: " + b);
// 创建指定日期时间
LocalDateTime c = LocalDateTime.of(2018, 8, 8, 10, 10, 10);
System.out.println("指定日期时间: " + c);
}
}
3. 日期字符串转换
package model3.unit2;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
public class Java03 {
public static void main(String[] args) {
// 字符串转换为日期类型
// 字符串转换日期
String a = "2023-05-30";
LocalDate b = LocalDate.parse(a);
System.out.println("字符串转日期: " + b);
// 字符串转换时间
String c = "14:03:34.429";
LocalTime d = LocalTime.parse(c);
System.out.println("字符串转时间: " + d);
// 字符串转换日期时间
String e = "2023-05-30T14:01:14";
LocalDateTime f = LocalDateTime.parse(e);
System.out.println("字符串转日期时间: " + f);
System.out.println("格式化日期时间: " + f.toString());
}
}
4. 日期计算
package unit4;
import java.time.format.DateTimeFormatter;
import java.util.Date;
import java.text.SimpleDateFormat;
import java.time.LocalDateTime;
public class Java32 {
public static void main(String[] args) {
// 使用 java.util.Date 进行日期计算
Date date = new Date();
// 增加10天
date.setTime(date.getTime() + (10 * 24 * 60 * 60 * 1000L));
SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
System.out.println("计算后的日期: " + simpleDateFormat.format(date));
}
}
(3)封装类
1. 基本类型的封装类
package model3.unit3;
public class Java01 {
public static void main(String[] args) {
// 封装类:八种基本数据类型对应的类类型
// 基本类型 封装类
// byte Byte
// short Short
// int Integer
// long Long
// float Float
// double Double
// boolean Boolean
// char Character
// 装箱拆箱原理
// 装箱:基本数据类型自动转换为引用类型包装类
// 拆箱:包装类自动转换为基本数据类型
int a = 2;
Integer b = Integer.valueOf(a); // 装箱
int c = b.intValue(); // 拆箱
}
}
2. 字符串转换基本类型
package model3.unit3;
public class Java02 {
public static void main(String[] args) {
// 封装类的作用
// 1. 基本类型中只存储数据。封装类不但能存储数据还提供方法。
// 2. java中的集合中只能存储类类型、不能存储基本数据类型。
// 建议使用封装类。
// Integer数据区间
// System.out.println(Integer.MIN_VALUE);
// System.out.println(Integer.MAX_VALUE);
// 字符串转换为整数
String a = "100";
int b = Integer.parseInt(a);
System.out.println(b);
double c = Double.parseDouble(a);
System.out.println(c);
}
}
3. 包装类的缓存机制
package unit2;
public class Java11 {
public static void main(String[] args) {
// 包装类的缓存机制
// 有缓存机制的有:每次使用会先从缓存中查找数据、如果存在则直接返回
// Byte、Short、Integer、Long、Boolean、Character
// 注意坑:整数只对[-128, 127]区间的数字有缓存机制
// 注意坑:字符只对[0, 127]区间的字符有缓存机制。128个字符
// 没有缓存机制的有:每次使用都会创建一个新的对象
// Float、Double
Integer a = 1000;
Integer b = 1000;
System.out.println(a == b);
Boolean c = true;
Boolean d = true;
System.out.println(c == d);
Character e = '你';
Character f = '你';
System.out.println(e == f);
Double g = 1.5;
Double h = 1.5;
System.out.println(g == h);
}
}
4. 自动装箱的坑
package unit2;
public class Java12 {
public static void main(String[] args) {
// 自动装箱拆箱的坑
// 注意:缓存只针对于字面值
Integer a = 3;
Integer b = new Integer(3); // new创建一个新的对象、分配一个新的内存地址
System.out.println(a == b); // false
Integer c = 1000;
Integer d = 1000;
Integer e = 100;
Integer f = 100;
System.out.println(c == d); // false,因为1000不在-128,127的范围内
System.out.println(e == f); // true
}
}
(4)集合
1. ArrayList
package model3.unit4;
import java.util.ArrayList;
import java.util.List;
public class Java01 {
public static void main(String[] args) {
// List接口:有序集合:添加的顺序和遍历的顺序一致
// ArrayList实现类
// 创建集合
// 注意:强烈建议使用泛型:规定集合中存储数据的具体类型
List<String> list = new ArrayList<>();
// 添加对象
list.add("aaa");
list.add("bbb");
list.add("ccc");
// 遍历集合
for (String s : list) {
System.out.println(s);
}
}
}
2. 集合和数组的区别
package model3.unit4;
import java.util.ArrayList;
import java.util.List;
public class Java02 {
public static void main(String[] args) {
// 集合和数组的区别
// 区别一:数组固定长度。集合动态长度。
// 区别二:数组任何类型都可以存储的。集合只能存储类类型。
List<Integer> list = new ArrayList<>();
// 集合中添加基本数据类型的时候、底层自动装箱原理
list.add(1);
list.add(2);
list.add(3);
// 集合中获取数据的时候、底层自动拆箱原理
for (int i : list) {
System.out.println(i);
}
}
}
3. HashSet
package model3.unit4;
import java.util.HashSet;
import java.util.Set;
public class Java03 {
public static void main(String[] args) {
// Set集合:不重复集合:如果添加的对象已经存在则不重复添加
// HashSet实现类
Set<String> set = new HashSet<>();
set.add("a");
set.add("a");
set.add("a");
for (String s : set) {
System.out.println(s);
}
}
}
4. LinkedList
package model3.unit4;
import java.util.LinkedList;
import java.util.List;
public class Java04 {
public static void main(String[] args) {
// List接口
// LinkedList实现类
// ArrayList和LinkedList区别
// ArrayList底层是用数组实现的。遍历快、增删慢。
// LinkedList底层是用链表实现的。遍历慢、增删快。
List<String> list = new LinkedList<>();
list.add("aa");
list.add("bb");
list.add("cc");
for (String s : list) {
System.out.println(s);
}
}
}
5. TreeSet
package model3.unit4;
import java.util.Set;
import java.util.TreeSet;
public class Java05 {
public static void main(String[] args) {
// Set接口
// TreeSet实现类
// HashSet和TreeSet区别
// HashSet:不重复
// TreeSet:不重复 + 排序
Set<Integer> set = new TreeSet<>();
set.add(2);
set.add(5);
set.add(4);
set.add(5);
set.add(2);
for (int i : set) {
System.out.println(i);
}
}
}
6. HashMap
package model3.unit4;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
public class Java06 {
public static void main(String[] args) {
// Map接口
// HashMap实现类
// 键值对的存储结构(要求:key必须唯一)
// 键 值
// key -> value
// 创建map
Map<Integer, String> map = new HashMap<>();
// 添加键值对
map.put(1, "张三");
map.put(2, "李四");
map.put(3, "王五");
// 根据key获取value的方法
// String s = map.get(2);
// System.out.println(s);
// 遍历map集合
Set<Integer> set = map.keySet();
for (int key : set) {
System.out.println(key + " " + map.get(key));
}
}
}
7. TreeMap
package model3.unit4;
import java.util.Map;
import java.util.TreeMap;
public class Java07 {
public static void main(String[] args) {
// Map接口
// TreeMap实现类:键值对的存储结构。按照key排序。
Map<Integer, String> map = new TreeMap<>();
map.put(3, "张三");
map.put(1, "李四");
map.put(2, "王五");
for (int key : map.keySet()) {
System.out.println(key + " " + map.get(key));
}
}
}
8. 遍历方式
package model3.unit4;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Java08 {
public static void main(String[] args) {
// 集合的遍历方式
List<String> list = new ArrayList<>();
list.add("a");
list.add("b");
list.add("c");
// 如果只是想打印集合中的数据
list.forEach(System.out::println);
// 遍历集合中的所有对象
list.forEach(s -> {
System.out.println(s);
});
Map<Integer, String> map = new HashMap<>();
map.put(1, "a");
map.put(2, "b");
map.put(3, "c");
map.forEach((k, v) -> {
System.out.println(k + " " + v);
});
}
}
9. foreach原理
package unit3;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Java28 {
public static void main(String[] args) {
int[] arr = {1,2,3,4,5};
for (int a : arr) {
System.out.println(a);
}
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
for (int i : list) {
System.out.println(i);
}
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
int x = iterator.next();
System.out.println(x);
}
}
}
10. 迭代器遍历
package unit3;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class Java29 {
public static void main(String[] args) {
List<Integer> list = new ArrayList<>();
list.add(1);
list.add(2);
list.add(3);
list.add(4);
list.add(5);
Iterator<Integer> iterator = list.iterator();
while (iterator.hasNext()) {
int x = iterator.next();
if (x == 3) {
iterator.remove();
}
System.out.println(x);
}
list.forEach(System.out::println);
}
}
11. 集合底层源码数据结构
package unit6;
import java.util.*;
/*
1.数据结构
队列:先进先出,后进后出
栈:后进先出,先进后出
数组:内存连续区域,根据索引查询快,增删慢
链表:元素是游离的,查询慢,双向链表首尾操作极快
二叉树:永远只有一个根节点,每个节点不超过2个子节点的树
二叉查找树:小的左边,大的右边,但是可能树会变得很高,查询性能变差
平衡查找二叉树:让树的高度差不大于1,增删改查都提高了
红黑树:基于红黑规则实现了自平衡的排序二叉树
2.集合数据结构
List:
ArrayList:数组
LinkedList:链表
Set:
HashSet:底层HashMap
TreeSet:底层TreeMap
Map:
HashMap:数组+链表+红黑树(链表长度大于阈值8)
TreeMap:红黑树
*/
public class CollectionTest extends Object {
public static void main(String[] args) {
// (1)ArrayList数组结构
// public class ArrayList<E> extends AbstractList<E>
// implements List<E>, RandomAccess, Cloneable, java.io.Serializable
// List 有序集合接口
// RandomAccess 通过元素序号快速获取元素对象、快速随机访问
// Cloneable 重写clone、能被克隆
// Serializable 序列化接口、对象流化
// ArrayList<Integer> arrayList = new ArrayList();
// this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
// private static final Object[] DEFAULTCAPACITY_EMPTY_ELEMENTDATA = {};
// Object[]数组、初始长度为0
// arrayList.add(1);
// 当添加第一个元素的时候、创建一个长度为10的Object数组
// private static final int DEFAULT_CAPACITY = 10;
// grow扩容的方法、扩容1.5倍
// if (minCapacity - elementData.length > 0) grow(minCapacity); }
// int newCapacity = oldCapacity + (oldCapacity >> 1);
// elementData = Arrays.copyOf(elementData, newCapacity);
// System.out.println(arrayList.get(0));
// int a = 4;
// System.out.println(a << 2); // 右移一位就是除2、左移一位就是乘2
// (2)LinkedList链表结构
// public class LinkedList<E>
// extends AbstractSequentialList<E>
// implements List<E>, Deque<E>, Cloneable, java.io.Serializable
// private static class Node<E> {
// E item;
// LinkedList.Node<E> next;
// LinkedList.Node<E> prev;
//
// Node(LinkedList.Node<E> prev, E element, LinkedList.Node<E> next) {
// this.item = element;
// this.next = next;
// this.prev = prev;
// }
// }
// LinkedList linkedList = new LinkedList();
// linkedList.add(1);
// final LinkedList.Node<E> newNode = new LinkedList.Node<>(l, e, null);
// last = newNode;
// linkedList.remove("");
// 链表遍历方式
// for (LinkedList.Node<E> x = first; x != null; x = x.next) {
// if (o.equals(x.item)) {
// unlink(x);
// return true;
// }
// }
// final LinkedList.Node<E> next = x.next;
// final LinkedList.Node<E> prev = x.prev;
//
// if (prev == null) {
// first = next;
// } else {
// prev.next = next;
// x.prev = null;
// }
// (3)HashMap数组结构 + 链表结构 + 红黑树结构
// HashMap初始化大小是16
// static final int DEFAULT_INITIAL_CAPACITY = 1 << 4; // aka 16
// 之后每次扩容是原来的2倍
// newThr = oldThr << 1;
// 链表阈值超过8则会转换为红黑树
// static final int TREEIFY_THRESHOLD = 8;
// 数组、如果链表长度超过8、先扩容数组、如果数值长度超过64、转换为红黑树
// static final int MIN_TREEIFY_CAPACITY = 64;
HashMap hashMap = new HashMap();
// this.loadFactor = DEFAULT_LOAD_FACTOR;
// 扩容的阈值:0.75 超过3/4才会扩容
// static final float DEFAULT_LOAD_FACTOR = 0.75f;
hashMap.put(1, "张三");
}
}
12. HashSet去重原理
package unit5;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
public class Java44 {
public static void main(String[] args) {
// HashSet不重复
// 原理:hashCode()、equals()
// 先比较对象的hashCode、如果没有相符的hashcode会假设没有重复出现、
// 如果有相同的hashCode会调用equlas方法检查是否相等、如果相等则不添加
// 解释:自定义一个类想使用hashset去重、必须重写hashcode、equals。
// HashSet的底层实现:HashSet是通过HashMap实现的!!
// 创建HashSet对象的时候、底层实际上是创建了一个HashMap集合
// public HashSet() {
// map = new HashMap<>();
// }
// HashSet添加对象的时候、底层实际上是作为key添加到HashMap中
// public boolean add(E e) {
// return map.put(e, PRESENT)==null;
// }
// 需求:如果名字和年龄都相同只添加一个。
Set<Person> set = new HashSet<Person>();
System.out.println(set.add(new Person("张三", 30)));
System.out.println(set.add(new Person("张三", 30)));
System.out.println(set.add(new Person("张三", 50)));
set.forEach(System.out::println);
}
}
class Person {
String name;
int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
// 第一步:重写hashcode、返回相同的值
@Override
public int hashCode() {
return 100;
}
// 第二步:重写equals、定义相等的规则
@Override
public boolean equals(Object obj) {
Person person = (Person)obj;
return this.name.equals(person.name) && this.age==person.age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
13. TreeSet和TreeMap排序原理
package unit5;
import java.util.TreeMap;
import java.util.TreeSet;
public class Java45 {
public static void main(String[] args) {
// 集合排序
// TreeSet集合:不重复、排序
// 报错:unit5.P cannot be cast to java.lang.Comparable
TreeSet<P> treeSet = new TreeSet<>();
treeSet.add(new P("bca", 40));
treeSet.add(new P("abc", 30));
treeSet.add(new P("ccc", 50));
treeSet.forEach(System.out::println);
// TreeSet源码:TreeSet底层就是通过TreeMap实现的
// public TreeSet() {
// this(new TreeMap<E,Object>());
// }
// public boolean add(E e) {
// return m.put(e, PRESENT)==null;
// }
// TreeMap集合:key-value存储、key排序
// TreeMap<String, String> treeMap = new TreeMap<>();
// treeMap.put("bba","张A");
// treeMap.put("abc","张B");
// treeMap.put("ccc","张C");
// treeMap.put("bca","张D");
// treeMap.forEach((k,v)->{
// System.out.println(k + v);
// });
// 排序本质:TreeSet -> TreeMap -> Comparable
// Comparable<? super K> k = (Comparable<? super K>) key;
// TreeMap.Entry<K,V> p = root;
// while (p != null) {
// int cmp = k.compareTo(p.key);
// System.out.println("a".compareTo("b"));
// System.out.println("b".compareTo("a"));
// System.out.println("a".compareTo("a"));
}
}
// 自定义类需要实现Comparable接口、规定了排序的规则
class P implements Comparable<P> {
// 实现排序规则的方法
// 正数、负数、0
@Override
public int compareTo(P p) {
return this.name.compareTo(p.name);
}
String name;
int age;
public P(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "P{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
14. 集合数组转换
package unit5;
import java.util.Arrays;
import java.util.List;
public class Java46 {
public static void main(String[] args) {
// 集合和数组转换
// 数组:基本类型和引用类型都可以存储。固定长度。
// 集合:只能存储应用类型。动态长度。
// 数组转换集合:Arrays数组工具类
List<Integer> list = Arrays.asList(1,2,3,4,5,6);
list.forEach(System.out::println);
// 集合转换数组:list中toArray
Integer[] arr = list.toArray(new Integer[0]);
for (int a:arr) {
System.out.println(a);
}
}
}
15. 数组类Array/Arrays
package unit5;
import java.lang.reflect.Array;
import java.util.Arrays;
public class Java47 {
public static void main(String[] args) {
// 数组类:为我们提供了动态创建和访问数组的方法。
// Array数组类、Arrays数组工具类
// // Collection集合接口、Collections集合工具类
// int[] arr = {1,2,3,4,5};
// // System.out.println(arr[2]);
// System.out.println(Array.getInt(arr, 2));
// // arr[2] = 33;
// Array.setInt(arr, 2, 33);
// System.out.println(Array.getInt(arr, 2));
// 反射API + Array创建数值
// 参数一:class类对象
// 参数二:数值长度
// int[] brr = new int[5];
// Object o = Array.newInstance(int.class, 5);
// int[] brr = (int[])o;
// System.out.println(Arrays.toString(brr));
// Arrays数组工具类
int[] x = {1,2,3};
int[] y = {1,2,3,4};
boolean equals = Arrays.equals(x, y);
System.out.println(equals);
// 参数:长度
int[] z = Arrays.copyOf(x, x.length);
for (int i:z) {
System.out.println(i);
}
}
(5)异常
1. 常见异常
package model3.unit5;
public class Java01 {
public static void main(String[] args) {
// 算数异常java.lang.ArithmeticException
// int a = 2 / 0;
// 数组下标越界异常java.lang.ArrayIndexOutOfBoundsException
// int[] b = {1,2};
// System.out.println(b[2]);
// 空指针异常java.lang.NullPointerException
// String c = null;
// System.out.println(c.length());
// 类型转换异常java.lang.ClassCastException
// Object d = "你好";
// LocalDateTime e = (LocalDateTime)d;
// 数字转换异常 java.lang.NumberFormatException
// int e = Integer.parseInt("你好");
}
}
2. 异常体系
package model3.unit5;
public class Java02 {
public static void main(String[] args) {
// 异常体系
// java.lang.Throwable 顶级父类
// java.lang.Error 错误(处理不了的错误) 非检查型
// java.lang.Exception 异常
// java.lang.RuntimeException 运行时异常 非检查型
// 其它异常类 检查型
// 异常分类
// 检查型异常:必须处理的异常。
// 非检查型异常:非必须处理的异常。
// 检查型异常示例
try {
FileReader fileReader = new FileReader("d:/person.txt");
} catch (FileNotFoundException e) {
e.printStackTrace();
}
}
}
3. 捕获异常
package model3.unit5;
public class Java03 {
public static void main(String[] args) {
// 异常处理
// 检查型异常(必须处理)、非检查型异常(建议处理)
// 异常有两种处理方式:
// 捕获异常:try、catch、finally
// try关键字:try语句块用来包含有可能产生异常的代码。
// catch关键字:catch用来捕获对应的异常并打印异常信息。
// finally关键字:不论try语句块中是否有异常都会被执行。
try {
String s = "";
// 空指针异常、当某一行代码发生异常时、代码会立刻终止并抛出异常
int i = s.length();
System.out.println(100);
System.out.println(i);
} catch (NullPointerException e) {
// 如果捕获到异常就会执行当前的语句块
e.printStackTrace();
System.out.println("错误描述信息。。。。。。");
} finally {
System.out.println(300);
}
}
}
4. 抛出异常
package model3.unit5;
public class Java04 {
public static void main(String[] args) {
// 第二种处理异常的方式:抛出异常
// throw:抛出关键字、用在方法体内部抛出一个异常。
// throws:抛出关键字、用在方法参数列表后边声明抛出多个异常。
// 理解:当异常是使用者的原因、方法抛出异常给调用者、调用者要处理。
try {
m(3, 0);
} catch (MyException e) {
e.printStackTrace();
}
}
// 除法
public static void m(int a, int b) throws MyException {
if (b == 0) {
throw new MyException("分母不能为零");
}
System.out.println(a / b);
}
}
5. 自定义异常
package model3.unit5;
// 自定义异常:业务异常
public class MyException extends Exception {
public MyException() {
super();
}
public MyException(String message) {
super(message);
}
}
6. 异常捕获关键字
package unit4;
import java.io.FileNotFoundException;
import java.io.FileReader;
public class Java33 {
// try和finally中都有return、try中的return会被忽略
// try中的return值会暂存到一个临时的本地变量中、finally的return执行后
// 这个变量中的值就变为finally的return的值
public static int m() {
try {
FileReader fileReader = new FileReader("d:/a.txt");
return 10;
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
System.out.println("一定执行");
return 100;
}
}
public static void main(String[] args) {
int i = m();
System.out.println(i);
// 处理异常的关键字
// 异常的处理方式两种:
// 捕获异常:try、catch、finally
// 抛出异常:throw、throws
// try:用于捕获异常、try catch/try finally/ try catch finally
// try语句块用来包含可能出现异常的代码
// 如果某行代码出现异常则当前代码终止并抛出异常
// catch:捕获try抛出的异常并打印异常信息、如果多个catch范围由小到大
// finally:不论是否有异常发生都会被执行的语句块
try {
String s = null;
char c = s.charAt(0); // 空指针异常、抛出空指针异常
System.out.println(100);
// int a = 3 / 0;
} catch (NullPointerException e) {
e.printStackTrace();
// 记录日志
System.out.println("空指针异常");
} catch (Exception e) {
e.printStackTrace();
System.out.println("算数异常");
} finally {
System.out.println("一定执行的代码放在此处");
}
// System.out.println(200);
// try {
//
// } finally {
//
// }
//
// try {
//
// } catch (Exception e) {
//
// } finally {
//
// }
}
}
7. 异常抛出关键字
package unit4;
import org.omg.SendingContext.RunTime;
public class Java34 {
static int bank = 100;
public static void main(String[] args) {
// 异常抛出
// 方式一:根据职责判断:实现方法问题捕获、调用方法问题抛出
// 方式二:根据异常分类:语法异常捕获、项目业务规则异常抛出
// throw:在方法内部抛出一个异常
// throws:在方法声明处抛出多个异常
try {
m(200);
} catch (Exception e) {
e.printStackTrace();
}
}
public static void m(int money) throws MyException, Exception {
if (money > bank) {
throw new MyException("余额不足");
}
// throw new Exception();
}
}
// 自定义异常
// exception异常包:定义当前项目中的自定义异常、违反项目业务规则的异常
// RuntimeException非检查
// Exception检查
class MyException extends Exception {
public MyException(String message) {
super(message);
}
}
(6)I/O流
1. IO体系
package model3.unit6;
public class Java01 {
public static void main(String[] args) {
// I/O流API体系
// InputStream输入流、读取
// OutputStream输出流、写出
// IO流分为两大类
// 第一类:字节流:byte[]:以字节流的方式来读写
// 字节流读:java.io.InputStream
// 字节流写:java.io.OutputStream
// 第二类:字符流:char[]:以字符流的方式来读写
// 字符流读:java.io.Reader
// 字符流写:java.io.Writer
}
}
2. 字符输入流
package model3.unit6;
import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
public class Java02 {
public static void main(String[] args) throws IOException {
// 字符输入流案例:读取文件
// 创建一个文件输入流
FileReader fileReader = new FileReader("d:/person.txt");
// 以文件输入流对象为构造参数创建缓冲流
BufferedReader bufferedReader = new BufferedReader(fileReader);
// 按行读取文件
String s = "";
while ((s = bufferedReader.readLine()) != null) {
System.out.println(s);
}
// 关闭IO流:关闭的顺序和打开的顺序相反
bufferedReader.close();
fileReader.close();
}
}
3. 字符输出流
package model3.unit6;
import java.io.BufferedWriter;
import java.io.FileWriter;
import java.io.IOException;
public class Java03 {
public static void main(String[] args) throws IOException {
// 字符输出流案例:写文件
// 创建文件输出流
FileWriter fileWriter = new FileWriter("d:/person2.txt", true);
// 创建缓冲流
BufferedWriter bufferedWriter = new BufferedWriter(fileWriter);
// 写文件
for (int i = 0; i < 10; i++) {
bufferedWriter.write("你好" + i + "\r\n");
}
// 关闭
bufferedWriter.close();
fileWriter.close();
}
}
4. 序列化
package unit5;
import java.io.*;
public class Java43 {
// 序列化:对象 ——> 文件
static void m1() throws IOException {
Per p1 = new Per("张三", 30);
File file = new File("d:/per.txt");
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(file));
oos.writeObject(p1);
oos.close();
}
// 反序列化:文件 ——> 对象
static void m2() throws IOException, ClassNotFoundException {
File file = new File("d:/per.txt");
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(file));
Object o = ois.readObject();
Per per = (Per)o;
System.out.println(per);
}
public static void main(String[] args) throws IOException, ClassNotFoundException {
// IO序列化、反序列化
// 注意:static不会被序列化。
// 注意:transient:被transient这个关键字修饰不会被序列化
// 序列化:对象 ——> 文件
// 把java对象以字节形式保存在磁盘文件中的过程。
//m1();
// 反序列化:文件 ——> 对象
// 把保存在磁盘中的java对象重新转换为内存中的java对象。
m2();
}
}
// 要实现序列化功能、类必须实现序列化接口(Serializable 标识接口)
class Per implements Serializable {
String name;
transient int age;
public Per(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Per{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
(7)网络
1. C/S和B/S架构
package model3.unit7;
public class Java01 {
public static void main(String[] args) {
// C/S架构:Client客户端、Server服务器
// 客户端应用程序(如桌面应用)与服务器之间的通信。
// B/S架构:Browser浏览器、Server服务器
// 浏览器与服务器之间的通信。
// Java语言实现网络通信
// 发送数据 接收数据
// Client类:客户端 ——> Server类:服务器
}
}
2. ServerSocket
package model3.unit7;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.ServerSocket;
import java.net.Socket;
public class Server {
public static void main(String[] args) throws IOException {
// 创建服务器套接字
// ip:主机号
// port:分机号、端口号是需要指定的、不能冲突
ServerSocket serverSocket = new ServerSocket(8888);
Socket socket = null;
InputStream in = null;
// 从socket中获取字节输入流
while (true) {
// 接收客户端发来的请求、当客户发送请求的时候才会被调用
socket = serverSocket.accept();
// 输入
in = socket.getInputStream();
byte[] b = new byte[1024];
int i = in.read(b); // 返回实际读取的长度
String str = new String(b, 0, i);
System.out.println(str);
// 输出
OutputStream outputStream = socket.getOutputStream();
outputStream.write("服务器响应的数据".getBytes());
}
// 注意:关闭
// in.close();
// socket.close();
}
}
3. Socket
package model3.unit7;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.Socket;
public class Client {
public static void main(String[] args) throws IOException {
// 客户端
// 创建套接字对象
// ip:192.168.3.53
// port:8888
Socket socket = new Socket("192.168.3.53", 8888);
// 输出、写
OutputStream outputStream = socket.getOutputStream();
String str = "张三";
outputStream.write(str.getBytes());
// 输入、读
InputStream in = socket.getInputStream();
byte[] b = new byte[1024];
int i = in.read(b); // 返回实际读取的长度
System.out.println(new String(b, 0, i));
outputStream.close();
socket.close();
}
}
(8)反射
1. 反射API
package model3.unit8;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Java01 {
public static void main(String[] args) throws ClassNotFoundException {
// 反射API
// 反射是一种看透Java的能力。只需要知道(包名.类名)就可以知道类中所有成员。
// 说明一:反射是所有Java框架实现的底层技术、开发技术的技术。
// 说明二:不但能看透所有代码、还可以执行调用所有的代码。高级API。
// java.lang.Class 类
// java.lang.reflect.Field 成员变量
// java.lang.reflect.Method 成员方法
// java.lang.reflect.Constructor 构造方法
// 获取类对象
Class<?> a = Class.forName("model3.unit8.Person");
// 获取成员变量
Field[] arr = a.getDeclaredFields();
for (Field f : arr) {
System.out.println(f.getName());
}
// 获取成员方法
Method[] brr = a.getDeclaredMethods();
for (Method m : brr) {
System.out.println(m.getName());
}
// 获取构造方法
Constructor[] crr = a.getConstructors();
for (Constructor c : crr) {
System.out.println(c.getName());
}
// 获取父类
Class<?> father = a.getSuperclass();
System.out.println(father.getName());
// 获取接口
Class<?>[] x = a.getInterfaces();
for (Class<?> k : x) {
System.out.println(k.getName());
}
}
}
class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
interface A {
}
interface B {
}
2. 反射案例
package model3.unit8;
public class Java02 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
// Spring框架IOC模块使用反射创建对象的底层机制
// 创建一个对象
Person person1 = new Person();
System.out.println(person1);
// 使用反射创建对象
Class<?> c = Class.forName("model3.unit8.Person");
// 调用无参构造方法创建对象
Person person2 = (Person) c.newInstance();
person2.setName("张三");
person2.setAge(30);
System.out.println(person2);
}
}
3. 注解+反射案例
package unit5;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
public class Java41 {
@V(name = "王五", age = 50)
static String name;
static int age;
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
// 注解是一种特殊的注释、主要用于修饰类、方法、变量
// 可以提供某些信息在程序编译或运行中的时候使用。
// 本质:继承Annotation的特殊接口
// 说明:定义注解的时候需要用来【元注解】、定义注解的注解。
// 总结:class类、interface接口、enum枚举、@interface注解
// 【注解 + 反射】 实现一个简单的通过注解实现赋值操作:
Class<?> c = Java41.class;
Field[] arr = c.getDeclaredFields();
for (Field f : arr) {
// 判断变量是否被注解修饰
if (f.isAnnotationPresent(V.class)) {
V v = f.getAnnotation(V.class);
String name = v.name();
// 回调函数
f.set(c.newInstance(), name);
}
}
System.out.println(name);
System.out.println(age);
}
}
// 定义了一个注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface V {
String name() default "张三";
int age();
}
(9)反射
1. 反射API
package model3.unit8;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
public class Java01 {
public static void main(String[] args) throws ClassNotFoundException {
// 反射API
// 反射是一种看透Java的能力。只需要知道(包名.类名)就可以知道类中所有成员。
// 说明一:反射是所有Java框架实现的底层技术、开发技术的技术。
// 说明二:不但能看透所有代码、还可以执行调用所有的代码。高级API。
// java.lang.Class 类
// java.lang.reflect.Field 成员变量
// java.lang.reflect.Method 成员方法
// java.lang.reflect.Constructor 构造方法
// 获取类对象
Class<?> a = Class.forName("model3.unit8.Person");
// 获取成员变量
Field[] arr = a.getDeclaredFields();
for (Field f : arr) {
System.out.println(f.getName());
}
// 获取成员方法
Method[] brr = a.getDeclaredMethods();
for (Method m : brr) {
System.out.println(m.getName());
}
// 获取构造方法
Constructor[] crr = a.getConstructors();
for (Constructor c : crr) {
System.out.println(c.getName());
}
// 获取父类
Class<?> father = a.getSuperclass();
System.out.println(father.getName());
// 获取接口
Class<?>[] x = a.getInterfaces();
for (Class<?> k : x) {
System.out.println(k.getName());
}
}
}
class Person {
String name;
int age;
public Person() {
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
}
interface A {
}
interface B {
}
2. 反射案例
package model3.unit8;
public class Java02 {
public static void main(String[] args) throws ClassNotFoundException, InstantiationException, IllegalAccessException {
// Spring框架IOC模块使用反射创建对象的底层机制
// 创建一个对象
Person person1 = new Person();
System.out.println(person1);
// 使用反射创建对象
Class<?> c = Class.forName("model3.unit8.Person");
// 调用无参构造方法创建对象
Person person2 = (Person) c.newInstance();
person2.setName("张三");
person2.setAge(30);
System.out.println(person2);
}
}
3. 注解+反射案例
package unit5;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
import java.lang.reflect.Field;
public class Java41 {
@V(name = "王五", age = 50)
static String name;
static int age;
public static void main(String[] args) throws InstantiationException, IllegalAccessException {
// 注解是一种特殊的注释、主要用于修饰类、方法、变量
// 可以提供某些信息在程序编译或运行中的时候使用。
// 本质:继承Annotation的特殊接口
// 说明:定义注解的时候需要用来【元注解】、定义注解的注解。
// 总结:class类、interface接口、enum枚举、@interface注解
// 【注解 + 反射】 实现一个简单的通过注解实现赋值操作:
Class<?> c = Java41.class;
Field[] arr = c.getDeclaredFields();
for (Field f : arr) {
// 判断变量是否被注解修饰
if (f.isAnnotationPresent(V.class)) {
V v = f.getAnnotation(V.class);
String name = v.name();
// 回调函数
f.set(c.newInstance(), name);
}
}
System.out.println(name);
System.out.println(age);
}
}
// 定义了一个注解
@Target({ElementType.FIELD})
@Retention(RetentionPolicy.RUNTIME)
@interface V {
String name() default "张三";
int age();
}
(10)线程
1. 单线程
package model3.unit9;
public class Java01 {
public static void main(String[] args) {
// 现在:Java应用程序只有一个主线程。单线程程序。
// while (true) {
// System.out.println(Thread.currentThread().getName());
// }
// 在Java项目中对象的运行机制是【多线程】机制。多少用户就会有多少线程。
}
}
2. 继承Thread
package model3.unit9;
// 实现多线程的方式一:直接继承线程类Thread
public class Java02 extends Thread {
// 线程核心业务方法
@Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String[] args) {
// 多个线程交替执行:时间片轮换
// 启动多线程
Java02 a = new Java02();
// 启动线程的方法
a.start();
Java02 b = new Java02();
b.start();
while (true) {
System.out.println(Thread.currentThread().getName());
}
}
}
3. 实现Runnable接口
package model3.unit9;
// 实现多线程的方式二(建议):实现Runnable接口
public class Java03 implements Runnable {
@Override
public void run() {
while (true) {
System.out.println(Thread.currentThread().getName());
}
}
public static void main(String[] args) {
// 启动线程
Java03 a = new Java03();
Thread b = new Thread(a, "线程B");
b.start();
Thread c = new Thread(a, "线程C");
c.start();
}
}
4. synchronized
package model3.unit9;
// 购票类
public class Java04 implements Runnable {
int count = 1;
public static void main(String[] args) {
// 多线程并发的问题
// 线程A ->
// 12306火车票购票
// 线程B ->
// 处理多线程并发问题:两种方式
// 原因:多个线程同时访问了一个方法、同时访问一个代码片段。
// 解决:某一个时刻只让一个线程访问、多个线程排队访问、效率低、但是安全。
// 同步块:使用synchronized锁定一个对象
// 把可能出现并发问题的代码放入同步块中。确保每次只有一个线程访问。
// 同步方法:使用synchronized修饰方法、让整个方法的实现都是线程安全的。
Java04 x = new Java04();
Thread a = new Thread(x, "线程A");
a.start();
Thread b = new Thread(x, "线程B");
b.start();
}
// 锁机制:同步方法锁的是类对象(Java04.class)
// 原理:当线程访问同步方法的时候、先检查类对象是否加锁
// 如果没有加锁:可以访问方法、并对类对象加锁、其它线程在方法外排队等候
// 如果已经加锁:在外边排队等候、等方法中线程调用结束之后释放锁才能访问。
public synchronized void m() {
String s = "";
// 同步块
// 原理:在Java语言中、每一个对象都有一个锁机制
// 先检查对象是否被加锁、如果没有锁则可以访问同步块代码、同时给对象加锁。
// 发现对象已经被加锁、只能在外等候、等待里边线程访问完后释放锁才能访问。
// synchronized (s) {
if (count > 0) {
// (2)线程B:休眠1秒
// (4)线程A:休眠1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
count--;
System.out.println(count);
}
//}
}
@Override
public void run() {
while (true) {
// 注意:不能用Integer锁对象。
String s = "";
synchronized (s) {
if (count > 0) {
// (2)线程B:休眠1秒
// (4)线程A:休眠1秒
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
e.printStackTrace();
}
System.out.println(Thread.currentThread().getName());
count--;
System.out.println(count);
}
}
}
}
}
(11)Stream流
1. Stream流创建
package unit6;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.stream.Stream;
public class Stream01 {
public static void main(String[] args) {
// 原理理解
// 创建-加工-获取
// (1)stream流创建
// Collection流
Stream<String> s1 = Arrays.asList("11", "22", "33").stream();
Stream<String> s2 = Arrays.asList("11", "22", "33").parallelStream();
// Map不可以创建流、但是Map中的Entry、key、value可以创建Stream流
Map<Integer, String> map = new HashMap<>();
Stream<Map.Entry<Integer, String>> s3 = map.entrySet().stream();
Stream<Integer> s4 = map.keySet().stream();
Stream<String> s5 = map.values().stream();
}
}
2. Stream流加工
package unit6;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
public class Stream02 {
public static void main(String[] args) {
// (2) Stream流加工
//创建原始数据
List<Employee> list = new ArrayList<>();
Employee ceo = new Employee("张三", 56, "男", 50000.42D, "浙江杭州", "浙江杭州", "ceo", null);
Employee manager1 = new Employee("李四", 47, "女", 20000.7D, "浙江宁波", "浙江宁波", "经理", ceo);
Employee manager2 = new Employee("王五", 45, "男", 24000.5D, "浙江金华", "浙江金华", "经理", ceo);
Employee employee1 = new Employee("麻六", 27, "女", 7000.6D, "浙江宁波", "广东广州", "售前", manager1);
Employee employee2 = new Employee("孙七", 28, "男", 8000.8D, "浙江宁波", "广东深圳", "售后", manager1);
Employee employee3 = new Employee("赵八", 27, "女", 9500.2D, "浙江杭州", "云南昆明", "售前", manager2);
Employee employee4 = new Employee("钱九", 26, "男", 9000.0D, "浙江杭州", "云南玉溪", "售后", manager2);
list.add(ceo);
list.add(manager1);
list.add(manager2);
list.add(employee1);
list.add(employee2);
list.add(employee3);
list.add(employee4);
// (1)filter
list.stream().filter(employee -> "张三".equals(employee.getName())).forEach(System.out::println);
// (2)map
list.stream().map(employee -> employee.getName()).forEach(System.out::println);
// (3)limit
list.stream().limit(1).forEach(System.out::println);
// (4)skip
list.stream().skip(6).forEach(System.out::println);
// (5)distinct
list.stream().distinct().forEach(System.out::println);
// (6)sorted
list.stream().sorted((e1,e2) -> (int) (e2.getSalary() - e1.getSalary())).forEach(System.out::println);
// (7)count/max/min
long count = list.stream().count();
System.out.println(count);
Employee max = list.stream().max(Comparator.comparingInt(Employee::getAge)).get();
System.out.println(max);
Employee min = list.stream().min(Comparator.comparingInt(Employee::getAge)).get();
System.out.println(min);
// (8)allMatch/noneMatch
boolean allMatch = list.stream().allMatch(employee -> 27 == employee.getAge());
System.out.println(allMatch);
boolean noneMatch = list.stream().noneMatch(employee -> 100 == employee.getAge());
System.out.println(noneMatch);
}
}
3. Stream流获取
package unit6;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
public class Stream03 {
public static void main(String[] args) {
List<Employee> list = new ArrayList<>();
Employee ceo = new Employee("张三", 56, "男", 50000.42D, "浙江杭州", "浙江杭州", "ceo", null);
Employee manager1 = new Employee("李四", 47, "女", 20000.7D, "浙江宁波", "浙江宁波", "经理", ceo);
Employee manager2 = new Employee("王五", 45, "男", 24000.5D, "浙江金华", "浙江金华", "经理", ceo);
Employee employee1 = new Employee("麻六", 27, "女", 7000.6D, "浙江宁波", "广东广州", "售前", manager1);
Employee employee2 = new Employee("孙七", 28, "男", 8000.8D, "浙江宁波", "广东深圳", "售后", manager1);
Employee employee3 = new Employee("赵八", 27, "女", 9500.2D, "浙江杭州", "云南昆明", "售前", manager2);
Employee employee4 = new Employee("钱九", 26, "男", 9000.0D, "浙江杭州", "云南玉溪", "售后", manager2);
list.add(ceo);
list.add(manager1);
list.add(manager2);
list.add(employee1);
list.add(employee2);
list.add(employee3);
list.add(employee4);
// (3)Stream流获取
// collect
// (1)分组:Collectors.groupingBy
Map<String, List<Employee>> collectGroup = list.stream().collect(Collectors.groupingBy(employee -> employee.getPosition()));
collectGroup.forEach((k,v)->{
System.out.println(k + "\t" + v);
});
// (2)list->set:Collectors.toSet()
Set<Employee> collectSet = list.stream().collect(Collectors.toSet());
collectSet.forEach(System.out::println);
// (3)list->map:Collectors.toMap
Map<String, Employee> collectMap = list.stream().collect(Collectors.toMap(Employee::getName, Employee->Employee));
collectMap.forEach((k,v)->{
System.out.println(k + "\t" + v);
});
// (4)平均:Collectors.averagingDouble()
Double collectDouble = list.stream().collect(Collectors.averagingDouble(Employee::getSalary));
System.out.println(collectDouble);
}
}
4. Stream合并
package unit6;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Collectors;
public class Stream04 {
public static void main(String[] args) {
// (1)注意:Stream流不能连续调用多次
// 异常:IllegalStateException
// List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
// Stream<Integer> stream = list.stream();
// stream.limit(2);
// stream.forEach(System.out::println);
// (2)集合合并
// List<Integer> list = new ArrayList<>();
// list.add(1);
// list.add(2);
// List<Integer> list2 = new ArrayList<>();
// list2.add(3);
// list2.add(4);
// list.addAll(list2);
// System.out.println(list);
// (3)Stream流合并
// List<Integer> list = Arrays.asList(1, 2);
// List<Integer> list2 = Arrays.asList(3, 4, 5);
// Stream.concat(list.stream(), list2.parallelStream()).forEach(System.out::println);
// (4)集合删除
// List<Integer> list = new ArrayList<>();
// list.add(1);
// list.add(4);
// list.removeIf(i->i==4);
// System.out.println(list);
// (5)交集、差集
// List<Integer> list = Arrays.asList(1, 2, 3);
// List<Integer> list2 = Arrays.asList(2,3,4);
// List<Integer> collect = list.stream().filter(a -> (!list2.conTAIns(a))).collect(Collectors.toList());
// System.out.println(collect);
// 并集
List<Integer> list = Arrays.asList(1, 2, 3);
List<Integer> list2 = Arrays.asList(2, 3, 4);
List<Integer> list3 = list.stream().collect(Collectors.toList());
list3.addAll(list2.stream().collect(Collectors.toList()));
list3.stream().distinct().forEach(System.out::println);
list3.stream().distinct().collect(Collectors.toList()).forEach(System.out::println);
}
}
5. Stream案例
package unit6;
import java.util.ArrayList;
import java.util.List;
public class Stream05 {
public static void main(String[] args) {
List<Employee> list = new ArrayList<>();
Employee ceo = new Employee("张三", 56, "男", 50000.42D, "浙江杭州", "浙江杭州", "ceo", null);
Employee manager1 = new Employee("李四", 47, "女", 20000.7D, "浙江宁波", "浙江宁波", "经理", ceo);
Employee manager2 = new Employee("王五", 45, "男", 24000.5D, "浙江金华", "浙江金华", "经理", ceo);
Employee employee1 = new Employee("麻六", 27, "女", 7000.6D, "浙江宁波", "广东广州", "售前", manager1);
Employee employee2 = new Employee("孙七", 28, "男", 8000.8D, "浙江宁波", "广东深圳", "售后", manager1);
Employee employee3 = new Employee("赵八", 27, "女", 9500.2D, "浙江杭州", "云南昆明", "售前", manager2);
Employee employee4 = new Employee("钱九", 26, "男", 9000.0D, "浙江杭州", "云南玉溪", "售后", manager2);
list.add(ceo);
list.add(manager1);
list.add(manager2);
list.add(employee1);
list.add(employee2);
list.add(employee3);
list.add(employee4);
// 综合案例
list.parallelStream()
.filter(e->e.getAge()>20 && e.getAge()<60)
.filter(e->e.getSalary()>5000)
.sorted((e1,e2) -> (int) (e2.getSalary() - e1.getSalary()))
.limit(3)
.map(e->e.getName()+e.getAge()+e.getSalary())
.forEach(System.out::println);
}
}
(12)函数式接口
1. Function
package unit6;
import java.util.function.Function;
public class Stream6 {
public static void main(String[] args) {
// java.util.function.Function
// public interface Function<T, R> {
// R apply(T t);
// }
// Function函数型接口:有一个传入参数、有一个输出、传入参数T、返回类型R
Function<Integer, String> function = (b)->{
return "你好" + b;
};
String s = function.apply(123);
System.out.println(s);
}
}
2. Predicate
package unit6;
import java.util.function.Predicate;
public class Stream7 {
public static void main(String[] args) {
// java.util.function.Predicate
// public interface Predicate<T> {
// boolean test(T t);
// }
// 断定型接口:有一个输入参数、返回值只能是布尔值
Predicate<String> predicate = (str)->str.equals("abc");
boolean boo = predicate.test("abc");
System.out.println(boo);
}
}
3. Consumer
package unit6;
import java.util.function.Consumer;
public class Stream8 {
public static void main(String[] args) {
// java.util.function.Consumer
// public interface Consumer<T> {
// void accept(T t);
// }
// 消费型接口:只有输入、没有返回值
Consumer<String> consumer = (str)->{
System.out.println(str);
};
consumer.accept("abc");
}
}
4. Supplier
package unit6;
import java.util.function.Supplier;
public class Stream9 {
public static void main(String[] args) {
// java.util.function.Supplier
// public interface Supplier<T> {
// T get();
// }
// 供给型接口:没有参数、只有返回值
Supplier supplier = ()->{return 100;};
Object o = supplier.get();
System.out.println(o);
}
}