目录
6.1.5 find操作--findFirst和findAny
6.1.6 match 匹配操作--allMatch anyMatch
概念:Lambda表达式:特殊的匿名内部类,语法更简洁
Lambda表达式允许把函数作为一个方法的参数(函数作为方法参数传递),将代码像数据一样传递
匿名内部类:无需创建接口的实现类,可以之间创建接口对象
- Runnable runnable=new Runnable() {
- @Override
- public void run() {
-
- }
- };
调用方法时:传递的参数可以是 基本类型,引用类型
语法:
函数式接口: 接口有只有一个抽象方法。这种接口就是函数式接口。
我们要想使用lambda表示,它的接口必须为函数式接口。
箭头左边:抽象方法的参数
->: 运算符
箭头右边: 抽象方法的方法体。
- public class Test {
- public static void main(String[] args) {
-
-
- //构造函数需要传递一个Runnable target类型的参数。而Runnable它是一个接口。
- MyRunnable my=new MyRunnable();
- Thread t=new Thread(my);
- t.start();
-
-
- //使用匿名内部类
- Runnable runnable=new Runnable() {
- @Override
- public void run() {
- System.out.println("~~~~~~~~~~~~~~这是匿名内部类");
- }
- };
- Thread t2=new Thread(runnable);
- t2.start();
-
-
-
- }
- }
- class MyRunnable implements Runnable{
-
- @Override
- public void run() {
- System.out.println("~~~~~~~~~~~~~~这是自定义接口实现类");
- }
- }
分析代码:
Thread 类需要 Runnable 接口作为参数,其中的抽象 run 方法是用来指定线程任务内容的核心
为了指定 run 的方法体,不得不需要 Runnable 接口的实现类
为了省去定义一个 Runnable 实现类的麻烦,不得不使用匿名内部类
必须覆盖重写抽象 run 方法,所以方法名称、方法参数、方法返回值不得不再写一遍,且不能写错
而实际上,似乎只有方法体才是关键所在。
我们就可以使用Lambda表达式
- //lambda表达式 没有关注方法的名称 以及方法的返回类型 --lambda表示不会生成字节码文件
- Runnable r=()->{
- System.out.println("这是lambda表达式");
- };
- Thread t3=new Thread(r);
- t3.start();
- public class Test {
- public static void main(String[] args) {
- Swimming s=new Swimming() {
- @Override
- public void swiming() {
- System.out.println("~~~~~~~~~~~~匿名内部类");
- }
- };
- fun(s);
-
-
- Swimming s2=()->{
- System.out.println("lambda表达式============");
- };
- fun(s2);
-
- }
-
- //定义一个方法---传递的参数为接口类型---函数式接口
- public static void fun(Swimming s){
- s.swiming();
- }
- }
- //它就是函数式接口
- @FunctionalInterface
- interface Swimming{
- public void swiming();
- }
- public class Test02 {
- public static void main(String[] args) {
- //无需参数类型
- Operator o = (arr) -> {
- int sum = 0;
- for (int b : arr) {
- sum += b;
- }
- return sum;
- };
-
-
- fun(o);
- }
-
- public static void fun(Operator operator) {
- int sum[] = {11, 12, 13, 14};
- int sum1 = operator.getSum(sum);
- System.out.println("数组中元素的和:" + sum1);
- }
- }
-
- interface Operator {
- //求数组中元素的和
- public int getSum(int[] arr);
- }
下面举例演示 java.util.Comparator 接口的使用场景代码,其中的抽象方法定义为:
public abstract int compare(T o1, T o2);
当需要对一个对象集合进行排序时, Collections.sort 方法需要一个 Comparator 接口实例来指定排序的规则。
- public class Test03 {
- public static void main(String[] args) {
- List
list=new ArrayList<>(); - list.add(new Student("柳昌江",16));
- list.add(new Student("汪豪杰",17));
- list.add(new Student("闫克起",15));
- list.add(new Student("刘洺宇",16));
- //List
list,要排序的集合 - // Comparator super T> c: 指明排序的规则
- // Comparator
comparator=new Comparator() { - // //返回0 表示o1和o2 相同 返回大于0
- // @Override
- // public int compare(Student o1, Student o2) {
- // return o1.getAge()-o2.getAge();
- // }
- // };
-
- Comparator
comparator=(o1,o2)->{return o2.getAge()-o1.getAge();}; - Collections.sort(list,comparator);
- System.out.println(list);
- }
- }
-
-
- class Student{
- private String name;
- private Integer age;
-
- @Override
- public String toString() {
- return "Student{" +
- "name='" + name + '\'' +
- ", age=" + age +
- '}';
- }
-
- 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 Student(String name, Integer age) {
- this.name = name;
- this.age = age;
- }
- }
1.4 详细介绍Lambda表达式
什么时候使用lambda表达式?
调用某个方法时,该方法需要传递一个函数式接口参数时

概念: 如果一个接口只有一个抽象方法,则该接口称之为函数式接口,函数式接口可以使用Lambda表达式,Lambda表达式会被匹配到这个抽象方法上。
@FunctionalInterface 注解检测接口是否符合函数式接口
内置函数式接口的由来
- public class Test {
- public static void main(String[] args) {
- Operator o=arr -> arr.length;
- fun(o);
- }
- public static void fun(Operator operator) {
- int sum[] = {11, 12, 13, 14};
- int sum1 = operator.getSum(sum);
- System.out.println("数组中元素的个数:" + sum1);
- }
- }
-
- interface Operator {
- //求数组中元素的和
- public int getSum(int[] arr);
- }
分析
我们知道使用Lambda表达式的前提是需要有函数式接口。而Lambda使用时不关心接口名,抽象方法名,只关心抽 象方法的参数列表和返回值类型。因此为了让我们使用Lambda方便,JDK提供了大量常用的函数式接口。 ---无需自定义函数式接口。---如果JDK不提供一些函数式接口,那么每个人需要自定义函数式接口,而且每个人定义的名称不一致。
内置的函数式接口都在 java.util.function包下
T: 参数的泛型
void accept(T t);
方法中有参,无返回值。
- /**
- * Created by Intellij IDEA
- *
- * @author 王俊凯
- * @Date: 2022/11/3 12:11
- * @Version 1.0
- */
- package com.wjk.demo05;
-
- import java.util.function.Consumer;
-
- /**
- * 消费性函数式接口
- * 有参无返回值
- * 如果需要一个有参返回值的函数式接口,那么我们就可以使用Consumer函数式即可,无需自定义函数式接口
- */
- public class Test05 {
- public static void main(String[] args) {
- Consumer
consumer=a -> { - System.out.println("吃烧烤需要花:"+a);
- };
-
- fun(consumer,9999.99);
- }
-
- public static void fun(Consumer
consumer,Double money) { - consumer.accept(money);
- }
- }
-
T:表示方法的返回值泛型 T get();
方法没有参数,有返回值。 当我们需要无参有返回值的函数式接口,就可以使用这种内置
- /**
- * Created by Intellij IDEA
- *
- * @author 王俊凯
- * @Date: 2022/11/3 12:15
- * @Version 1.0
- */
- package com.wjk.demo06;
-
- import java.util.function.Supplier;
-
- /**
- * T:表示方法的返回值泛型
- * 方法没有参数,有返回值 当我们需要无参有返回值的函数式接口时,就可以用这种内置
- * fun是自己写的方法,未来可能调用jdk自带的方法,参数也可能就是上面给的函数式接口。
- */
- public class Test06 {
- public static void main(String[] args) {
- Supplier
s=()->{ - return "八嘎";
- };
- fun(s);
- }
-
- public static void fun(Supplier
supplier) { - String s = supplier.get();
- System.out.println(s);
- }
- }
-
T:参数的泛型
R: 返回值的泛型
R apply(T t);
这种函数式接口需要参数和有返回值。
- /**
- * Created by Intellij IDEA
- *
- * @author 王俊凯
- * @Date: 2022/11/3 12:18
- * @Version 1.0
- */
- package com.wjk.demo07;
-
-
- import java.util.function.Function;
-
- /**
- * Funcation
函数型函数式接口 - * T:参数的泛型
- * R: 返回值的泛型
- * R apply(T t);
- * 这种函数式接口需要参数和有返回值
- */
- public class Test07 {
- public static void main(String[] args) {
-
- Function
function=t->t.length(); -
- fun(function,"hahahahahahahhahahahahahahahhaha");
- }
- public static void fun(Function
f,String str) { - Integer apply = f.apply(str);
- System.out.println(apply);
- }
- }
-
boolean test(T t);
泛型: 参数的类型
返回值: boolean
根据参数做相应的条件判断,如果满足条件则返回true,不满足则返回false.
- /**
- * Created by Intellij IDEA
- *
- * @author 王俊凯
- * @Date: 2022/11/4 9:11
- * @Version 1.0
- */
- package com.wjk.demo1104.demo01;
-
- import java.util.function.BiPredicate;
- import java.util.function.Predicate;
-
- /**
- * 断言型函数式接口
- */
- public class TestPredicate {
- public static void main(String[] args) {
-
- //根据你传递的字符串,判断字符串的长度是否大于5
- Predicate
p=t->{ - return t.length()>5;
- };
-
- boolean baga = p.test("hello baga");
- System.out.println(baga);
-
- //boolean test (T t,U u)
- BiPredicate
biPredicate=(t,u)->{ - return t.equals(u);
- };
-
- boolean test = biPredicate.test("baga", "guizi");
- System.out.println(test);
- }
- }
-
我们用Lambda表达式来实现匿名方法。但有些情况下,我们用Lambda表达式仅仅是调用一些已经存在的方法,除了调用方法外,没有其他任何多余的动作,在这种情况下,我们倾向于通过方法名来调用它,而Lambda表达式可以帮助我们实现这一要求,它使得Lambda在调用那些已经拥有方法名的方法的代码更简洁、更容易理解。方法引用可以理解为Lambda表达式的另外一种表现形式。方法引用要比lambda表达式语法更加简洁
方法引用: 理解为Lambda表达式的另一种表现。它的语法更加简洁。
方法引用使用的前提: lambda表达式中调用的是已经存在的方法,除了调用方法外,不能有任何其他操作,才可以使用方法引用。
| 类型 | 语法 | 对应的LAMBDA表达式 |
|---|---|---|
| 静态方法引用 | 类名::staticMethod | (args) -> 类名.staticMethod(args) |
| 实例方法引用 | inst::instMethod | (args) -> inst.instMethod(args) |
| 对象方法引用 | 类名::instMethod | (inst,args) -> inst.instMethod(args) |
| 构建方法引用 | 类名::new | (args) -> new 类名(args) |
:: 是方法引用的符号。
静态方法的引用:当lambda表达式中,通过类名引用了一个已经存在的静态方法时。而且仅有一条语句
- public class Test01 {
- public static void main(String[] args) {
-
- //void accept(T t);
- //Consumer
consumer=(arr)->{Test01.sum(arr);}; - //观察: 我们发现lambda表达式中有且仅有一条一句,而且这条语句,是调用了已经存在的方法。
- Consumer<int[]> consumer=Test01::sum;
- int[] arr={1,2,3,4};
- consumer.accept(arr);
- }
-
- public static void sum(int[] arr) {
- int sum = 0;
- for (int a : arr) {
- sum += a;
- }
- System.out.println("数组中元素的和:"+sum);
-
- }
- }
- public class Test02 {
- public static void main(String[] args) {
-
- List
list=new ArrayList<>(); - list.add(2);
- list.add(3);
- list.add(8);
- list.add(4);
- list.add(1);
- //Comparator
comparator=(o1,o2)->Integer.compare(o1,o2); - Comparator
comparator=Integer::compare; - Collections.sort(list,comparator);
-
- System.out.println(list);
- }
- }
实例方法的引用:实例方法引用 inst::instMethod (args) -> inst.instMethod(args)
- /**
- * Created by Intellij IDEA
- *
- * @author 王俊凯
- * @Date: 2022/11/4 10:16
- * @Version 1.0
- */
- package com.wjk.demo1104.demo03;
-
- import java.util.function.Supplier;
-
- /**
- * 实例方法引用
- */
- public class Test03 {
- public static void main(String[] args) {
- //无参 有返回值
- Teacher teacher=new Teacher("闫克起","35");
-
- //Supplier
supplier=()-> teacher.getName(); -
- //方法引用
- Supplier
supplier=teacher::getName; - Supplier
supplier1=teacher::getAge; -
- System.out.println(supplier.get()+"********"+supplier1.get());
-
-
-
- }
- }
- class Teacher{
- private String name;
- private String age;
-
- @Override
- public String toString() {
- return "Teacher{" +
- "name='" + name + '\'' +
- ", age='" + age + '\'' +
- '}';
- }
-
- public Teacher(String name, String age) {
- this.name = name;
- this.age = age;
- }
-
- public String getName() {
- return name;
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String getAge() {
- return age;
- }
-
- public void setAge(String age) {
- this.age = age;
- }
- }
-
对象方法引用 类名::instMethod (inst,args) -> inst.instMethod(args)
当lambda表达式第一个参数调用方法,而后面的参数作为方法的参数时。 我们可以考虑使用对象方法引用。
- /**
- * Created by Intellij IDEA
- *
- * @author 王俊凯
- * @Date: 2022/11/4 10:19
- * @Version 1.0
- */
- package com.wjk.demo1104.demo04;
-
- import java.util.function.BiPredicate;
-
- /**
- * 对象方法引用
- */
- public class Test {
- public static void main(String[] args) {
- //比较两个字符串是否一致 断言式函数式接口
- // BiPredicate
biPredicate=(o1,o2)->{ - // return o1.equals(o2);
- // };
-
- //对象方法引用
- BiPredicate
biPredicate=String::equals; -
- boolean test = biPredicate.test("八嘎", "baag");
- System.out.println(test);
- }
- }
-
构建方法引用 类名::new (args) -> new 类名(args)
lambda表达式中只有一条语句,而且这条数据是实例一个对象,调用构造方法,而且构造函数的参数和lambda表达式的参数一致。
- /**
- * Created by Intellij IDEA
- *
- * @author 王俊凯
- * @Date: 2022/11/4 10:23
- * @Version 1.0
- */
- package com.wjk.demo1104.demo05;
-
- import java.util.function.Function;
- import java.util.function.Supplier;
-
- /**
- * 构造方法引用
- */
- public class Test {
- public static void main(String[] args) {
- //Function
function=(t)->new Teacher(t); -
- //构造方法引用
- Function
function=Teacher::new; -
- Teacher apply = function.apply("闫克起");
- System.out.println(apply);
-
- }
- }
- class Teacher{
- private String name;
-
- public Teacher() {
- }
-
- @Override
- public String toString() {
- return "Teacher{" +
- "name='" + name + '\'' +
- '}';
- }
-
- public Teacher(String name) {
- this.name = name;
- }
-
- }
-
Java8的两个重大改变,一个是Lambda表达式,另一个就是本节要讲的Stream API表达式。Stream 是Java8中处理集合的关键抽象概念,它可以对集合进行非常复杂的查找、过滤、筛选等操作.
这种操作速度,要比操作数据库更快。 引用它基于JVM内存.
当我们需要对集合中的元素进行操作的时候,除了必需的添加、删除、获取外,最典型的就是集合遍历。我们来体验 集合操作数据的弊端,需求如下:
一个ArrayList集合中存储有以下数据:张无忌,周芷若,赵敏,张强,张三丰
需求:1.拿到所有姓张的 2.拿到名字长度为3个字的 3.打印这些数据
代码如下:
- public class Test {
- public static void main(String[] args) {
- ArrayList
list = new ArrayList<>(); - Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
-
- //1.获取所有姓张。
- ArrayList
newList = new ArrayList<>(); - for(String n:list){
- if(n.startsWith("张")){
- newList.add(n);
- }
- }
-
- //2. 名字中含有三个的字
- ArrayList
newList2 = new ArrayList<>(); - for(String n:newList){
- if(n.length()==3){
- newList2.add(n);
- }
- }
-
- //3.打印
- for (String s:newList2){
- System.out.println(s);
- }
-
- }
- }
不过循环遍历有个弊端 这段代码中含有三个循环,每一个作用不同:
首先筛选所有姓张的人;
然后筛选名字有三个字的人;
最后进行对结果进行打印输出。
每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。这是理所当然的么?不是。循环 是做事情的方式,而不是目的。每个需求都要循环一次,还要搞一个新集合来装数据,如果希望再次遍历,只能再使 用另一个循环从头开始。
那Stream能给我们带来怎样更加优雅的写法呢?
使用Stream流来体验上面对集合的操作。
- public static void main(String[] args) {
- ArrayList
list = new ArrayList<>(); - Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
-
-
- // Consumer
consumer=item-> System.out.println(item); - list.stream()
- .filter(item->item.startsWith("张"))
- .filter(item->item.length()==3)
- .forEach(item-> System.out.println(item));
-
- }
Stream流式思想类似于工厂车间的“生产流水线”,Stream流不是一种数据结构,不保存数据,而是对数据进行加工 处理。Stream可以看作是流水线上的一个工序。在流水线上,通过多个工序让一个原材料加工成一个商品。

这里获取流对象的方式有三种: 1. 通过集合名获取。 2. 通过Arrays中的静态方法获取streams 3. 通过Stream中的静态方法of
拿到流对象后才能操作Stream类中相关的方法
- public class Test02 {
- public static void main(String[] args) {
- ArrayList
list = new ArrayList<>(); - Collections.addAll(list, "张无忌", "周芷若", "赵敏", "张强", "张三丰");
- //通过集合对象调用stream方法获取
- Stream
stream = list.stream(); -
- //通过Arrays数组工具类调用stream方法。
- String [] arr={"张三","李四","王五"};
- Stream
stream1 = Arrays.stream(arr); -
- //通过Stream类中的方法获取Stream流对象
- Stream
stream2 = Stream.of("张三", "李四", "王五"); - }
- }
一个操作的中间链,对数据源的数据进行操作。
举个简单的例子:
假设有一个Person类和一个Person列表,现在有两个需求:1)找到年龄大于18岁的人并输出;2)找出所有中国人的数量。
- /**
- * Created by Intellij IDEA
- *
- * @author 王俊凯
- * @Date: 2022/11/4 14:27
- * @Version 1.0
- */
- package com.wjk.demo1104.demo07;
-
- import java.util.ArrayList;
- import java.util.List;
-
- public class Test02 {
- public static void main(String[] args) {
- List
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'));
- //找出年龄大于18
- personList.stream().filter(item->{
- return item.getAge()>18;
- }).forEach(System.out::println);
-
- System.out.println("*****************************");
-
- //找出所有中国人
- personList.stream().filter(item->item.getCountry().equals("中国")).forEach(System.out::println);
- }
- }
- 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 Person() {
- }
-
- public Person(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;
- }
- }
-
中间操作api: 一个操作的中间链,对数据源的数据进行操作。而这种操作的返回类型还是一个Stream对象。---中间操作如果没有调用终止操作的api,则中间操作的api不会被执行。
终止操作api: 一个终止操作,执行中间操作链,并产生结果,返回类型不在是Stream流对象。

