1.正文
1. lambda表达式
2. 函数式接口。
3. 方法引用。
4. Stream流
5. 日期时间类
2.lambda表达式
2.1lambda表达式的概念
2.2lambda表达式的语法
注意:
函数式接口:接口中只有一个抽象方法。
(参数1,参数2): 抽象方法的参数
->: 分隔符
{}:表示抽象方法的实现
2.3.案例:
package demo01;
import javafx.concurrent.Task;
/**
* @unthor : YSH
* @date : 14:39 2022/7/19
*/
public class Test01 {
public static void main(String[] args) {
//该构造方法需要传递一个线程任务对象。Runnable类型
My task=new My();
Thread t1=new Thread(task);
t1.start();
//匿名内部类
Runnable task02=new Runnable() {
@Override
public void run() {
System.out.println("这时匿名内部类方式的任务对象");
}
};
Thread t2=new Thread(task02);
t2.start();
}
}
class My implements Runnable{
@Override
public void run() {
System.out.println("自定义任务接口类");
}
}
分析代码:
Thread 类需要 Runnable 接口作为参数,其中的抽象 run 方法是用来指定线程任务内容的核心
为了指定 run 的方法体,不得不需要 Runnable 接口的实现类
为了省去定义一个 Runnable 实现类的麻烦,不得不使用匿名内部类
必须覆盖重写抽象 run 方法,所以方法名称、方法参数、方法返回值不得不再写一遍,且不能写错
而实际上,似乎只有方法体才是关键所在。
这时可以使用lambda表示完成上面的要求:
//lambda表达式
Runnable task03 = ()-> {
System.out.println("这是使用Lambda表达式完成的");
};
Thread t3=new Thread(task03);
t3.start();
前提:
必须是函数式接口。
简化匿名内部类的使用,语法更加简单。
2.4练习无参无返回值的lambda表达式
package demo02;
/**
* @unthor : YSH
* @date : 18:47 2022/7/19
*
*
* 无参无返回值
*/
public class Test01 {
public static void main(String[] args) {
/*Swimmingable swimmingable = new Swimmingable() {
@Override
public void swimming() {
System.out.println("这是匿名内部类的方式");
}
};*/
/*
Swimmingable swimmingable = ()->{
System.out.println("这是Lambda表达式");
};*/
fun(()->System.out.println("这是Lambda表达式"));
}
public static void fun(Swimmingable s){
s.swimming();
}
}
interface Swimmingable{
public void swimming();
}
2.5练习有参有返回值的lambda表达式
下面举例演示 java.util.Comparator 接口的使用场景代码,其中的抽象方法定义为:
-
public abstract int compare(T o1, T o2);
当需要对一个对象集合进行排序时, Collections.sort 方法需要一个 Comparator 接口实例来指定排序的规则。
package demo02;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
/**
* @unthor : YSH
* @date : 15:09 2022/7/19
*
* 有参有返回值
*/
public class Test01 {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("刘德华",50,175.0));
personList.add( new Person("张学友",55,178.0));
personList.add(new Person("郭富城",56,170.0));
personList.add(new Person("黎明",54,180.0));
//对集合中的元素进行排序 按照年龄从大到小。
//传统做法:Comparator: 排序规则接口
// Comparator<Person> comparator = new Comparator<Person>() {
// //int: 0表示新加的元素和集合中原来的比对的相同
// //1: o2比o1小
// //-1: o2比o1大
/* Comparator<Person> comparator = new Comparator<Person>() {
@Override
public int compare(Person o1, Person o2) {
return o2.getAge()-o1.getAge();
}
};
Collections.sort(personList,comparator);
for (Person p: personList
) {
System.out.println(p);
}
}*/
System.out.println("===============================lambda===========================");
Comparator<Person> comparator = ( o1, o2)-> o1.getAge()-o2.getAge();
Collections.sort(personList,comparator);
for (Person p: personList
) {
System.out.println(p);
}
}
}
class Person{
private String name;
private Integer age;
private Double tell;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", tell=" + tell +
'}';
}
public Person(String name, Integer age, Double tell) {
this.name = name;
this.age = age;
this.tell = tell;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public Double getTell() {
return tell;
}
public void setTell(Double tell) {
this.tell = tell;
}
}
2.6详细结介绍lambda表达式
3.函数式接口
内置函数式接口的由来
package demo03;
import java.util.Arrays;
import java.util.function.Consumer;
/**
* @unthor : YSH
* @date : 19:08 2022/7/19
*/
public class Test01 {
public static void main(String[] args) {
//自己定义的函数式接口
/*Operater operater = arr -> {
int sum=0;
for (int n:arr
) {
sum+=n;
}
System.out.println("数组的和为:"+sum);
};
fun(operater);*/
/*public static void fun(Operater operater){
int[] arr ={1,2,3,4,5};
operater.getSum(arr);
}*/
System.out.println("=================");
//使用JDK提供的函数式接口
Consumer<int[]> consumer = t->{
int sum=0;
for (int n:t
) {
sum+=n;
}
System.out.println("数组的和为:"+sum);
};
fun(consumer);
}
public static void fun(Consumer<int[]> consumer){
int[] arr = {1,2,3,4,5};
consumer.accept(arr);
}
}
@FunctionalInterface //注解检测接口是否符合函数式接口
interface Operater{
//求数组的和
public abstract void getSum(int[] arr);
}
分析
我们知道使用Lambda表达式的前提是需要有函数式接口。而Lambda使用时不关心接口名,抽象方法名,只关心抽 象方法的参数列表和返回值类型。因此为了让我们使用Lambda方便,JDK提供了大量常用的函数式接口。
常见得函数式接口
3.1Consumer<T>消费型函数式接口
有参,无返回值
package demo04;
import java.util.function.Consumer;
/**
* @unthor : YSH
* @date : 19:08 2022/7/19
*
* Consumer<T>消费型函数式接口
* <T>表示参数类型的泛型
* 有参无返回值
*/
public class Test01 {
public static void main(String[] args) {
Consumer<Double> consumer = t->{
System.out.println("吃饭花费了:"+t);
};
fun(consumer,200);
}
//调用某个方法时,该方法需要的参数为接口类型,这时就应该能想到使用lambda
public static void fun(Consumer<Double> consumer,double money){
consumer.accept(money);
}
}
3.2Supplier<T>供给型函数式接口
T:表示返回结果的泛型
无参,有返回结果的函数式接口
T get();
package demo04;
import java.util.Random;
import java.util.function.Supplier;
/**
* @unthor : YSH
* @date : 20:08 2022/7/19
*Supplier<T>供给型函数式接口
*T:表示返回结果的泛型
* 无参有返回值
*/
public class Test02 {
public static void main(String[] args) {
/*Supplier<Integer> supplier = ()->{
return new Random().nextInt(10);//new Random().nextInt(10);随机生成一个0-10的数字
};*/
fun(()->{return new Random().nextInt(10);});
}
public static void fun(Supplier<Integer> supplier){
Integer result = supplier.get();
System.out.println("输出的内容为:"+result);
}
}
3.3Function<T,R> 函数型函数式接口
T: 参数类型的泛型
R: 函数返回结果的泛型
有参,有返回 值时
例子: 传入一个字符串把小写转换为大写。
package demo04;
import java.util.function.Function;
/**
* @unthor : YSH
* @date : 16:35 2022/7/19
*
* Function<T,R>函数型函数式接口
* T: 参数类型的泛型
* R: 函数返回结果的泛型
*
* 有参有返回值
*/
public class Test03 {
public static void main(String[] args) {
fun((t)->{
return t.toUpperCase();//t.toUpperCase()把字符串由小写转为大写
},"hello world");
}
public static void fun(Function<String,String> function,String msg){
String s = function.apply(msg);
System.out.println("结果为:"+s);
}
}
运行结果:
3.4Predicated<T>断言型函数式接口
T: 参数的泛型
boolean test(T t);
当传入一个参数时,需要对该参数进行判断时,则需要这种函数。
package demo04;
import java.util.function.Predicate;
/**
* @unthor : YSH
* @date : 20:57 2022/7/19
*
* Predicated<T>断言型函数式接口
*
* 当传入一个参数时,需要对该参数进行判断时,则需要这种函数
*/
public class Test04 {
public static void main(String[] args) {
fun(n->{
return n.length()>3?true:false;
},"迪丽热巴");
}
public static void fun(Predicate<String> predicate,String name){
boolean b = predicate.test(name);
System.out.println("改名字的长度是否大于3:"+b);
}
}
运行结果
4.方法引用
4.1lambda表达式的冗余
package demo05;
import java.util.function.Consumer;
/**
* @unthor : YSH
* @date : 21:05 2022/7/19
*
*
*
* 如果我们在Lambda中所指定的功能,已经有其他方法存在相同方案,那是否还有必要再写重复逻辑?可以直接“引 用”过去就好了:---方法引用。
*/
public class Test01 {
public static void main(String[] args) {
Consumer<Integer[]> c=arr->{
int sum=0;
for(int b:arr){
sum+=b;
}
System.out.println("数组的和为:"+sum);
};
fun(c);
}
public static void fun(Consumer<Integer[]> consumer){
Integer[] arr={1,2,3,4,5};
consumer.accept(arr);
}
public static void sum(Integer[] arr){
int sum=0;
for (int a:arr){
sum+=a;
}
System.out.println("数组的和为:"+sum);
}
}
分析:
如果我们在Lambda中所指定的功能,已经有其他方法存在相同方案,那是否还有必要再写重复逻辑?可以直接“引 用”过去就好了:---方法引用。
package demo05;
import java.util.function.Consumer;
/**
* @unthor : YSH
* @date : 21:05 2022/7/19
*
*
*
* 如果我们在Lambda中所指定的功能,已经有其他方法存在相同方案,那是否还有必要再写重复逻辑?可以直接“引 用”过去就好了:---方法引用。
*/
public class Test01 {
public static void main(String[] args) {
/*Consumer<Integer[]> consumer =arr->{
int sum=0;
for (int a:arr
) {
sum+=a;
}
System.out.println("数组的和为:"+sum);
};
fun(consumer);*/
Consumer<Integer[]> consumer = Test01::sum;// :: 表示方法引用
fun(consumer);
}
public static void fun(Consumer<Integer[]> consumer){
Integer[] arr = {1,2,3,4,5};
consumer.accept(arr);
}
public static void sum(Integer[] arr){
int sum=0;
for (int a:arr
) {
sum+=a;
}
System.out.println("数组的和为:"+sum);
}
}
请注意其中的双冒号 :: 写法,这被称为“方法引用”,是一种新的语法。
4.2什么是方法引用
方法引用的分类:
4.3静态方法引用
package demo06;
import java.util.Arrays;
import java.util.Comparator;
/**
* @unthor : YSH
* @date : 21:34 2022/7/19
*
*
* 静态方法引用
* 语法: 类名::staticMethod
* 对应的lambda表达式: (args)->类名.staticMethod(args)
*/
public class Test02 {
public static void main(String[] args) {
People[] ps={new People("张三",15) ,new People("李四",25),new People("王五",13)};
//该数组进行排序---年龄排序int compare(T o1, T o2);
// Comparator<People> c=(o1,o2)->o1.getAge()-o2.getAge();
// //如果在lambda表达式中有且仅有一条语句,而且这条语句是对方法的调用。这时可以考虑使用方法引用、
// Comparator<People> c=(o1,o2)->People.compareTo(o1,o2);
Comparator<People> comparator = People::compareTo;
Arrays.sort(ps,comparator);
}
}
class People{
private String name;
private int age;
public People(String name, int age) {
this.name = name;
this.age = age;
}
public static int compareTo(People p1, People p2){
return p1.getAge()-p2.getAge();
}
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;
}
}
4.4实例方法引用
实例方法引用,顾名思义就是调用已经存在的实例的方法,与静态方法引用不同的是类要先实例化,静态方法引用类无需实例化,直接用类名去调用。
package demo06;
import java.util.Arrays;
import java.util.Comparator;
import java.util.function.Supplier;
/**
* @unthor : YSH
* @date : 21:46 2022/7/19
*
* 实例方法引用
* 语法: inst::instMethod
* 对应的Lambda表达式: (args)->inst.instMethod(args)
*
*/
public class Test03 {
public static void main(String[] args) {
Person person = new Person("张三",26);
//在这个lambda表达式中只有一条语句,而且这条语句又是调用了某个方法
Supplier<String> supplier=()->{
System.out.println("===========");
return person.getName();
};
// Supplier<String> s=p::getName;
fun(supplier);
}
public static void fun(Supplier<String> supplier){
String s = supplier.get();
System.out.println("结果为:"+s);
}
}
class Person{
private String name;
private int age;
public static int compareTo(Person p1, Person p2){
return p1.getAge()-p2.getAge();
}
public Person(String name, int age) {
this.name = name;
this.age = age;
}
public Person() {
}
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;
}
}
4.5对象方法引用
对象方法引用: 类名::实例方法. (参数1,参数2)->参数1.实例方法(参数2)
package com.qy151.demo01;
import java.util.function.BiFunction;
import java.util.function.Function;
/**
* @unthor : YSH
* @date : 18:55 2022/7/20
*/
public class Test01 {
public static void main(String[] args) {
//[3]对象方法引用: 类名::实例方法. (参数1,参数2)->参数1.实例方法(参数2)
/*Function<String,Integer> function = (str)->{
return str.length();
};*/
Function<String,Integer> function = String::length;
Integer len =function.apply("xyy");
System.out.println(len);
//比较两个字符串的内容是否一致.T, U, R
// R apply(T t, U u);
BiFunction<String,String,Boolean> biFunction = (t,s)->{
return t.equals(s);
};
Boolean apply = biFunction.apply("xyy", "myy");
System.out.println(apply);
}
}
4.6构造方法引用
构造方法引用: 类名::new (参数)->new 类名(参数)
package com.qy151.demo01;
import java.util.function.Function;
import java.util.function.Supplier;
/**
* @unthor : YSH
* @date : 19:06 2022/7/20
*/
public class Test02 {
public static void main(String[] args) {
// [4]构造方法引用: 类名::new (参数)->new 类名(参数)
/*Supplier<String> supplier = ()->{
return new String("张三");
};
String s = supplier.get();
System.out.println(s);*/
Function<String,People> function = People::new;
People n = function.apply("王五");
System.out.println(n);
}
}
class People{
private String name;
public People(String name) {
this.name = name;
}
public People() {
}
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
5.Stream流
Java8的两个重大改变,一个是Lambda表达式,另一个就是本节要讲的Stream API表达式。==Stream 是Java8中处理集合的关键抽象概念==,它可以对集合进行非常复杂的查找、过滤、筛选等操作.
5.1为什么使用Stream流
当我们需要对集合中的元素进行操作的时候,除了必需的添加、删除、获取外,最典型的就是集合遍历。我们来体验 集合操作数据的弊端,需求如下:
一个ArrayList集合中存储有以下数据:张无忌,周芷若,赵敏,张强,张三丰,何线程
需求:1.拿到所有姓张的 2.拿到名字长度为3个字的 3.打印这些数据
未使用stream流的代码如下:
import java.util.ArrayList;
import java.util.Collections;
import java.util.Hashtable;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.Executors;
import java.util.concurrent.ThreadPoolExecutor;
/**
* @author: YSH
* @create: 2022-07-20 19:17
**/
public class My {
public static void main(String[] args) {
// 一个ArrayList集合中存储有以下数据:张无忌,周芷若,赵敏,张强,张三丰
// 需求:1.拿到所有姓张的 2.拿到名字长度为3个字的 3.打印这些数据
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
// 1.拿到所有姓张的
ArrayList<String> zhangList = new ArrayList<>(); // {"张无忌", "张强", "张三丰"}
for (String name : list) {
if (name.startsWith("张")) {
zhangList.add(name);
}
}
// 2.拿到名字长度为3个字的
ArrayList<String> threeList = new ArrayList<>(); // {"张无忌", "张三丰"}
for (String name : zhangList) {
if (name.length() == 3) {
threeList.add(name);
}
}
// 3.打印这些数据
for (String name : threeList) {
System.out.println(name);
}
}
}
分析:
这段代码中含有三个循环,每一个作用不同:
首先筛选所有姓张的人;
然后筛选名字有三个字的人;
最后进行对结果进行打印输出。
每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。这是理所当然的么?不是。循环 是做事情的方式,而不是目的。每个需求都要循环一次,还要搞一个新集合来装数据,如果希望再次遍历,只能再使 用另一个循环从头开始。
那Stream能给我们带来怎样更加优雅的写法呢?
使用stream流的代码如下:
package com.qy151.demo02;
import java.util.ArrayList;
import java.util.Collections;
/**
* @unthor : YSH
* @date : 19:19 2022/7/20
*/
public class Test01 {
public static void main(String[] args) {
ArrayList<String> list = new ArrayList<>();
Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰","张翠山");
//1. 首先筛选所有姓张的人;
//2. 然后筛选名字有三个字的人;
//3. 最后进行对结果进行打印输出。
list.stream()
.filter(item->item.startsWith("张"))
.filter(item->item.length()>2)
.forEach(System.out::println);
}
}
对集合的操作语法简洁:性能比传统快。
5.2Stream流的原理
注意:Stream和IO流(InputStream/OutputStream)没有任何关系,请暂时忘记对传统IO流的固有印象!
Stream流式思想类似于工厂车间的“生产流水线”,Stream流不是一种==数据结构==,==不保存数据==,而是对数据进行==加工 处理==。Stream可以看作是流水线上的一个工序。在流水线上,通过多个工序让一个原材料加工成一个商品。
Stream不存在数据,只对数据进行加工处理。
5.3 如何获取Stream流对象。
package com.qy151.demo02;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;
/**
* @unthor : YSH
* @date : 19:24 2022/7/20
*
* Stream流的原理
* Stream不存在数据,只对数据进行加工处理。
*/
public class Test02 {
public static void main(String[] args) {
//1.通过集合对象调用stream()获取流
List<String> list = new ArrayList<>();
list.add("喜羊羊");
list.add("美羊羊");
list.add("懒羊羊");
list.add("沸羊羊");
list.add("暖羊羊");
Stream<String> stream = list.stream();
stream.forEach(System.out::println);
stream.close();
System.out.println("==============");
//2.通过Arrays数组工具类获取Stream对象
int[] arr={2,4,6,8,10};
IntStream stream1 = Arrays.stream(arr);
stream1.forEach(System.out::println);
System.out.println("==============");
//3.使用Stream类中of方法
Stream<String> java = Stream.of("Java", "Python", "Spring", "World");
java.forEach(System.out::println);
System.out.println("==============");
//4.LongStream
//LongStream.range(1, 10);获取1-10之间的数字不包括10
// LongStream.rangeClosed(1, 10);获取1-10之间的数包括10
LongStream range = LongStream.range(1, 10);
range.forEach(System.out::println);
System.out.println("==============");
//上面的都是获取的串行流。还可以获取并行流。如果流中的数据量足够大,并行流可以加快处理速度
Stream<String> parallelStream = list.parallelStream();
parallelStream.forEach(System.out::println);
}
}
5.4 Stream流中常见的api
中间操作api: 一个操作的中间链,对数据源的数据进行操作。而这种操作的返回类型还是一个Stream对象。
终止操作api: 一个终止操作,执行中间操作链,并产生结果,返回类型不在是Stream流对象。
5.4.1 filter / foreach / count
package com.qy151.demo03;
import java.util.ArrayList;
import java.util.List;
import java.util.function.Predicate;
/**
* @unthor : YSH
* @date : 19:43 2022/7/20
*
* Stream流中常见的api
* filter / foreach / count
*/
public class Test01 {
public static void main(String[] args) {
List<Person> personList = new ArrayList<>();
personList.add(new Person("欧阳雪",18,"中国",'F'));
personList.add(new Person("Tom",24,"美国",'M'));
personList.add(new Person("Harley",22,"英国",'F'));
personList.add(new Person("向天笑",20,"中国",'M'));
personList.add(new Person("李康",22,"中国",'M'));
personList.add(new Person("小梅",20,"中国",'F'));
personList.add(new Person("何雪",21,"中国",'F'));
personList.add(new Person("李康",22,"中国",'M'));
//1)找到年龄大于18岁的人并输出;filter()过滤器需要一个断言接口函数,断言接口返回true,获取该元素。 foreach(Consumer)
//无论执行多少个中间操作,如果没有执行终止操作,那么中间操作都不会被执行。
personList.stream()
.filter(item->item.getAge()>18)
.forEach(System.out::println);
//2)找出所有中国人的数量。--->filter过滤掉其他国家的人 count()终止操作
long count = personList.stream()
.filter(item -> item.getCountry().equals("中国") ).count();
System.out.println(count);
}
}
class Person {
private String name;
private Integer age;
private String country;
private char sex;
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
", country='" + country + '\'' +
", sex=" + sex +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public Person(String name, Integer age, String country, char sex) {
this.name = name;
this.age = age;
this.country = country;
this.sex = sex;
}
}
运行结果:
5.4.2 map | sorted
map--接收Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
package com.qy151.demo03;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @unthor : YSH
* @date : 19:51 2022/7/20
*
* Stream流中常见的api
* map | sorted (排序)
*/
public class Test02 {
public static void main(String[] args) {
List<Person01> personList = new ArrayList<>();
personList.add(new Person01("欧阳雪",18,"中国",'F'));
personList.add(new Person01("Tom",24,"美国",'M'));
personList.add(new Person01("Harley",22,"英国",'F'));
personList.add(new Person01("向天笑",20,"中国",'M'));
personList.add(new Person01("李康",22,"中国",'M'));
personList.add(new Person01("小梅",20,"中国",'F'));
personList.add(new Person01("何雪",21,"中国",'F'));
personList.add(new Person01("李康",22,"中国",'M'));
//3.集合中每个元素只打印出名字.map--->原来流中每个元素转换为另一种格式
personList.stream()
.map(item->item.getName())
.forEach(System.out::println);
System.out.println("===========");
//打印出员工的名字和年龄
personList.stream()
.map(item->{
Map<String,Object> map = new HashMap<>();
map.put("name",item.getName());
map.put("age",item.getAge());
return map;
})
.forEach(System.out::println);
System.out.println("===========");
//4.对流中元素按照年龄从小到大进行排序
personList.stream()
.sorted((o1, o2) -> o1.getAge()- o2.getAge())
.forEach(System.out::println);
}
}
class Person01 {
private String name;
private Integer age;
private String country;
private char sex;
@Override
public String toString() {
return "Person01{" +
"name='" + name + '\'' +
", age=" + age +
", country='" + country + '\'' +
", sex=" + sex +
'}';
}
public Person01(String name, Integer age, String country, char sex) {
this.name = name;
this.age = age;
this.country = country;
this.sex = sex;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
}
运行结果:
5.4.3 min | max
package com.qy151.demo03;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
/**
* @unthor : YSH
* @date : 20:06 2022/7/20
*
* Stream流中常见的api
* (3) min max
*
*/
public class Test03 {
public static void main(String[] args) {
List<Person02> personList = new ArrayList<>();
personList.add(new Person02("欧阳雪",18,"中国",'F'));
personList.add(new Person02("Tom",24,"美国",'M'));
personList.add(new Person02("Harley",22,"英国",'F'));
personList.add(new Person02("向天笑",20,"中国",'M'));
personList.add(new Person02("李康",22,"中国",'M'));
personList.add(new Person02("小梅",20,"中国",'F'));
personList.add(new Person02("何雪",21,"中国",'F'));
personList.add(new Person02("李康",22,"中国",'M'));
//求出员工中年龄最大的 max终止操作
Optional<Person02> max = personList.stream()
.max((o1, o2) -> o1.getAge() - o2.getAge());
System.out.println("年龄最大的员工为:"+max.get());
System.out.println("==============");
//求出员工中年龄最小的
Optional<Person02> min = personList.stream()
.min((o1, o2) -> o1.getAge() - o2.getAge());
System.out.println("年龄最小的员工名字为:"+min.get().getName());
System.out.println("==============");
}
}
class Person02 {
private String name;
private Integer age;
private String country;
private char sex;
@Override
public String toString() {
return "Person02{" +
"name='" + name + '\'' +
", age=" + age +
", country='" + country + '\'' +
", sex=" + sex +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
public Person02(String name, Integer age, String country, char sex) {
this.name = name;
this.age = age;
this.country = country;
this.sex = sex;
}
}
运行结果:
5.4.4规约reduce
求集合中所有人的年龄和。参数和返回类型必须一致
Optional<Integer> reduce = personList.stream()
.map(item -> item.getAge())
.reduce((a, b) -> a + b);
System.out.println("年龄和为:"+reduce.get());
//[18,24,22,20,22,20,21]--->(18,24)->18+24;--->(42,22)->42+22--->(64,20)->64+20
Integer reduce1 = personList.stream()
.map(item -> item.getAge()).reduce(10, (a, b) -> a + b);
System.out.println(reduce1);
5.4.5collect搜集 match find
package com.qy151.demo03;
import java.util.ArrayList;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
/**
* @unthor : YSH
* @date : 20:55 2022/7/20
*/
public class Test04 {
public static void main(String[] args) {
List<Person03> personList = new ArrayList<>();
personList.add(new Person03("欧阳雪",18,"中国",'F'));
personList.add(new Person03("Tom",24,"美国",'M'));
personList.add(new Person03("Harley",22,"英国",'F'));
personList.add(new Person03("向天笑",20,"中国",'M'));
personList.add(new Person03("李康",22,"中国",'M'));
personList.add(new Person03("小梅",20,"中国",'F'));
personList.add(new Person03("何雪",21,"中国",'F'));
personList.add(new Person03("李康",22,"中国",'M'));
// findFirst findAll
Optional<Person03> first = personList.stream()
.filter(item -> item.getSex() == 'F').findFirst();
System.out.println(first.get().getName());
Optional<Person03> any = personList.parallelStream()
.filter(item -> item.getSex() == 'F').findAny();
System.out.println(any.get().getName());
System.out.println("================");
//员工中是否有性别为F且年龄没有大于20的
boolean b = personList.parallelStream()
.filter(item -> item.getSex() == 'F')
.noneMatch(item -> item.getAge() > 20);
System.out.println(b);
System.out.println("================");
//搜集方法 collect 它属于终止方法
//年龄大于20且性别为M
List<Person03> collect = personList.stream()
.filter(item -> item.getAge() > 20)
.filter(item -> item.getSex() == 'M')
.collect(Collectors.toList());
System.out.println(collect);
}
}
class Person03 {
private String name;
private Integer age;
private String country;
private char sex;
public Person03(String name, Integer age, String country, char sex) {
this.name = name;
this.age = age;
this.country = country;
this.sex = sex;
}
@Override
public String toString() {
return "Person03{" +
"name='" + name + '\'' +
", age=" + age +
", country='" + country + '\'' +
", sex=" + sex +
'}';
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getCountry() {
return country;
}
public void setCountry(String country) {
this.country = country;
}
public char getSex() {
return sex;
}
public void setSex(char sex) {
this.sex = sex;
}
}
6.日期时间类
package com.qy151.demo05;
import java.time.Duration;
import java.time.LocalDate;
import java.time.LocalDateTime;
import java.time.LocalTime;
import java.time.format.DateTimeFormatter;
/**
* @unthor : YSH
* @date : 9:43 2022/7/21
*
*
*
* LocalDate: 表示日期类。yyyy-MM-dd
*
* LocalTime: 表示时间类。 HH:mm:ss
*
* LocalDateTime: 表示日期时间类 yyyy-MM-dd t HH:mm:ss sss
*
* DatetimeFormatter:日期时间格式转换类。
*
* Instant: 时间戳类。
*
* Duration: 用于计算两个日期类
*/
public class Test01 {
public static void main(String[] args) {
LocalDate now = LocalDate.now();//获取当前日期
LocalDate date = LocalDate.of(2000, 01, 01);//指定日期
System.out.println("现在的日期为:"+now);
System.out.println("指定的日期为:"+date);
System.out.println("=========");
LocalTime localTime = LocalTime.now();//获取当前时间
System.out.println("当前的时间为:"+localTime);
//LocalTime.of--指定时间--> .of表示指定时间
System.out.println("=========");
LocalDateTime localDateTime = LocalDateTime.now();//获取当前时间日期
LocalDateTime localDateTime1 = LocalDateTime.of(2022, 7, 1, 17, 45, 32);
Duration between = Duration.between(localDateTime, localDateTime1);
System.out.println("当前的时间日期为:"+localDateTime);
System.out.println("两个时间相差"+between.toHours()+"个小时");
System.out.println("=========");
DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");//把字符串转换为日期的格式规则
LocalDate parse = LocalDate.parse("1999-07-12", dateTimeFormatter);//把字符串转换为日期格式
String format = parse.format(dateTimeFormatter);//把字日期转换为字符串
System.out.println("日期为:"+parse);
System.out.println("字符串为:"+format);
}
}
运行结果: