java8新特性—lambda表达式和Stream API

lambda表达式

一个匿名函数 ,代码更简洁灵活。

格式:

​ -> 箭头操作符

箭头左边:lambda形参列表/其实就是接口中抽象方法的形参列表

箭头右边:lambda体 / 其实就是重写的抽象方法的方法体

注意: lambda 表达式针对的是==接口==

语法格式一:无参、无返回值

//非lambda表达式写法
Runnable l1=new Runnable() {
   @Override
   public void run() {
      System.out.println("测试一");
   }
 };
l1.run();
//lambda表达式写法
Runnable l2=()->System.out.println("测试二");
l2.run();

语法格式二:需要一个参数、无返回值

//非lambda表达式写法
Consumer<String> consumer=new Consumer<String>() {
    @Override
    public void accept(String s) {
        System.out.println(s);
    }
};
consumer.accept("什么是快乐呢");
//lambda表达式写法
Consumer<String> consumer2=(String s)->System.out.println(s);
consumer2.accept("什么是快乐呢2");

语法格式三:数据类型可以省略,由编译器推断得出,称为类型推断

Consumer<String> consumer2=(s)->System.out.println(s);//将String S的String省去
consumer2.accept("什么是快乐呢2");

语法格式四:lambda 若只要一个参数,参数的小括号也可以省略

Consumer<String> consumer4=s->System.out.println(s);//将格式三中的()删去
consumer2.accept("什么是快乐呢4");

语法格式五:Lambda 需要两个或以上的参数,多条执行语句,并且可以有返回值

Comparator<Integer> comparable=(o1, o2)->{
           System.out.println(o1);
           System.out.println(o2);
            return o1.compareTo(o2);
        };

语法格式六:当lambda 体只有一条语句的时候,return和大括号都可以省略

Comparator<Integer> comparable=(o1, o2)-> o1.compareTo(o2);

lambda 表达式本质:作为函数式接口(如果一个接口中只申明了一个抽象方法,则次接口称为函数式接口)的实例。

Stream API

使用Stream API可以对集合数据进行操作,就类似使用SQL语句执行数据库的查询

注意:

Stream本身不会存储数据

Stream不会改变源对象,而是返回一个持有新对象的Stream

Stream是延迟操作,需要用到结果时才执行。

Stream操作的三个步骤
  1. 创建Stream

    一个数据源,获取一个流

    创建方式一:通过集合创建

    List<person> personList=new person().getListPersn();
    Stream<person> stream = personList.stream();//返回一个顺序流的Stream
    Stream<person> personStream = personList.parallelStream();//返回一个并行流的Stream
    

    创建方式二:通过数组创建Stream

    int[] arr={1,2,3,4,5,6,7,8};
    IntStream stream1 = Arrays.stream(arr);
    
    

    创建方式三:通过Stream 的of()方法

    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5, 6);
    
  2. 中间操作

    1筛选与切片

    • filter()—接收lambda,从流中排除某些元素
    stream.filter(e ->e.getAge()>24).forEach(System.out::println);//从人群中显示年龄大于24的
    
    • limit(n) —截断流,使其元素
    stream.limit(3).forEach(System.out::println);//从人群中显示3个人
    
    • skip(n)跳过 元素返回一个去调前n个元素的流
    stream.skip(3).forEach(System.out::println);//从人群中跳过前三个
    
    • distinct() 筛选通过流生成元素的hashcode和equals()去除重复元素
    stream.distinct().forEach(System.out::println);//从人群中去除重复的
    

    2 映射

    • map(Function f) 接收一个函数作为参数,将元素转换为其他形式或提取元素
    List<String> list= Arrays.asList("aa","bb","cc","dd");
    list.Stream().map(str->str.toUpperCase()).forEach(System.out::println);//将字母转为大写
    

    flatMap(Function f) 接收一个函数作为参数,将流中的每个值换为另一个流,最后将流合并一个流

    类似于 list.addAll()和list.add区别。将集合中嵌入的集合打开。

    3排序

    • sorted() 自然排序

      List<Integer> list=Array.asList(11,2,0,-8,-3,60);
      list.Stream().sorted().forEach(System.out::println);//对list排序   从小到大
      
    • sorted(comparator com) 定制排序

      List<person> personList=new person().getListPersn();
      personList.stream().sorted(e1,e2)->{
          return Integer.compare(e1.getAge(),e2.getAge());//对对象按年龄排序
      }.forEach(System.out::println);
      
      
  3. 终止操作

    3.1匹配聚合操作

        allMatch:接收一个 Predicate 函数,当流中每个元素都符合该断言时才返回true,否则返回false
        noneMatch:接收一个 Predicate 函数,当流中每个元素都不符合该断言时才返回true,否则返回false
        anyMatch:接收一个 Predicate 函数,只要流中有一个元素满足该断言则返回true,否则返回false
        findFirst:返回流中第一个元素
        findAny:返回流中的任意元素
        count:返回流中元素的总个数
        max:返回流中元素最大值
        min:返回流中元素最小值
    

    使用代码:

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
 