该方法需要一个断言型函数式接口参数,满足条件的留下,不满足条件的过滤掉。

- public class Test03 {
- public static void main(String[] args) {
- List
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'));
-
- //筛选出年龄大于20
- // personList.stream().filter(item -> item.getAge() > 20).forEach(item-> System.out.println(item));
-
- personList.stream().filter(item -> item.getAge() > 20).forEach(System.out::println);
-
-
- }
- }
- 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 Person() {
- }
-
- public Person(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;
- }
- }
map--接收Lambda,将元素转换成其他形式或提取信息。接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。

- List
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'));
-
- //map映射操作--名称
- personList.stream().map(item->item.getName()).forEach(System.out::println);
- List
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'));
-
- //sort排序操作--年龄
- personList.stream().sorted((o1,o2)->Integer.compare(o1.getAge(),o2.getAge())).forEach(System.out::println);
流也可以进行合并、去重、限制、跳过等操作。 filter map sort concat distinct limit skip
- public class Test04 {
- public static void main(String[] args) {
- String[] arr1 = { "a", "b", "c", "d" };
- String[] arr2 = { "d", "e", "f", "g" };
- Stream
stream1 = Stream.of(arr1); - Stream
stream2 = Stream.of(arr2); -
- //合并流
- //Stream.concat(stream1,stream2).forEach(System.out::println);
- //去重--distinct
- // Stream.concat(stream1,stream2).distinct().forEach(System.out::println);
-
- //获取前n个元素--limit
- //Stream.concat(stream1,stream2).limit(5).forEach(System.out::println);
-
- //跳过前n个元素
- Stream.concat(stream1,stream2).skip(2).forEach(System.out::println);
- }
- }
- List
personList = new ArrayList<>(); - personList.add(new Person("Tom",24,"美国",'M'));
- personList.add(new Person("欧阳雪",18,"中国",'F'));
- personList.add(new Person("Harley",22,"英国",'F'));
- personList.add(new Person("小梅",20,"中国",'F'));
- personList.add(new Person("向天笑",20,"中国",'M'));
- personList.add(new Person("李康",22,"中国",'M'));
- personList.add(new Person("何雪",21,"中国",'F'));
- personList.add(new Person("李康",22,"中国",'M'));
-
- //find操作-- findFirst 获取流中第一个元素
- // Optional
first = personList.stream().findFirst(); - // System.out.println(first.get());
- //find操作---findAny() 获取流中任意一个元素 必须使用并行流测试
- Optional
any = personList.parallelStream().findAny(); - System.out.println(any.get());
- List
personList = new ArrayList<>(); - personList.add(new Person("Tom",24,"美国",'M'));
- personList.add(new Person("欧阳雪",18,"中国",'F'));
- personList.add(new Person("Harley",22,"英国",'F'));
- personList.add(new Person("小梅",20,"中国",'F'));
- personList.add(new Person("向天笑",20,"中国",'M'));
- personList.add(new Person("李康",22,"中国",'M'));
- personList.add(new Person("何雪",21,"中国",'F'));
- personList.add(new Person("李康",22,"中国",'M'));
-
- //匹配操作--所有元素都必须匹配条件 才返回true
- // boolean b = personList.stream().allMatch(item -> item.getAge() > 10);
- // System.out.println(b);
- boolean b = personList.stream().anyMatch(item -> item.getAge() > 50);
- System.out.println(b);

