• JAVA8新特性 Lambda表达式、双冒号、streamm详解


    Lambda 允许把函数作为参数传递进方法中。

    不是每个接口都可以缩写成 Lambda 表达式。只有那些函数式接口(Functional Interface)才能缩写成 Lambda 表示式。

    所谓函数式接口(Functional Interface)就是只包含一个抽象方法的声明。
    只要接口中仅仅包含一个抽象方法,我们就可以将其改写为 Lambda 表达式。为了保证一个接口明确的被定义为一个函数式接口(Functional Interface),我们需要为该接口添加注解:@FunctionalInterface。这样,一旦你添加了第二个抽象方法,编译器会立刻抛出错误提示。

    Lambda表达式的重要特征:
      可选类型声明:不需要声明参数类型,编译器可以统一识别参数值。
      可选的参数圆括号:一个参数无需定义圆括号,但多个参数需要定义圆括号。
      可选的大括号:如果主体包含了一个语句,就不需要使用大括号。
      可选的返回关键字:如果主体只有一个表达式返回值则编译器会自动返回值,大括号需要指定明表达式返回了一个数值。

    变量作用域
      lambda 表达式只能引用标记了 final 的外层局部变量,这就是说不能在 lambda 内部修改定义在域外的局部变量,否则会编译错误。

    Lambda表达式的基本语法:

    (parameters) -> expression  或  (parameters) ->{ statements; }

    Lambda小程序,遍历 List 集合

    String[] array = {"a","b","c"};
    List<String> list = Arrays.asList(array);
     
    System.out.println("方式一:原始方式");
    for (int i = 0; i < list.size(); i++) {
        System.out.println(list.get(i));
    }
     
    System.out.println("方式二:增强 for 循环");
    for (String s : list) {
        System.out.println(s);
    }
     
    System.out.println("方式三:lambda 表达式");
    list.forEach( e -> System.out.println(e) );
     
    System.out.println("方式四:lambda 表达式");
    list.forEach( (e) -> {System.out.println(e);} );
     
    System.out.println("方式五:lambda 表达式 之 静态方法引用");
    list.forEach(System.out::println);

    Lambda 小程序,使用 Lambda 表达式实现匿名内部类

    System.out.println("方式一:匿名内部类实现 Runnable接口 run 方法,并使用多线程运行");
    new Thread(new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello world !");
        }
    }).start();
     
    System.out.println("方式一:Lambda 实现 Runnable接口,并使用多线程运行");
    new Thread(() -> System.out.println("Hello world !")).start();
     
    System.out.println("方式二:匿名内部类实现 Runnable接口 run 方法");
    Runnable r1 = new Runnable() {
        @Override
        public void run() {
            System.out.println("Hello world !");
        }
    };
    r1.run();
     
    System.out.println("方式二:Lambda 实现 Runnable接口");
    Runnable r2 = () -> System.out.println("Hello world !");
    r2.run();

    真实应用示例(forEach):

    // 遍历比较
    Set<DeptItem> itemList = entity.getRppDeptItem();
    if(entity.getDatasource().equals(DeptDateSourceEnum.nc.getCode())){
        itemList.forEach(item->{
            if(item.getNcid() == null && item.getPersistStatus().equals(PersistStatus.ADDED)){
                throw new RuntimeException("来源NC部门不允许在主数据新增岗位" );
            }
        });
    }

    双冒号 ::

    双冒号运算符在Java 8中被用作方法引用,方法引用是与 lambda 表达式相关的一个重要特性。它提供了一种不执行方法的方法。为此,方法引用需要由兼容的函数接口组成的目标类型上下文。

    使用lambda表达式会创建匿名方法, 但有时候需要使用一个lambda表达式只调用一个已经存在的方法(不做其它), 所以这才有了方法引用!

    以下是Java 8中方法引用的一些语法:
      静态方法引用语法:classname::methodname 例如:Person::getAge
      对象的实例方法引用语法:instancename::methodname 例如:System.out::println
      对象的超类方法引用语法: super::methodname
      类构造器引用语法: classname::new 例如:ArrayList::new
      数组构造器引用语法: typename[]::new 例如: String[]:new

    简要:https://www.cnblogs.com/maohuidong/p/11527681.html

    详细:https://blog.csdn.net/zhoufanyang_china/article/details/87798829

    真实应用示例(stream、::):

    // list转换成数组
    List<String> list = Arrays.asList("a","b","c");
    String[] arrays = list.stream().toArray(String[]::new);
    for (String array : arrays) {
        System.out.println(array);
    }

    Stream

    采用java8 lambda表达式 实现 java list 交集 并集 差集 去重复并集

    Java 8 中的 Stream 是对集合(Collection)对象功能的增强,使用的是函数式编程模式,它可以对集合进行链状流式的操作,它专注于对集合对象进行各种非常便利、高效的聚合操作(aggregate operation),或者大批量数据操作 (bulk data operation)。Stream API 借助于同样新出现的 Lambda 表达式,极大的提高编程效率和程序可读性。

    流的执行:
    当存在终端操作时,中间操作操作才会被执行。

    入门看我:https://www.jianshu.com/p/11c925cdba50

    一般详细:https://www.ibm.com/developerworks/cn/java/j-lo-java8streamapi/index.html#icomments

    非常详细:https://juejin.im/post/5cc124a95188252d891d00f2

     真实应用示例(stream.map):

    // 小写字母转换为大写字母
    List<String> collected1 = Arrays.asList("alpha","beta");
    collected1 = collected1.stream().map(string -> string.toUpperCase()).collect(Collectors.toList());
    System.out.println(collected1);

     真实应用示例(stream.map):

    // string转换为list
    String ids = "1,2,3     ,4,5";
    List<Long> listIds = Arrays.asList(ids.split(",")).stream().map(e -> Long.valueOf(e.trim())).collect(Collectors.toList());
    System.out.println(listIds);

     真实应用示例(stream.map):

    // 获取到所有商品ID
    // List<ProductSkuImageDto> resultList = updateProductSkuValues(addedList, modifiedList, deletedList);
    // 写法一
    List<String> productIdsList = resultList.stream().map(ProductSkuImageDto::getProductId).collect(Collectors.toList());
    // 写法二
    List<String> productIdsList = resultList.stream().map(e -> e.getProductId()).collect(Collectors.toList());

     真实应用示例(stream.forEach):

    // 遍历值放到map中
    protected Map<String, GoodsBomDto> getBomInfos(Set<String> parentGoodsIds){
        if(CollectionUtils.isEmpty(parentGoodsIds)){
            return new HashMap<>(0);
        }
        List<GoodsBomDto> goodsBomDtos = goodsBomApi.goodsBomByParentGoodId(String.join(",", parentGoodsIds)).getBody();
        if(CollectionUtils.isEmpty(goodsBomDtos)){
            return new HashMap<>(0);
        }
        Map<String, GoodsBomDto> parentGoodsId_bomMap = new HashMap<>(goodsBomDtos.size());
        goodsBomDtos.stream().forEach(goodsBomDto -> parentGoodsId_bomMap.put(goodsBomDto.getParentGoodsId(), goodsBomDto));
        return parentGoodsId_bomMap;

     真实应用示例(stream.forEach):

    // 给实体里面的数字,设置一个值
    protected void set_Status(List<UnitAdapter> data, String operation) {
        data.stream().forEach(unitAdapter -> unitAdapter.set_status(operation));

     入门小程序:

    List<String> list = Arrays.asList("abc", "def", "1234");
            System.out.println("统计字符长度");
            System.out.println("方式一:lambda表达式");
            list.stream().map(e -> e.length()).forEach(e -> System.out.println(e));
            System.out.println("方式二:函数引用");
            list.stream().map(String :: length).forEach(System.out::println);
     
            System.out.println("mapToInt 将数据流中的元素结果转换为 int 类型");
            list.stream().mapToInt(e -> e.length()).forEach(e -> System.out.println(e));
     
            System.out.println("mapToDouble 将数据流中的元素结果转换为 Double 类型");
            list.stream().mapToDouble(e -> e.length()).forEach(e -> System.out.println(e));
     
     
            List<String> list2 = Arrays.asList("a-b-c-d","e-f-i-g-h");
            System.out.println("flatmap 作用就是将元素拍平拍扁");
            // flatmapToInt、flatmapToLong、flatmapToDouble 跟flatMap 都类似的,只是类型被限定了
            list2.stream().flatMap(e -> Stream.of(e.split("-"))).forEach(e -> System.out.println(e));
     
            System.out.println("limit 限制显示元素的个数");
            List<Integer> list3 = Arrays.asList(1,2,3,4,5,6);
            list3.stream().limit(3).forEach(e -> System.out.println(e));
     
            System.out.println("distinct 去重");
            List<Integer> list4 = Arrays.asList(1,2,3,1,2,5,6,7,8,0,0,1,2,3,1);
            list4.stream().distinct().forEach(e -> System.out.println(e));
     
            System.out.println("filter 过滤");
            list4.stream().filter(e -> e<3).forEach(e -> System.out.println(e));
     
            System.out.println("skip 跳过前几个元素");
            List<String> list5 = Arrays.asList("a","b","c");
            list5.stream().skip(2).forEach(e -> System.out.println(e));
     
            System.out.println("sorted 排序,底层依赖Comparable 实现");
            list4.stream().sorted().forEach(e -> System.out.println(e));
     
            System.out.println("collect(Collectors.toSet()) 将元素收集到 Set 中");
            List<String> list6 = Arrays.asList("apple", "banana", "orange", "waltermaleon", "grape");
            list6.stream().collect(Collectors.toSet()).forEach(e -> System.out.println(e));
     
            System.out.println("count 统计数据流中的元素个数");
            System.out.println(list6.stream().count());
     
            System.out.println("findFirst 获取第一个元素");
            System.out.println(list6.stream().findFirst());
     
            System.out.println("findAny 随机获取一个元素");
            System.out.println(list6.stream().parallel().findAny());
     
            System.out.println("noneMatch 集合中是否不存在指定字符,如果不存在返回 true,否则返回 false");
            System.out.println(list6.stream().noneMatch(e -> e.equals("orange")));
     
            System.out.println("anayMatch 集合中是否存在指定字符,如果存在返回 true,否则返回 false");
            System.out.println(list6.stream().anyMatch(e -> e.equals("orange")));
     
            System.out.println("min 查找最小的元素");
            List<Integer> list7 = Arrays.asList(1,2,3,4,5,6);
            System.out.println(list7.stream().min((e1, e2) -> e1.compareTo(e2)));
     
            System.out.println("max 查找最大的元素");
            System.out.println(list7.stream().max((e1, e2) -> e1.compareTo(e2)));
     
            System.out.println("reduce 是一个规约操作,所有的元素归约成一个,比如对所有元素求和");
            System.out.println(list7.stream().reduce(0, (e1, e2) -> e1+e2));
     
            System.out.println("forEachOrdered 适用用于并行流的情况下进行迭代,能保证迭代的有序性");
            Stream.of(0,2,6,5,4,9,8,-1)
                    .parallel()
                    .forEach(e->{
                        System.out.println(Thread.currentThread().getName()+": "+e);});

     转载自:https://www.cnblogs.com/tangshengwei/p/12587976.html

  • 相关阅读:
    遗产继承骗局
    Nginx配置https和wss
    Servlet乱码问题
    logback+slf4j作为日志系统
    InteliJ Idea通过maven创建webapp
    pip安装注意事项
    [转]TCP(HTTP)长连接和短连接区别和怎样维护长连接
    Python Socket编程初探
    有用的git片段
    Python使用chardet包自动检测编码
  • 原文地址:https://www.cnblogs.com/damoblog/p/15820953.html
Copyright © 2020-2023  润新知