j8特性之:lambdb表达式

 

出自:https://blog.csdn.net/qq_28410283/article/details/80601495

Lambda 表达式:

//1.Lambda 表达式,也可称为闭包,它是推动 Java 8 发布的最重要新特性。
//2.Lambda 允许把函数作为一个方法的参数(函数作为参数传递进方法中)。
//3.使用 Lambda 表达式可以使代码变的更加简洁紧凑。
/*以下是lambda表达式的重要特征:
可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。*/

    1.   左侧:lambda表达式的参数列表
    2.   右侧:lambda表达式中所需要执行的功能,即lambda函数体
    3   .lambda表达式语法格式有三种:

1).无参数,无返回值的用法 :( ) -> System.out.println("hello lambda");

 2). 有一个参数,无返回值的用法: (x) -> System.out.println(x); 或者 x -> System.out.println(x);  一个参数,可以省略参数的小括号

3)有两个参数,有返回值的:(x, y) -> x + y

public void test4() {
  // 无返回值lambda函数体中用法
 //多行的,只需要用大括号{}把语句包含起来就可以了   
//只有一条语句的,大括号可以不用写;
        Runnable r1 = () -> {
            System.out.println("hello lambda1");
            System.out.println("hello lambda2");
            System.out.println("hello lambda3");
        };
        r1.run();
 
 // 有返回值lambda函数体中用法
//有返回值和无返回值的,只有一个return的区别
//只有一条语句的,renturn都可以不用写;
        BinaryOperator<Integer> binary = (x, y) -> {
            int a = x * 2;
            int b = y + 2;
            return a + b;
        };
        System.out.println(binary.apply(1, 2));// 6
    }

2.方法的引用的语法,主要有三类

1.指向静态方法的方法引用,例如Integer的parseInt方法 ,可以写成 Integer::parseInt

     类::静态方法名

2.指向任意类型实例方法的方法引用,例如String的length方法,写成 String::length;

    类::实例方法名

3.指向现有对象的实例方法的方法引用

    对象::实例方法名

构造器的引用:对于一个现有构造函数,你可以利用它的名称和关键字new来创建它的一个引用ClassName::new;

public static void main(String args[]){
       
        /*************** 方法的引用 ****************/
        // 类::静态方法名
        Comparator<Integer> cam1 = (x, y) -> x.compareTo(y);
        System.out.println(cam1.compare(2, 4));
        Comparator<Integer> cam = Integer::compareTo;
        System.out.println(cam.compare(3, 2));
        // 类::实例方法名
        BiPredicate<String, String> bp = (x, y) -> x.equals(y);
        System.out.println(bp.test("a", "b"));
        BiPredicate<String, String> bp1 = String::equals;
        System.out.println(bp1.test("a", "b"));

        // 对象::实例方法名
        Consumer<String> con1 = x -> System.out.println(x);
        con1.accept("abc");
        Consumer<String> con = System.out::println;
        con.accept("abc");

        Emp emp = new Emp("上海", "xiaoMIng", 18);
        Supplier<String> supper1 = () -> emp.getAddress();
        System.out.println(supper1.get());
        Supplier<String> supper = emp::getAddress;
        System.out.println(supper.get());

        /*************** 构造器的引用 ****************/
        // 无参构造函数,创建实例
        Supplier<Emp> supper2 = () -> new Emp();
        Supplier<Emp> supper3 = Emp::new;
        Emp emp1 = supper3.get();
        emp1.setAddress("上海");
        System.out.println("emp1="+emp1.toString());
        
        // 一个参数
        Function<String, Emp> fun = address -> new Emp(address);
        Function<String, Emp> fun1 = Emp::new;
        System.out.println("beijing="+fun1.apply("beijing"));
        
        // 两个参数
        BiFunction<String, Integer, Emp> bFun = (name, age) -> new Emp(name, age);
        BiFunction<String, Integer, Emp> bFun1 = Emp::new;
        System.out.println("xiaohong="+bFun1.apply("xiaohong", 18));

    }

3、java8 函数式接口简介:https://blog.csdn.net/qq_28410283/article/details/80962325

4、Stream接口简介:   流是java API中的新的成员,它可以让你用声明式的方式处理集合,简单点说,可以看成遍历数据的一个高级点的迭代器。

1.Arrays.stream,我们可以通过Arrays的静态方法,传入一个泛型数组,创建一个流。