- List
personList = new ArrayList<>(); - personList.add(new Person("Tom",24,"美国",'M'));
- personList.add(new Person("欧阳雪",18,"中国",'F'));
- personList.add(new Person("Harley",22,"英国",'F'));
- personList.add(new Person("小梅",20,"中国",'F'));
- personList.add(new Person("向天笑",20,"中国",'M'));
- personList.add(new Person("李康",22,"中国",'M'));
- personList.add(new Person("何雪",21,"中国",'F'));
- personList.add(new Person("李康",22,"中国",'M'));
-
- //聚合操作---count
- // long count = personList.stream().count();
- // System.out.println("个数:"+count);
- //聚合操作---max min
- Optional
max = personList.stream().max((o1, o2) -> o1.getAge() - o2.getAge()); - System.out.println(max.get());

- public class Test05 {
- public static void main(String[] args) {
- Integer [] arr={2,3,4,5,6,2};
-
- //第一次赋值时,会把集合中的前两个元素赋值于t1 t2 后面会把方法计算的结果赋予t1 在集合的后面的元素赋予t2
- Optional
reduce = Arrays.stream(arr).reduce((t1, t2) -> t1+=t2); - System.out.println(reduce.get());
- }
- }
计数: count
平均值: averagingInt、 averagingLong、 averagingDouble
最值: maxBy、 minBy
求和: summingInt、 summingLong、 summingDouble
- List
personList = new ArrayList<>(); - personList.add(new Person("Tom",24,"美国",'M'));
- personList.add(new Person("欧阳雪",18,"中国",'F'));
- personList.add(new Person("Harley",22,"英国",'F'));
- personList.add(new Person("小梅",20,"中国",'F'));
- personList.add(new Person("向天笑",20,"中国",'M'));
- personList.add(new Person("李康",22,"中国",'M'));
- personList.add(new Person("何雪",21,"中国",'F'));
- personList.add(new Person("李康",22,"中国",'M'));
-
- // Long collect =personList.stream().collect(Collectors.counting());
- // System.out.println(collect);
- // Double collect = personList.stream().collect(Collectors.averagingInt(item -> item.getAge()));
- // System.out.println(collect);
- // Optional
collect = personList.stream().collect(Collectors.maxBy(((o1, o2) -> o1.getAge() - o2.getAge()))); - // System.out.println(collect);
-
- Integer collect = personList.stream().collect(Collectors.summingInt(item -> item.getAge()));
- System.out.println(collect);
搜集为一个新的集合。
- List
personList = new ArrayList<>(); - personList.add(new Person("Tom",24,"美国",'M'));
- personList.add(new Person("欧阳雪",18,"中国",'F'));
- personList.add(new Person("Harley",22,"英国",'F'));
- personList.add(new Person("小梅",20,"中国",'F'));
- personList.add(new Person("向天笑",20,"中国",'M'));
- personList.add(new Person("李康",22,"中国",'M'));
- personList.add(new Person("何雪",21,"中国",'F'));
-
- // Set
set = personList.stream().filter(item -> item.getAge() > 20) - // .filter(item -> item.getCountry().equals("中国"))
- // .map(item -> item.getName())
- // .collect(Collectors.toSet());
- // System.out.println(set);
- Map
map = personList.stream().filter(item -> item.getAge() > 20) - .filter(item -> item.getCountry().equals("中国"))
- .collect(Collectors.toMap(item -> item.getName(), item -> item));
- System.out.println(map);
分组操作
- List
personList = new ArrayList<>(); - personList.add(new Person("Tom",24,"美国",'M'));
- personList.add(new Person("欧阳雪",18,"中国",'F'));
- personList.add(new Person("Harley",22,"英国",'F'));
- personList.add(new Person("小梅",20,"中国",'F'));
- personList.add(new Person("向天笑",20,"中国",'M'));
- personList.add(new Person("李康",22,"中国",'M'));
- personList.add(new Person("何雪",21,"中国",'F'));
-
- Map
> collect = personList.stream().collect(Collectors.groupingBy(item -> item.getSex())); - System.out.println(collect);
- public class Test {
- public static void main(String[] args) {
- // //自定义时间的日期---设计不合理。
- // Date date=new Date(2022,11,5);
- // System.out.println(date);
- //
- // //时间格式转化---存在线程安全问题
- SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
- // System.out.println(sdf.format(date));
-
- for (int i = 0; i <10 ; i++) {
- new Thread(new Runnable() {
- @Override
- public void run() {
- try {
- System.out.println(sdf.parse("2022-11-05"));
- } catch (ParseException e) {
- e.printStackTrace();
- }
- }
- }).start();
- }
- }
- }
日期时间类设计不合理---两个包下都有Date. Date的年需要从1900算起。
日期转化类存在线程安全问题。
jdk8后提供了新的日期时间类以及转化类。java.time包下