boolean allMatch = list.stream().allMatch(e -> e > 10); //false
boolean noneMatch = list.stream().noneMatch(e -> e > 10); //true
boolean anyMatch = list.stream().anyMatch(e -> e > 4);  //true
 
Integer findFirst = list.stream().findFirst().get(); //1
Integer findAny = list.stream().findAny().get(); //1
 
long count = list.stream().count(); //5
Integer max = list.stream().max(Integer::compareTo).get(); //5
Integer min = list.stream().min(Integer::compareTo).get(); //1

​ 3.2规约操作

​ Optional reduce(BinaryOperator accumulator):第一次执行时,accumulator函数的第一个参数为流中的第一个元素,第二个参数为流中元素的第二个元素;第二次执行时,第一个参数为第一次函数执行的结果,第二个参数为流中的第三个元素;依次类推。
​ T reduce(T identity, BinaryOperator accumulator):流程跟上面一样,只是第一次执行时,accumulator函数的第一个参数为identity,而第二个参数为流中的第一个元素。
U reduce(U identity,BiFunction<U, ? super T, U> accumulator,BinaryOperator combiner):在串行流(stream)中,该方法跟第二个方法一样,即第三个参数combiner不会起作用。在并行流(parallelStream)中,我们知道流被fork join出多个线程进行执行,此时每个线程的执行流程就跟第二个方法reduce(identity,accumulator)一样,而第三个参数combiner函数,则是将每个线程的执行结果当成一个新的流,然后使用第一个方法reduce(accumulator)流程进行规约。

//经过测试,当元素个数小于24时,并行时线程数等于元素个数,当大于等于24时,并行时线程数为16
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24);
 
Integer v = list.stream().reduce((x1, x2) -> x1 + x2).get();
System.out.println(v);   // 300
 
Integer v1 = list.stream().reduce(10, (x1, x2) -> x1 + x2);
System.out.println(v1);  //310
 
Integer v2 = list.stream().reduce(0,
        (x1, x2) -> {
            System.out.println("stream accumulator: x1:" + x1 + "  x2:" + x2);
            return x1 - x2;
        },
        (x1, x2) -> {
            System.out.println("stream combiner: x1:" + x1 + "  x2:" + x2);
            return x1 * x2;
        });
System.out.println(v2); // -300
 
Integer v3 = list.parallelStream().reduce(0,
        (x1, x2) -> {
            System.out.println("parallelStream accumulator: x1:" + x1 + "  x2:" + x2);
            return x1 - x2;
        },
        (x1, x2) -> {
            System.out.println("parallelStream combiner: x1:" + x1 + "  x2:" + x2);
            return x1 * x2;
        });
System.out.println(v3); //197474048

3.3收集操作

collect:接收一个Collector实例,将流中元素收集成另外一个数据结构。
Collector<T, A, R> 是一个接口,有以下5个抽象方法:
Supplier< A > supplier():创建一个结果容器A
BiConsumer<A, T> accumulator():消费型接口,第一个参数为容器A,第二个参数为流中元素T。
BinaryOperator< A > combiner():函数接口,该参数的作用跟上一个方法(reduce)中的combiner参数一样,将并行流中各 个子进程的运行结果(accumulator函数操作后的容器A)进行合并。
Function<A, R> finisher():函数式接口,参数为:容器A,返回类型为:collect方法最终想要的结果R。
Set characteristics():返回一个不可变的Set集合,用来表明该Collector的特征。有以下三个特征:
CONCURRENT:表示此收集器支持并发。
UNORDERED:表示该收集操作不会保留流中元素原有的顺序。
IDENTITY_FINISH:表示finisher参数只是标识而已,可忽略。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值