目录

  • 1 Lambda
    • 1.1 为什么使用lambda
    • 1.2 lambda案例
    • 1.3 lambda语法规则
      • 1.3.1 接口里面只能有一个方法
    • 1.4 lambda使用前提
  • 2 Stream
    • 2.1为什么使用这个
    • 2.2 入门代码
    • 2.3 思想
    • 2.4 stream流的获取方式
    • 2.5 stream里面的方法
      • 2.5.1 forEach
      • 2.5.2 count
      • 2.5.3 filter
      • 2.5.4 limit
      • 2.5.5 skip
      • 2.5.6 map
      • 2.5.7 sorted
      • 2.5.8 distinct
      • 2.5.9 reduce
      • 2.5.10 concat
      • 2.5.11 parallelStream
      • 2.5.12 findFirst()
      • 2.5.13 anyMatch
      • 2.5.14 .isPresent()
    • 2.6 综合案例
    • 2.7 stream 结果集
      • 2.7.1 结果收集到集合中
      • 2.7.2 结果收集到数组中
    • 2.8 对流中的数据做聚合计算
    • 2.9 对流中的数据做分组
    • 2.10 对流中的数据做分区操作
    • 2.11 对流中的数据做拼接功能
    • 2.12 并行流
    • 2.13 并行流与串行流对比
    • 2.14 使用并行流的线程安全问题
  • 3 stream技巧
    • 3.1 数组转集合
    • 3.2 统计数组元素中的个数

1 Lambda

1.1 为什么使用lambda

1.2 lambda案例

new Thread(()-> {System.out.println("lambda");System.out.println("666");}).start();

1.3 lambda语法规则

1.3.1 接口里面只能有一个方法

@FunctionalInterface
public interface UserService {void getname();
}

我们要使用lambda表达式,接口里面只能有一个方法,但是有可能其他人往这个接口里面写代码,所以我们在这个接口里面写一个注解@FunctionalInterface;这个接口就是一个标注注解,被这个注解修饰的接口,只能有一个抽象方法

1.4 lambda使用前提


2 Stream

2.1为什么使用这个

我们自己定义一个list集合,要使用里面的数据,我们就需要一直的循环,多一个需求,就多一次循环,这样是不好的,很复杂;

其实就是简化了我们对集合的操作,对数组的操作

2.2 入门代码

List<String> strings = Arrays.asList("张三", "张四", "王五", "赵六");
strings.stream().filter(s -> s.startsWith("张")).filter(s -> s.length()==2).forEach(s -> System.out.println(s));

2.3 思想

stream就是一个流水线

2.4 stream流的获取方式


直接对数组进行操作

2.5 stream里面的方法


2.5.1 forEach

2.5.2 count

        Stream<String> a1 = Stream.of("a1", "a2", "a3");long count = a1.count();System.out.println(count);

2.5.3 filter

List<String> strings = Arrays.asList("张三", "张四", "王五", "赵六");
strings.stream().filter(s -> s.startsWith("张")).filter(s -> s.length()==2).forEach(s -> System.out.println(s));

2.5.4 limit

相当于分页,截取多少个数据

 List<String> strings = Arrays.asList("张三", "张四", "王五", "赵六");strings.stream().filter(s -> s.startsWith("张")).filter(s -> s.length()==2).limit(1)   取出1个元素.forEach(s -> System.out.println(s));

2.5.5 skip

List<String> strings = Arrays.asList("张三", "张四", "王五", "赵六");
strings.stream().skip(1).forEach(s -> System.out.println(s));

2.5.6 map


2.5.7 sorted

 List<Integer> strings1 = Arrays.asList(1, 2, 3, 4);strings1.stream().sorted() //默认是从小到大排序.sorted((o1,o2)-> o2-o1) //自定义排序规则.forEach(s -> System.out.println(s));

2.5.8 distinct

排除相同的数据

 List<Integer> strings1 = Arrays.asList(1, 1, 3, 4);strings1.stream().sorted() //默认是从小到大排序.sorted((o1,o2)-> o2-o1) //自定义排序规则.distinct()//去掉重复的数据.forEach(s -> System.out.println(s));

2.5.9 reduce


2.5.10 concat

2.5.11 parallelStream

获取一个并行流

ArrayList<Object> objects = new ArrayList<>();
Stream<Object> objectStream = objects.parallelStream();

2.5.12 findFirst()

匹配出流里面的第一个数据

// 匹配第一个
Optional<Integer> findFirst = list.stream().
filter(x -> x > 6).findFirst();