- public class Test {
- public static void main(String[] args) {
- //创建一个指定日期时间的类
- LocalDateTime dateTime = LocalDateTime.of(2022, 10, 11, 17, 18, 16);
- //创建当前的日期时间对象
- LocalDateTime now = LocalDateTime.now();
-
- System.out.println("指定的日期时间:"+dateTime.toString());
- System.out.println("当前的日期时间:"+now);
- }
-
- private static void getTime(){
- //获取一个指定的时间
- LocalTime time = LocalTime.of(11, 11, 11);
- //获取当前的时间
- LocalTime now = LocalTime.now();
- System.out.println("指定的时间:"+time);
- System.out.println("当前的时间:"+now);
-
- //时间类中常用的方法
- System.out.println("获取时间的小时:"+now.getHour());
- System.out.println("获取时间的分钟:"+now.getMinute());
- System.out.println("获取时间的秒:"+now.getSecond());
- System.out.println("获取时间的纳秒:"+now.getNano());
- }
- private static void getDate(){
- //创建一个LocalDate日期类。--创建指定的日期
- LocalDate date = LocalDate.of(2022, 10, 7);
- //创建一个当前日期
- LocalDate now = LocalDate.now();
-
- System.out.println("指定的日期:"+date);
- System.out.println("当前日期:"+now);
-
- //日期类中的常见的方法
- System.out.println("获取日期的年份:"+now.getYear());
- System.out.println("获取日期的月份:"+now.getMonth().getValue());
- System.out.println("获取日期的星期:"+now.getDayOfWeek().getValue());
- }
- }
DateTimeFormate 可以进行日期时间和字符串的转化
(1) 把日期时间转化为指定格式的字符串。
- public static void main(String[] args) {
- LocalDateTime now = LocalDateTime.now();
- System.out.println("转化前的日期时间:"+now);
- DateTimeFormatter dtf=DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
-
- String format = now.format(dtf);
- System.out.println("转化后:"+format);
- }
(2)把字符串转化为日期时间对象
- public static void main(String[] args) {
- DateTimeFormatter dtf=DateTimeFormatter.ofPattern("yyyy/MM/dd HH:mm:ss");
- LocalDateTime dateTime = LocalDateTime.parse("2020/11/17 22:22:22", dtf);
- System.out.println(dateTime);
- }

- public class Test {
- public static void main(String[] args) {
- LocalDate date = LocalDate.of(2020, 11, 1);
- LocalDate now = LocalDate.now();
- //比较两个日期的距离
- Period period = Period.between(date, now);
- System.out.println("相差的年:"+ period.getYears());
- System.out.println("相差的月:"+ period.getMonths());
- System.out.println("相差的天:"+ period.getDays());
-
- LocalTime time = LocalTime.of(8, 12, 12);
- LocalTime now1 = LocalTime.now();
- Duration between = Duration.between(time, now1);
- System.out.println(between.toHours());
- System.out.println(between.toMinutes()); //时间与时间之间相差的分钟
- System.out.println(between.getSeconds());//时间与时间之间相差的秒
-
-
- }
- }