2.Stream.of,我们可以通过Stream的静态方法,传入一个泛型数组,或者多个参数,创建一个流,这个静态方法,也是调用了Arrays的stream静态方法,如下

System.out.println(Stream.of("one", "two", "three", "four").filter(e -> e.length() > 3));

通过stream里面抽象方法的定义,我们可以看到,这个方法,可以分成两种类型,一种返回类型为接口本身的Stream<T>,另外一种是返回其他对象类型的,返回接口类型的,我们称这些方法为中间操作,返回其他具体类型的,我们称为终端操作;

5、Stream接口之

⑥对对象的操作:peek
⑥统计个数:count
⑦取用前几个:limit
⑧跳过前几个:skip
⑨组合数组:concat
⑩排序:sorted:
  sorted()   自然排序
  sorted(Comparator com)   定制排序
  allMatch   检查是否匹配所有元素
  anyMatch   检查是否至少匹配一个元素
  noneMatch   检查是否没有匹配所有元素
  findFirst   返回第一个元素
  findAny   返回当前流中的任意元素
  count   返回流中元素的总个数
  max   返回流中最大值
  min   返回流中最小值

?Collect:  将流转换为其他形式。接收一个Collector的实现,用于给stream中元素做汇总的方法。
?map映射,  用来归类,结果一般是一组数据,比如可以将list中的学生分数映射到一个新的stream中。
?reduce规约, 用来计算值,结果是一个值,比如计算最高分。
④flatMap    接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。即对流扁平化处理,浅显一点解释就是把几个小的list转换到一个大的list

6.并行流和顺序流:
并行流是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。
通过parallel()与sequential()可以实现并行流和顺序流之间的切换。

7、流的实例用法demo:

 

package jdk18meths;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
 
public class TestJava8 {
    public static List<Emp> list = new ArrayList<>();
    static {
        list.add(new Emp("xiaoHong1", 20, 1000.0));
        list.add(new Emp("xiaoHong2", 25, 2000.0));
        list.add(new Emp("xiaoHong3", 30, 3000.0));
        list.add(new Emp("xiaoHong4", 35, 4000.0));
        list.add(new Emp("xiaoHong5", 38, 5000.0));
        list.add(new Emp("xiaoHong6", 45, 9000.0));
        list.add(new Emp("xiaoHong7", 55, 10000.0));
        list.add(new Emp("xiaoHong8", 42, 15000.0));
    }
 
    public static void main(String[] args) {
        // 对数组流,先过滤重复,在排序,再控制台输出 1,2,3
        List arr =Arrays.asList(3, 1, 2, 1).stream().distinct().sorted().collect(Collectors.toList());
        System.out.println(arr);
        
        // 对list里的emp对象,取出薪水,并对薪水进行排序,然后输出薪水的内容,map操作,改变了Strenm的泛型对象
        List list2= list.stream().map(emp -> emp.getSalary()).sorted().collect(Collectors.toList());
        System.out.println(list2);
        
        //peek  给年纪大于30岁的人,薪水提升1.5倍,并输出结果
        List<Emp> stream = list.stream().filter(emp -> {
            return emp.getAge() > 30;
        }).peek(emp -> {
            emp.setSalary(emp.getSalary() * 1.5);
        }).collect(Collectors.toList());
        
        stream.forEach(s -> System.out.println(s.getName()));
        System.out.println("stream="+stream.toString());
        
        //peek
        List list = Stream.of("one", "two", "three", "four").filter(e -> e.length() > 3).peek(e -> e.equals("four"))
        .map(String::toUpperCase).collect(Collectors.toList());
        System.out.println(list);
        
        //把2个数组组合在一起
        Stream<String> stream1 = Stream.of("陈奕迅", "陈伟霆", "陈七", "钟汉良");
        String[] arr2 = {"1","2","3"};
        Stream<String> stream2 = Stream.of(arr2);
        Stream<String> concatStream = Stream.concat(stream1, stream2);
        concatStream.forEach(str-> System.out.println(str));
        System.out.println(concatStream);
        //另一种方法:flatMap
        //接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流。即对流扁平化处理,浅显一点解释就是把几个小的list转换到一个大的list
     }       
 