2.5.13 anyMatch

// 是否包含符合特定条件的元素

// 是否包含符合特定条件的元素
boolean anyMatch = list.stream().anyMatch(x -> x > 6);

2.5.14 .isPresent()

isPresent()可以判断所找到的值是否是null

2.6 综合案例

    public static void main(String[] args) {//        创建两个listList<String> list1 = Arrays.asList("迪丽热巴", "古力娜扎", "孙悟空", "租八戒", "唐生");List<String> list2 = Arrays.asList("张无忌", "赵敏", "刘亦菲", "张三分", "张姐","胡歌", "纳兰性德");
// 从list1里面得到长度为3的,并且只要前三个Stream<String> stream1 = list1.stream().filter(s -> s.length() == 3).limit(3);
//从list2中筛选只要张姓的人,并且不要最前面的两个人Stream<String> stream2 = list2.stream().filter(s -> s.startsWith("张")).skip(1);
// 将两个合并为一个Stream<String> concat = Stream.concat(stream1, stream2);
//        根据姓名创建对象Stream<person> personStream = concat.map(s -> new person(s));
//        将对象输出personStream.forEach(s ->{System.out.println(s.getName());});

2.7 stream 结果集

我们通过stream过滤完数据,需要将结果保存

2.7.1 结果收集到集合中


//        将过滤之后的数据转为list集合List<person> collect = personStream.collect(Collectors.toList());System.out.println(collect.toString());
//        将过滤之后的数据转为set集合Set<person> collect1 = personStream.collect(Collectors.toSet());System.out.println(collect1.toString());
转换成特定的实现类ArrayList<person> collect = personStream.collect(Collectors.toCollection(() -> new ArrayList<>()));System.out.println(collect.toString());

2.7.2 结果收集到数组中

        String[] strings = Stream.of("1", "2", "3").toArray(String[]::new);System.out.println(Arrays.toString(strings)); //[1, 2, 3]

2.8 对流中的数据做聚合计算

    public static void main(String[] args) {//从数据库查询出来的值Stream<person> personStream = Stream.of(new person("小红", 15),new person("小百", 14),new person("小天", 18),new person("小让", 85),new person("小与", 4));//获取list里面的年龄的最大值
//        Optional<person> collect = personStream.
//                collect(Collectors.maxBy((p1, p2) -> p1.getAge() - p2.getAge()));
//        System.out.println(collect.get());//获取list里面的年龄的最小值
//                Optional<person> collect = personStream.
//                collect(Collectors.minBy((p1, p2) -> p1.getAge() - p2.getAge()));
//        System.out.println(collect.get());//        求和
//        Integer collect = personStream.
//                collect(Collectors.summingInt(person::getAge));//        平均值
//        Double collect = personStream.collect(Collectors.averagingInt(person::getAge));//        统计数量Long collect = personStream.collect(Collectors.counting());}

2.9 对流中的数据做分组

 public static void main(String[] args) {//从数据库查询出来的值Stream<person> personStream = Stream.of(new person("小红", 15),new person("小百", 15),new person("小天", 18),new person("小让", 18),new person("小与", 19));//        以某一个字段进行分组
//        Map<String, List<person>> collect = personStream.collect(Collectors.groupingBy(person::getName));
//        collect.forEach((k,v)-> System.out.println("k="+k+"===="+"v="+v));
//        k=小让====v=[person{name='小让', age=18}]
//        k=小天====v=[person{name='小天', age=18}]
//        k=小与====v=[person{name='小与', age=4}]
//        k=小百====v=[person{name='小百', age=15}]
//        k=小红====v=[person{name='小红', age=15}]//        以成年未成年进行分组
//        Map<String, List<person>> collect = personStream.collect(Collectors.groupingBy(p -> {//            return p.getAge() > 18 ? "成年" : "未成年";
//        }));
//        System.out.println(collect);//       多级分组Map<String, Map<Object,List<person>>> collect =personStream.collect(Collectors.groupingBy(person::getName,Collectors.groupingBy(p -> {return p.getAge() > 18 ? "成年" : "未成年";})));System.out.println(collect);}

2.10 对流中的数据做分区操作

//从数据库查询出来的值Stream<person> personStream = Stream.of(new person("小红", 15),new person("小百", 15),new person("小天", 18),new person("小让", 18),new person("小与", 19));Map<Boolean, List<person>> collect = personStream.collect(Collectors.partitioningBy(person -> person.getAge() > 10));System.out.println(collect);

结果

{false=[],
true=[person{name='小红', age=15}, person{name='小百', age=15}, person{name='小天', age=18}, person{name='小让', age=18}, person{name='小与', age=19}]}

2.11 对流中的数据做拼接功能

    public static void main(String[] args) {//从数据库查询出来的值Stream<person> personStream = Stream.of(new person("小红", 15),new person("小百", 15),new person("小天", 18),new person("小让", 18),new person("小与", 19));//        Map<Boolean, List<person>> collect = personStream.collect(Collectors.partitioningBy(person -> person.getAge() > 10));
//        System.out.println(collect);//        拼接String collect = personStream.map(person -> person.getName()).collect(Collectors.joining("_", "&&&", "wwww"));System.out.println(collect);
&&&小红_小百_小天_小让_小与wwww

2.12 并行流

获取并行流的2个方式

        List<String> list1 = Arrays.asList("迪丽热巴", "古力娜扎", "孙悟空", "租八戒", "唐生");//获取并行流  第一个方式Stream<String> stringStream = list1.parallelStream();
//        第二个Stream<String> parallel = Stream.of("1", "2").parallel();

2.13 并行流与串行流对比

2.14 使用并行流的线程安全问题

就是我们从数据库查询出list数据,过滤完成之后往新的list集合里面添加数据,那么如果使用并行流遍历,会出现线程安全问题

public static void main(String[] args) {ArrayList<Object> objects = new ArrayList<>();for(int i=0;i<2000;i++){objects.add(i);}System.out.println(objects.size());ArrayList<Object> rrrr = new ArrayList<>();objects.parallelStream().forEach(f->{rrrr.add(f);});System.out.println(rrrr.size());}

以上代码会出现的错误


我们的解决方法是
1 加一个同步代码块

   public static void main(String[] args) {ArrayList<Object> objects = new ArrayList<>();for(int i=0;i<2000;i++){objects.add(i);}System.out.println(objects.size());Object obj = new Object();ArrayList<Object> rrrr = new ArrayList<>();objects.parallelStream().forEach(f->{synchronized (obj){rrrr.add(f);}});System.out.println(rrrr.size());}

3 stream技巧

3.1 数组转集合

之前我们写代码

// 将 List 元素存储到数组中
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
int[] arr = new int[list.size()];
Integer[] temp = list.toArray(new Integer[0]);
for (int i = 0; i < temp.length; i++) {arr[i] = temp[i];
}// 将数组元素 存储到 List 中
int[] arr = {1, 2, 3, 4, 5};
List<Integer> list = new ArrayList<>();
for (int val : arr) {list.add(val);
}

现在写

// 将 List 元素存储到数组中
List<Integer> list = new ArrayList<>(Arrays.asList(1, 2, 3, 4, 5));
int[] arr = list.stream().mapToInt(Integer::intValue).toArray();// 将数组元素 存储到 List 中
int[] arr = {1, 2, 3, 4, 5};
List<Integer> list = IntStream.of(arr).boxed().collect(Collectors.toList());

3.2 统计数组元素中的个数

假设我们现在需要统计并输出一个有重复元素的数组中每个元素及对应元素出现的个数,相信各位都能够想到,我们使用一个Map就很容易解决这个问题,代码如下:

String[] arr = {"a", "c", "a", "b", "d", "c"};
Map<String, Integer> map = new HashMap<>();
for (String s : arr) {if (map.containsKey(s)) {map.put(s, map.get(s) + 1);} else {map.put(s, 1);}
}
map.forEach((key, value) -> System.out.println(key + " : " + value));
String[] arr = {"a", "c", "a", "b", "d", "c"};
Stream.of(arr).collect(Collectors.toMap(k -> k, k -> 1, Integer::sum)).forEach((k, v) -> System.out.println(k + " : " + v));

在上面的代码中,Collectors.toMap(k -> k, k -> 1, Integer::sum)这一部分可能不好理解,对于这里面的三个参数,第一个参数代表将arr中的每一个元素作为Map中的key,第二个参数代表每一个key所对应的value,在这里每一个元素都对应个数1,第三个参数代表,如果存在相同的key,该如何进行合并,这里通过使用Integer::sum,代表将具有相同key的元素进行合并时,其value进行相加,这样便实现了每个元素个数的统计

JDK8新特性详解LambdaStream相关推荐

  1. JDK8新特性详解Lambda、StreamAPI、Optional等

    JDK8学习笔记 学习视频地址:https://www.bilibili.com/video/BV1k64y1R7sA 操作代码:https://gitee.com/rederic/study-jdk ...

  2. java11 新特性 详解

    为什么80%的码农都做不了架构师?>>>    引言: 点击-->java10 新特性 详解 点击-->java9 新特性 详解 点击-->java8 新特性 详解 ...

  3. Java9 新特性 详解

    目录 Java9 新特性 详解 1.Java9新特性之---目录结构 2.Java9新特性之---JShell工具 3.Java9新特性之---模块化 4.Java9新特性之---多版本兼容Jar包 ...

  4. 还在用JDK6的同学,来看看JDK13新特性详解吧

    点击上方"搜云库技术团队"关注,选择"设为星标" 回复"面试题"或"1024"获取 4T 学习资料 在 JDK 版本的世 ...

  5. 《Android群英传》读书笔记 (5) 第十一章 搭建云端服务器 + 第十二章 Android 5.X新特性详解 + 第十三章 Android实例提高...

    第十一章 搭建云端服务器 该章主要介绍了移动后端服务的概念以及Bmob的使用,比较简单,所以略过不总结. 第十三章 Android实例提高 该章主要介绍了拼图游戏和2048的小项目实例,主要是代码,所 ...

  6. Java基础学习总结(33)——Java8 十大新特性详解

    Java8 十大新特性详解 本教程将Java8的新特新逐一列出,并将使用简单的代码示例来指导你如何使用默认接口方法,lambda表达式,方法引用以及多重Annotation,之后你将会学到最新的API ...

  7. oracle dataguard详解,Oracle 19c 新特性详解:DataGuard 中ADG的自动DML重定向

    Oracle 19c 新特性详解:DataGuard 中ADG的自动DML重定向 在前面的文章<Oracle 19c 十大新特性一览>中,我们曾经提到 Oracle 19c的一个重要增强, ...

  8. java8-stream新特性详解及实战

    Java8 Stream新特性详解及实战 背景介绍 在阅读Spring Boot源代码时,发现Java 8的新特性已经被广泛使用,如果再不学习Java8的新特性并灵活应用,你可能真的要out了.为此, ...

  9. Java EE 8的五大新特性详解

    Java EE 8的五大新特性详解 2018.4.3 版权声明:本文为博主chszs的原创文章,未经博主允许不得转载. Java EE 8带来了很多新特性,其中最好的新特性有下面五个. 备受期待的Ja ...

最新文章

  1. Ubuntu报错记录(Could not get lock /var/lib/dpkg/lock-frontend问题的解决方法)
  2. 致远今目标移动APP无法脱离PC单独使用
  3. argparse.ArgumentParser()的用法
  4. 如何在AWS搭建服务器控制服务器
  5. cmd chcp命令切换字符格式UTF8
  6. 滴滴为啥值3600亿?看它的数据中台就知道了
  7. i.mx6 Android5.1.1 servicemanager本地服务
  8. 数组中第K个最大元素
  9. 曲曲直直线条图计算机教案,【曲曲直直的美术画】_美术教案第三课:曲曲直直(三年级美术下册教案)——小学美术...
  10. 平台(洛谷P1105题题解,Java语言描述)
  11. django种表单post出现CSRF verification failed( CSRF验证失败 ) 的两种解决方式
  12. 联想ThinkPad SL410(28428KC)与2842-EWC区别
  13. 数据库连接串的问题。(如果是集群数据库的话)
  14. 人力面试时常规的面试题
  15. [CSS基础]在一个网页中使用多种不同链接风格的CSS.
  16. 计算机培训考试内容,计算机等级考试的科目和内容解析
  17. 求职经历--ThoughtWorks
  18. onLoad onShow
  19. 基于超像素和自生成神经森林的肺实质图像序列分割方法(笔记五)
  20. 北斗三号短报文RDSS测试软件V1.0

热门文章

  1. android之城市定位
  2. 三星android操作系统耗电量大,三星手机如何省电?提升手机续航能力技巧【详解】...
  3. 如何成为一个有情怀的工程师?
  4. 广州楼市:2021下半年,到底要不要尽快买房?
  5. 艾司博讯:拼多多退款率过高会影响权重吗
  6. linux创建用户和赋权限
  7. SPR4: 依赖注入的三种方式
  8. 一文搞懂Ajax,附Ajax面试题
  9. NodeJS 依赖 Python 自动安装
  10. FreeSWITCH 空号识别 (mod_da2使用说明)