• java8新特性


    Lambda表达式

    Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。

        //原来的匿名内部类
        @Test
        public void test1(){
            Comparator<Integer> comparator = new Comparator<Integer>() {
                @Override
                public int compare(Integer o1, Integer o2) {
                    return Integer.compare(o1,o2);
                }
            };
            TreeSet<Integer> ts = new TreeSet<>(comparator);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
        //Lambda表达式
        @Test
        public void test2(){
            Comparator<Integer> comparator = (x,y) -> Integer.compare(x,y);
            TreeSet<Integer> ts = new TreeSet<>(comparator);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    实例

    员工实体类

    package com.xxxx.lln;
    
    /**
     * 员工实体
     */
    public class Employee {
    
        private String name;
        private int age;
        private double salary;
    
        public Employee() {
        }
    
        public Employee(String name, int age, double salary) {
            this.name = name;
            this.age = age;
            this.salary = salary;
        }
    
        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;
        }
    
        public double getSalary() {
            return salary;
        }
    
        public void setSalary(double salary) {
            this.salary = salary;
        }
    
        @Override
        public String toString() {
            return "Employee{" +
                    "name='" + name + '\'' +
                    ", age=" + age +
                    ", salary=" + salary +
                    '}';
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    定义员工集合

        //员工集合
        List<Employee> employees = Arrays.asList(
                new Employee("张三",18,9999.99),
                new Employee("李四",38,6666.66),
                new Employee("王五",35,5555.55),
                new Employee("赵六",13,3333.33),
                new Employee("田七",26,8888.88)
        );
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    需求1:获取年龄大于35的员工信息

    	//过滤
        public List<Employee> filterEmployees(List<Employee> list){
            List<Employee> emps =new ArrayList<>();
    
            for (Employee emp : list) {
                if (emp.getAge()>=35){
                    emps.add(emp);
                }
            }
            return emps;
        }
    
        //调用
        @Test
        public void test3(){
            List<Employee> list = filterEmployees(employees);
            for(Employee emp : list){
                System.out.println(emp.toString());
            }
        }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21

    在这里插入图片描述

    需求2:获取工资大于5000的员工信息
    
    • 1
        //过滤
        public List<Employee> filterEmployees2(List<Employee> list){
            List<Employee> emps =new ArrayList<>();
            for (Employee emp : list) {
                if (emp.getSalary()>=5000){//只改变了方法名和这一句
                    emps.add(emp);
                }
            }
            return emps;
        }
        //调用
        ......
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    每次都要写过滤函数,太麻烦了

    优化方式一:策略设计模式

    定义一个接口类

    package com.xxxx.lln;
    
    /**
     * 接口类
     * @param 
     */
    public interface MyPredicate<T>{
    
        public boolean test(T t);
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11

    定义过滤的方法函数

        //过滤员工,需要传入员工集合和过滤条件的接口类
        public List<Employee> filterEmployee(List<Employee> list , MyPredicate<Employee> mp){
            List<Employee> emps = new ArrayList<>();
            for (Employee employee:list) {
                if (mp.test(employee)){
                    emps.add(employee);
                }
            }
            return emps;
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    需要的时候去实现接口类

    package com.xxxx.lln;
    
    /**
     * 过滤年龄大于35
     */
    public class FilterEmployeeByAge implements MyPredicate<Employee>{
        @Override
        public boolean test(Employee employee) {
            return employee.getAge()>=35;
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    /**
     * 过滤工资大于5000
     */
    public class FilterEmployeeBySalary implements MyPredicate<Employee>{
        @Override
        public boolean test(Employee employee) {
            return employee.getSalary()>=5000;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    调用:

        @Test
        public void test4(){
            List<Employee> list = filterEmployee(employees,new FilterEmployeeByAge());
            for (Employee employee : list) {
                System.out.println(employee);
            }
    
            System.out.println("------------------------------------");
    
            List<Employee> list2 = filterEmployee(employees,new FilterEmployeeBySalary());
            for (Employee employee : list2) {
                System.out.println(employee);
            }
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    优化方式二:匿名内部类

        @Test
        public void test5(){
            List<Employee> list = filterEmployee(employees, new MyPredicate<Employee>() {
                @Override
                public boolean test(Employee employee) {
                    return employee.getSalary()>=5000;
                }
            });
            for (Employee employee : list){
                System.out.println(employee);
            }
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12

    在这里插入图片描述

    优化方式三:Lambda表达式

        //语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)
        @Test
        public void test6(){
        	//仍需要调用过滤的那个接口
            List<Employee> list = filterEmployee(employees,(e) -> e.getSalary() >= 5000);
            list.forEach(System.out::println);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    在这里插入图片描述

    优化方式四:Stream API

        @Test
        public void test7(){
        	//不需要用上面的接口
            employees.stream()
                    .filter((e) -> e.getSalary() >= 5000)
                    .limit(2)//取前两个
                    .forEach(System.out::println);
    
            System.out.println("---------------------------");
    
            //把所有名字拿出来
            employees.stream()
                    .map(Employee::getName)
                    .forEach(System.out::println);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    在这里插入图片描述

    Lambda表达式语法

    Lambda 表达式在Java 语言中引入了一个新的语法元 素和操作符。这个操作符为 -> , 该操作符被称 为 Lambda 操作符或剪头操作符。

    它将 Lambda 分为 两个部分:
    左侧:指定了 Lambda 表达式需要的所有参数
    右侧:指定了 Lambda 体,即 Lambda 表达式要执行的功能。


    在这里插入图片描述

    这里给出六个接口,后文的全部操作都利用这六个接口来进行阐述。

    /**多参数无返回*/
    @FunctionalInterface
    public interface NoReturnMultiParam {
        void method(int a, int b);
    }
    
    /**无参无返回值*/
    @FunctionalInterface
    public interface NoReturnNoParam {
        void method();
    }
    
    /**一个参数无返回*/
    @FunctionalInterface
    public interface NoReturnOneParam {
        void method(int a);
    }
    
    /**多个参数有返回值*/
    @FunctionalInterface
    public interface ReturnMultiParam {
        int method(int a, int b);
    }
    
    /*** 无参有返回*/
    @FunctionalInterface
    public interface ReturnNoParam {
        int method();
    }
    
    /**一个参数有返回值*/
    @FunctionalInterface
    public interface ReturnOneParam {
        int method(int a);
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    语法形式为 () -> {},其中 () 用来描述参数列表,{} 用来描述方法体,-> 为 lambda运算符 ,读作(goes to)。

    import lambda.interfaces.*;
    
    public class Test1 {
        public static void main(String[] args) {
            //无参无返回
            NoReturnNoParam noReturnNoParam = () -> {
                System.out.println("NoReturnNoParam");
            };
            noReturnNoParam.method();
    
            //一个参数无返回
            NoReturnOneParam noReturnOneParam = (int a) -> {
                System.out.println("NoReturnOneParam param:" + a);
            };
            noReturnOneParam.method(6);
    
            //多个参数无返回
            NoReturnMultiParam noReturnMultiParam = (int a, int b) -> {
                System.out.println("NoReturnMultiParam param:" + "{" + a +"," + + b +"}");
            };
            noReturnMultiParam.method(6, 8);
    
            //无参有返回值
            ReturnNoParam returnNoParam = () -> {
                System.out.print("ReturnNoParam");
                return 1;
            };
    
            int res = returnNoParam.method();
            System.out.println("return:" + res);
    
            //一个参数有返回值
            ReturnOneParam returnOneParam = (int a) -> {
                System.out.println("ReturnOneParam param:" + a);
                return 1;
            };
    
            int res2 = returnOneParam.method(6);
            System.out.println("return:" + res2);
    
            //多个参数有返回值
            ReturnMultiParam returnMultiParam = (int a, int b) -> {
                System.out.println("ReturnMultiParam param:" + "{" + a + "," + b +"}");
                return 1;
            };
    
            int res3 = returnMultiParam.method(6, 8);
            System.out.println("return:" + res3);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51

    Lambda 语法简化

    我们可以通过观察以下代码来完成代码的进一步简化,写出更加优雅的代码。

    import lambda.interfaces.*;
    
    public class Test2 {
        public static void main(String[] args) {
    
            //1.简化参数类型,可以不写参数类型,但是必须所有参数都不写
            NoReturnMultiParam lamdba1 = (a, b) -> {
                System.out.println("简化参数类型");
            };
            lamdba1.method(1, 2);
    
            //2.简化参数小括号,如果只有一个参数则可以省略参数小括号
            NoReturnOneParam lambda2 = a -> {
                System.out.println("简化参数小括号");
            };
            lambda2.method(1);
    
            //3.简化方法体大括号,如果方法条只有一条语句,则可以省略方法体大括号
            NoReturnNoParam lambda3 = () -> System.out.println("简化方法体大括号");
            lambda3.method();
    
            //4.如果方法体只有一条语句,并且是 return 语句,则可以省略方法体大括号
            ReturnOneParam lambda4 = a -> a+3;
            System.out.println(lambda4.method(5));
    
            ReturnMultiParam lambda5 = (a, b) -> a+b;
            System.out.println(lambda5.method(1, 1));
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30

    上述 Lambda 表达式中的参数类型都是由编译器推断 得出的。Lambda 表达式中无需指定类型,程序依然可 以编译,这是因为 javac 根据程序的上下文,在后台 推断出了参数的类型。Lambda 表达式的类型依赖于上 下文环境,是由编译器推断出来的。这就是所谓的 “ 类型推断”。

     

    函数式接口

    什么是函数式接口

    • 只包含一个抽象方法的接口,称为函数式接口。
    • 你可以通过 Lambda 表达式来创建该接口的对象。(若 Lambda 表达式抛出一个受检异常,那么该异常需要在目标接口的抽象方法上进行声明)。
    • 我们可以在任意函数式接口上使用 @FunctionalInterface 注解, 这样做可以检查它是否是一个函数式接口,同时 javadoc 也会包含一条声明,说明这个接口是一个函数式接口。

    自定义函数式接口

        @FunctionalInterface
        public interface MyNumber{
            public double getValue();
        }
    
    • 1
    • 2
    • 3
    • 4

    函数式接口中使用泛型:

        @FunctionalInterface
        public interface MyFunction<T>{
            public T getValue();
        }
    
    • 1
    • 2
    • 3
    • 4

    作为参数传递Lambda表达式

        public String toUpperString(MyFunction<String> m,String s){
            return m.getValue(s);
        }
        //作为参数传递
        String newStr = toUpperString((str)->str.toUpperCase(),"abcdef");
        System.out.println(newStr);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6

    需求:对一个数进行运算

    
    
        @FunctionalInterface
        public interface MyFunction {
            public Integer getValue(Integer num);
        }
    
        
        public Integer operation(Integer num , MyFunction m){
            return m.getValue(num);
        }
        
        
        @Test
        public void test(){
            Integer num = operation(100,x -> x * x);
            System.out.println(num);
    
    		System.out.println(operation(200,x -> x+300));
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    在这里插入图片描述

    Java 内置四大核心函数式接口

    在这里插入图片描述

     

    方法引用与构造器引用

    当要传递给Lambda体的操作,已经有实现的方法了,可以使用方法引用!
    实现抽象方法的参数列表,必须与方法引用方法的参数列表保持一致!
    方法引用:使用操作符 “::” 将方法名和对象或类的名字分隔开来。

    如下三种主要使用情况:

    • 对象::实例方法
    • 类::静态方法
    • 类::实例方法

    在这里插入图片描述
    在这里插入图片描述

    注意:当需要引用方法的第一个参数是调用对象,并且第二个参数是需要引用方法的第二个参数(或无参数)时:ClassName::methodName

            //对象::实例方法名
            //Consumer con = x -> System.out.println(x);
            Consumer<String> con = System.out::println;
            con.accept("asdfghjkl");
    
            System.out.println("------------------------------------");
    
            Employee emp = new Employee("lln",18,999);
            //Supplier supplier = () -> emp.getName();
            Supplier<String> supplier = emp::getName;
            System.out.println(supplier.get());
    
            System.out.println("------------------------------------");
    
            //类::静态方法名
            Comparator<Integer> com = (x,y) -> Integer.compare(x,y);
            //Comparator com = Integer::compare;
            System.out.println(com.compare(1,2));
    
            System.out.println("------------------------------------");
    
            //类::实例方法名
            //BiPredicate bp = (x,y)->x.equals(y);
            //规则:第一个参数是方法的调用者,第二个参数是要调用方法的参数时,可以使用类::实例方法名
            BiPredicate<String,String> bp = String::equals;
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25

    构造器引用

    与函数式接口相结合,自动与函数式接口中方法兼容。 可以把构造器引用赋值给定义的方法,构造器参数列表要与接口中抽象方法的参数列表一致!

    ClassName::new

    在这里插入图片描述

    interface ItemCreatorBlankConstruct {
        Item getItem();
    }
    interface ItemCreatorParamContruct {
        Item getItem(int id, String name, double price);
    }
    
    public class Exe2 {
        public static void main(String[] args) {
            ItemCreatorBlankConstruct creator = () -> new Item();
            Item item = creator.getItem();
    
            ItemCreatorBlankConstruct creator2 = Item::new;
            Item item2 = creator2.getItem();
    
            ItemCreatorParamContruct creator3 = Item::new;
            Item item3 = creator3.getItem(112, "鼠标", 135.99);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19

    数组引用

    在这里插入图片描述

            //数组引用
            //Function fun = (x) -> new String[x];
            Function<Integer,String[]> fun = String[]::new;
            String[] strs = fun.apply(10);
            System.out.println(strs.length);
    
    • 1
    • 2
    • 3
    • 4
    • 5

     

    Stream API

    Java8中有两大最为重要的改变。第一个是 Lambda 表达式;另外一 个则是 Stream API(java.util.stream.*)。

    Stream 是 Java8 中处理集合的关键抽象概念,它可以指定你希望对 集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。

    使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。

    也可以使用 Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

    流(Stream) 到底是什么呢?

    是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。

    “集合讲的是数据,流讲的是计算!”

    注意:
    ①Stream 自己不会存储元素。
    ②Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
    ③Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

    在这里插入图片描述

     

    创建Stream

    1.可以通过Collection系列集合提供的stream()或parallelStream()

    Java8 中的 Collection 接口被扩展,提供了 两个获取流的方法:

    • default Stream stream() : 返回一个顺序流
    • default Stream parallelStream() : 返回一个并行流
        List<String> list = new ArrayList<>();
        Stream<String> stream1 = list.stream();
    
    • 1
    • 2

    2.由数组创建

    Java8 中的 Arrays 的静态方法 stream() 可 以获取数组流:

    static Stream stream(T[] array): 返回一个流

        Employee[] emps = new Employee[10];
        Stream<Employee> stream2 = Arrays.stream(emps);
    
    • 1
    • 2

    3.由值创建流

    通过Stream类中的静态方法of()

    可以使用静态方法 Stream.of(), 通过显示值 创建一个流。它可以接收任意数量的参数。

    Stream<String> stream3 = Stream.of("aa","bb","cc");
    
    • 1

    4.由函数创建流:创建无限流

    可以使用静态方法 Stream.iterate() 和 Stream.generate(), 创建无限流。

    • 迭代 public static Stream iterate(final T seed, final UnaryOperator f)

    • 生成 public static Stream generate(Supplier s) :

            //迭代
            Stream<Integer> stream4 = Stream.iterate(0,(x) -> x + 2);
            stream4.limit(10)
                    .forEach(System.out::println);
    
            //生成
            Stream.generate(()->Math.random())
                    .limit(5)
                    .forEach(System.out::println);
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9

    Stream 的中间操作

    多个中间操作可以连接起来形成一个流水线,除非流水 线上触发终止操作,否则中间操作不会执行任何的处理! 而在终止操作时一次性全部处理,称为“惰性求值”。

        //员工集合
        List<Employee> employees = Arrays.asList(
                new Employee("张三",18,9999.99),
                new Employee("李四",38,6666.66),
                new Employee("王五",35,5555.55),
                new Employee("赵六",13,3333.33),
                new Employee("田七",26,8888.88)
        );
    
        //内部迭代:迭代操作由Stream API完成
        @Test
        public void test1(){
            //中间操作:不会执行任何操作
            Stream<Employee> stream = employees.stream()
                    .filter((e)->e.getAge()>35);
            //终止操作:一次性执行全部内容,即“惰性求值”
            stream.forEach(System.out::println);
    
        }
    
    
        //外部迭代
        @Test
        public void test2(){
    
            Iterator<Employee> it = employees.iterator();
    
            while(it.hasNext()){
                System.out.println(it.next());
            }
            
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    筛选与切片

    在这里插入图片描述

        @Test
        public void test3(){
            employees.stream()
                    .filter((e)->e.getSalary()>5000)
                    .limit(2)
                    .forEach(System.out::println);
        }
    //只要迭代到满足条件的两个数据后,后续操作就不进行了
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
        @Test
        public void test4(){
            employees.stream()
                    .filter((e)->e.getSalary()>5000)
                    //跳过前两个满足条件的数据
                    .skip(2)
                    .forEach(System.out::println);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8

    去重

        @Test
        public void test5(){
            employees.stream()
                    .filter((e)->e.getSalary()>5000)
                    .distinct()
                    .forEach(System.out::println);
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7

    映射

    在这里插入图片描述

        @Test
        public void test6(){
            List<String> list = Arrays.asList("aaa","bbb","ccc");
            list.stream()
                    .map((str)->str.toUpperCase())
                    .forEach(System.out::println);
    
            System.out.println("--------------------");
    
            //提取名字
            employees.stream()
                    .map(Employee::getName)
                    .distinct()
                    .forEach(System.out::println);
    
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16

    flatMap

        @Test
        public void test7(){
            List<String> list = Arrays.asList("aaa","bbb","ccc");
    //        {{a,a,a},{b,b,b},{c,c,c}}
    //        Stream> stream = list.stream()
    //                .map(TestStreamAPI2::filterCharacter);
    //
    //        stream.forEach((sm)->{
    //            sm.forEach(System.out::println);
    //        });
    
            System.out.println("-----------------------");
    
            //{a,a,a,b,b,b,c,c,c}
            Stream<Character> sm = list.stream()
                    .flatMap(TestStreamAPI2::filterCharacter);
            sm.forEach(System.out::println);
            
        }
    
    
        public static Stream<Character> filterCharacter(String str){
            List<Character> list = new ArrayList<>();
    
            for (Character ch : str.toCharArray()){
                list.add(ch);
            }
            return list.stream();
        }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    排序

    在这里插入图片描述

    Stream的终止操作

    终端操作会从流的流水线生成结果。其结果可以是任何不是流的 值,例如:List、Integer,甚至是 void 。

    查找和匹配

    allMatch——检查是否匹配所有元素 传入断定型接口

    anyMatch——检查是否至少匹配一个元素 传入断定型接口

    noneMatch——检查是否没有匹配的元素 传入断定型接口

    findFirst——返回第一个元素

    findAny——返回当前流中的任意一个元素

    count——返回流中元素的总个数

    max——返回流中最大值 传入Comparator接口

    min——返回流中最小值 传入Comparator接口

     

    接口中的默认方法与静态方法

    新时间日期API

    其他新特性

  • 相关阅读:
    Git使用指南
    C#,机器学习的KNN(K Nearest Neighbour)算法与源代码
    使用 shell 脚本拼接 srt 字幕文件 (srtcat)
    【C语言】23-结构体类型
    英雄联盟|王者|穿越火线 bgm AI配乐大赛分享
    使用 Docker 部署 WebTop 运行 Linux 系统
    Tech Lead如何组建你的全明星团队
    Hadoop学习笔记(1)
    同样的报告,你跪求IT部门排需求,而我会了这个工具就能实时分析
    简单的分布式锁+队列
  • 原文地址:https://blog.csdn.net/lln1540295459/article/details/126240838