    public static class Emp {
        @Override
        public String toString() {
            return "Emp [name=" + name + ", age=" + age + ", salary=" + salary + "]";
        }
        private String name;
        private Integer age;
        private Double salary;
        public Emp(String name, Integer age, Double salary) {
            super();
            this.name = name;
            this.age = age;
            this.salary = salary;
        }
        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 getSalary() {
            return salary;
        }
        public void setSalary(Double salary) {
            this.salary = salary;
        }
 
    }

}

 

package jdk180reduce;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

public class StreamTest01 {
    public static void main(String[] args) {
        List<Student> stuList = new ArrayList<>(10);
        stuList.add(new Student("刘一", 85));
        stuList.add(new Student("陈二", 90));
        stuList.add(new Student("张三", 98));
        stuList.add(new Student("李四", 88));
        stuList.add(new Student("王五", 83));
        stuList.add(new Student("赵六", 95));
        stuList.add(new Student("孙七", 87));
        stuList.add(new Student("周八", 84));
        stuList.add(new Student("吴九", 100));
 
        //需求:列出90分以上的学生姓名,并按照分数降序排序
        List<Student> result1 = new ArrayList<>(10);
        result1 = stuList.stream().filter(s -> s.getScore()>=90)
                .sorted(Comparator.comparing(Student :: getScore).reversed())
                .collect(Collectors.toList());
        System.out.println(result1);  //list.stream().sorted(Comparator.reverseOrder());
        
    //计算学生总分  2个参数:初始值(即0+a[1]+a[2]+...)开始一直相加,    //reduce用来计算值,结果是一个值,比如计算最高分。
    Integer totalScore1 = stuList.stream().map(Student::getScore).reduce(0,(a,b) -> a + b);
    System.out.println("totalScore1="+totalScore1);
    
    //计算学生总分,一个参数忽略a[0]     返回Optional类型的数据,改类型是java8中新增的,主要用来避免空指针异常
    Optional<Integer> totalScore2 = stuList.stream().map(Student::getScore).reduce((a,b) -> a + b);
    System.out.println("totalScore2="+totalScore2.get());
         
    //计算最高分和最低分
    Optional<Integer> max = stuList.stream().map(Student::getScore).reduce(Integer::max);
    Optional<Integer> min = stuList.stream().map(Student::getScore).reduce(Integer::min);
    System.out.println("max="+max.get());
    System.out.println("min="+min.get());
    
    //stream没有sum求和的方法,但是有别的。
    //将stream转换为IntStream求和
    int totalScoreInt = stuList.stream().mapToInt(Student::getScore).sum();
    System.out.println("Int_totalScore="+totalScoreInt);
    //计算平均分
    OptionalDouble avgScore = stuList.stream().mapToInt(Student::getScore).average();
    System.out.println("avgScore="+avgScore.getAsDouble());
    //生成1~100之间的数字
    IntStream num = IntStream.rangeClosed(1, 100);
    System.out.println("num="+num.toString());
    
    List<String> lists = new ArrayList<>();
    lists.add("li");
    lists.add("zhang");
    lists.add("chen");
    //Match匹配
    boolean a = lists.stream().anyMatch(s -> s.startsWith("li"));
    System.out.println("li = " + a);
    //判断是否全为li开头的
    System.out.println(lists.stream().allMatch(s -> s.startsWith("li")));
    //判断一个字符在该集合中不存在
    System.out.println(lists.stream().noneMatch(s -> s.startsWith("li2")));
    
    
    //filter: filter方法的作用,是对这个boolean做判断,返回true判断之后的对象
    //返回字符串为a的值
    String[] dd = { "a", "b", "c" };
    java.util.stream.Stream<String> stream = Arrays.stream(dd);
    stream.filter(str -> str.equals("c")).forEach(System.out::println);   
 }

}
package jdk180reduce;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.IntSummaryStatistics;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.OptionalDouble;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;
 
 
public class TestJava8 {
    
    public static List<Emp> list = new ArrayList<>();
    static {
        list.add(new Emp("上海", "小名", 17));
        list.add(new Emp("北京", "小红", 18));
        list.add(new Emp("深圳", "小蓝", 19));
        list.add(new Emp("广州", "小灰", 20));
        list.add(new Emp("杭州", "小黄", 21));
        list.add(new Emp("贵阳", "小白", 22));
    }
 
