Java的高级篇--JDK8的新特性

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);
        }
    }
}

分析:

这段代码中含有三个循环,每一个作用不同:

  1. 首先筛选所有姓张的人;

  2. 然后筛选名字有三个字的人;

  3. 最后进行对结果进行打印输出。

每当我们需要对集合中的元素进行操作的时候,总是需要进行循环、循环、再循环。这是理所当然的么?不是。循环 是做事情的方式,而不是目的。每个需求都要循环一次,还要搞一个新集合来装数据,如果希望再次遍历,只能再使 用另一个循环从头开始。

那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);


    }
}

运行结果:

猜你喜欢

转载自blog.csdn.net/Ysuhang/article/details/125906949
今日推荐