   public static void main(String[] args) {
        // 转list
        List<String> names = list.stream().map(e -> e.getName()).collect(Collectors.toList());
        System.out.println("names="+names);
        
        // 转set
        Set<String> address = list.stream().map(emp -> emp.getName()).collect(Collectors.toSet());
        System.out.println("address="+address);
        
        // 转map,需要指定key和value,Function.identity()表示当前的Emp对象本身
        Map<String, Emp> map = list.stream().collect(Collectors.toMap(Emp::getName, Function.identity()));
        System.out.println("转map="+map);
        
        // 计算元素中的个数
        Long count = list.stream().collect(Collectors.counting());
        
        // 数据求和 summingInt summingLong,summingDouble
        Integer sumAges = list.stream().collect(Collectors.summingInt(Emp::getAge));
        int totalScoreInt = list.stream().mapToInt(Emp::getAge).sum();
        System.out.println("求和="+sumAges);
        System.out.println("求和2="+totalScoreInt);
        
        // 平均值 averagingInt,averagingDouble,averagingLong
        Double aveAges = list.stream().collect(Collectors.averagingInt(Emp::getAge));
        OptionalDouble avgScore = list.stream().mapToInt(Emp::getAge).average();
        System.out.println("平均值 1="+aveAges);
        System.out.println("平均值 2="+avgScore);
 
        // 综合处理的,求最大值,最小值,平均值,求和操作
        // summarizingInt,summarizingLong,summarizingDouble
        IntSummaryStatistics intSummary = list.stream().collect(Collectors.summarizingInt(Emp::getAge));
        System.out.println(intSummary.getAverage());// 19.5
        System.out.println(intSummary.getMax());// 22
        System.out.println(intSummary.getMin());// 17
        System.out.println(intSummary.getSum());// 117
 
        // 连接字符串,当然也可以使用重载的方法,加上一些前缀,后缀和中间分隔符
        String strEmp = list.stream().map(emp -> emp.getName()).collect(Collectors.joining());
        String strEmp1 = list.stream().map(emp -> emp.getName()).collect(Collectors.joining("-中间的分隔符-"));
        String strEmp2 = list.stream().map(emp -> emp.getName()).collect(Collectors.joining("-中间的分隔符-", "前缀*", "&后缀"));
        // 小名小红小蓝小灰小黄小白
        // 小名-中间的分隔符-小红-中间的分隔符-小蓝-中间的分隔符-小灰-中间的分隔符-小黄-中间的分隔符-小白
        // 前缀*小名-中间的分隔符-小红-中间的分隔符-小蓝-中间的分隔符-小灰-中间的分隔符-小黄-中间的分隔符-小白&后缀
        System.out.println(strEmp);
        System.out.println(strEmp1);
        System.out.println(strEmp2);
        
        // maxBy 按照比较器中的比较结果刷选 最大值
        Optional<Integer> maxAge = list.stream().map(emp -> emp.getAge()).collect(Collectors.maxBy(Comparator.comparing(Function.identity())));
        // 最小值
        Optional<Integer> minAge = list.stream().map(emp -> emp.getAge()).collect(Collectors.minBy(Comparator.comparing(Function.identity())));
        System.out.println("max:" + maxAge);
        System.out.println("min:" + minAge);
 
        // 归约操作
        list.stream().map(emp -> emp.getAge()).collect(Collectors.reducing((x, y) -> x + y));
        list.stream().map(emp -> emp.getAge()).collect(Collectors.reducing(0, (x, y) -> x + y));
        // 分操作 groupingBy 根据地址,把原list进行分组
        Map<String, List<Emp>> mapGroup = list.stream().collect(Collectors.groupingBy(Emp::getAddress));
        System.out.println("mapGroup:" + mapGroup);
        // partitioningBy 分区操作 需要根据类型指定判断分区
        Map<Boolean, List<Integer>> partitioningMap = list.stream().map(emp -> emp.getAge()).collect(Collectors.partitioningBy(emp -> emp > 20));
        System.out.println("partitioningMap:" + partitioningMap);
    }
 
    static class Emp {
        private String address;
 
        private String name;
 
        private Integer age;
 
        public Emp() {
 
        }
 
        public Emp(String address) {
            this.address = address;
        }
 
        public Emp(String name, Integer age) {
            this.name = name;
            this.age = age;
        }
 
        public Emp(String address, String name, Integer age) {
            super();
            this.address = address;
            this.name = name;
            this.age = age;
        }
 
        //get set 方法

}

 

j8特性之:lambdb表达式

上一篇:【学习总结】SQL的学习-4-常用函数介绍


下一篇:Python之MySQL数据库连接池DBUtils