zoukankan      html  css  js  c++  java
  • Jdk8新特性

    Jdk8新特性

    介绍

    • 优点

      • 速度更快
      • 代码更少(Lambda表达式)
      • 强大的Stream API
      • 便于并行
      • 最大化减少控制异常Optional
    • 常用方法

      • Lambda表达式
      • 新的日期API
      • 函数式接口
      • 方法引用与构造器引用
      • Stream API流式计算
      • 接口中的默认方法与静态方法

    应用

    Lambda表达式

    概念

    Lambda 是一个匿名函数,我们可以把 Lambda 表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。Lambda 表达式在Java 语言中引入了一个新的语法元素和操作符。这个操作符为 “->” ,该操作符被称 为 Lambda 操作符或剪头操作符。它将 Lambda 分为 两个部分:

    左侧:指定了 Lambda 表达式需要的所有参数

    右侧:指定了 Lambda 体,即 Lambda 表达式要执行的功能。

    使用

    public class Test {
        public static void main(String[] args) {
            Consumer<String> consumer = (x) -> System.out.println(x);
            consumer.accept("我在学习Lambda表达式");
            
            String[] players_1 = {"Rafael Nadal", "Novak Djokovic",
                    "Stanislas Wawrinka", "David Ferrer",
                    "Roger Federer", "Andy Murray",
                    "Tomas Berdych", "Juan Martin Del Potro",
                    "Richard Gasquet", "John Isner"};
    
            // 1.2 使用 lambda expression 排序 players
            Comparator<String> sortByName = (String s1, String s2) -> (s1.compareTo(s2));
            Arrays.sort(players_1, sortByName);
    
            System.out.println(players_1);
    
            System.out.println("------------1----------------");
    
            String[] atp = {"Rafael Nadal", "Novak Djokovic",
                    "Stanislas Wawrinka",
                    "David Ferrer", "Roger Federer",
                    "Andy Murray", "Tomas Berdych",
                    "Juan Martin Del Potro"};
            List<String> players = Arrays.asList(atp);
    
            // 以前的循环方式
            for (String player : players) {
                System.out.print(player + "; ");
            }
            System.out.println("-------------2---------------");
            // 使用 lambda 表达式以及函数操作(functional operation)
            players.forEach((player) -> System.out.print(player + "; "));
    
            System.out.println("-------------3---------------");
            //在里面写方法,刚开始以为只是一个赋值
            //左侧是所有参数,右侧要执行的功能
            players.forEach(player -> {
                System.out.print(player + ";=== ");
            });
    
            System.out.println("-------------4---------------");
            // 在 Java 8 中使用双冒号操作符(double colon operator)
            players.forEach(System.out::println);
    
        }
    }
    
    

    Stream API流式计算

    概念

    Stream流的出现,主要是用在集合的操作上。在我们日常的工作中,经常需要对集合中的元素进行相关操作。诸如:增加、删除、获取元素、遍历。 Stream流式思想类似于工厂车间的"生产流水线",Stream流不是一种数据结构,不保存数据,而是对数据进行加工处理。Stream 可以看做是流水线上的一个工序。在流水线上,通过多个工序让一个原材料加工成一个商品。[1] 参考一

    • 举例
    public class Test2 {
        public static void main(String[] args) {
            List<String> listLevel = new ArrayList<String>();
            listLevel.add("5");
            listLevel.add("1");
            listLevel.add("2");
            listLevel.add("9");
            listLevel.add("7");
            //比较出最小的
            String levelMin = listLevel.stream().min((Comparator.comparing((a) -> a))).get();
            System.out.println(levelMin);
            //比较出最大的
            String levelMax = listLevel.stream().max((Comparator.comparing((a) -> a))).get();
            System.out.println(levelMax);
    
            //进入工厂
            listLevel.stream()
                    .filter(level-> (Integer.parseInt(level)>5))  //第一道工序
                    .filter(level-> (Integer.parseInt(level)<10))  //第二道工序
                    .forEach(level -> {                            //第三道工序
                        System.out.println("我是"+level);           //开始使用
                    });
        }
    }
    

    使用

    java.util.stream.Stream 是 JDK8 新加入的流接口。

    1. 所有的 Collection 集合都可以通过 .stream() 方法来获取流;
    2. 使用 Stream 接口的 .of() 静态方法,可以获取流。
    		//方式1:根据Collection获取流
            //Collection接口中有一个默认的方法:default Stream<E> stream()
            //1.List获取流
            List<String> list = new ArrayList<>();
            Stream<String> stream01 = list.stream();
     
            //2.Set获取流
            Set<String> set = new HashSet<>();
            Stream<String> stream02 = set.stream();
     
            //3.Map获取流
            //Map 并没有继承自 Collection 接口,所有无法通过该 map.stream()获取流。
    		//但是可用通过如下三种方式获取:
            Map<String,String> map = new HashMap<>();
            Stream<String> stream03 = map.keySet().stream();
            Stream<String> stream04 = map.values().stream();
            Stream<Map.Entry<String, String>> stream05 = map.entrySet().stream();
     
            //方式2:Stream中的静态方法of获取流
            // static<T> Stream<T> of(T... values)  
            // T... values:可变参数,实际原理就是可变数组(传递String数组进去)
            
            //1.字符串获取流
            Stream<String> stream06 = Stream.of("aa", "bb", "cc");
     
            //2.数组类型(基本类型除外)
            String[] strs = {"aa","bb","cc"};
            Stream<String> stream07 = Stream.of(strs);
     
            //3.基本数据类型的数组
            int[] arr = {1,2,3,4};
            //返回值是 int[],
    		//这是 Stream流把整个数组看做一个元素来操作,而不是操作数组中的int元素
            Stream<int[]> stream08 = Stream.of(arr);
    
    • 常用方法

      方法名 作用 返回值类型 方法种类
      count 统计个数 long 终结
      forEach 遍历(逐一处理) void 终结
      filter 过滤 Stream 函数拼接
      limit 取用前几个 Stream 函数拼接
      skip 跳过前几个 Stream 函数拼接
      map 映射 Stream 函数拼接
      concat 组合 Stream 函数拼接
      • 终结方法:返回值类型不再是 Stream 类型的方法,不再支持链式调用。终结方法包括 count()forEach() 方法;[2]
      • 非终结方法:又叫函数拼接方法。值返回值类型仍然是 Stream 类型的方法,支持链式调用(除了终结方法外,其与方法均为非终结方法) 参考2 参数3
      		// count() 方法,用来统计集合中的元素个数,是一个终结方法。
            long count = listLevel.stream().count();
            System.out.println("元素个数为:"+count);
    
            // limit() 方法,用来对 Stream 流中的数据进行截取,只取用前 n 个,是一个非终结方法。
            // 参数是一个 long 型,如果集合当前长度大于参数则进行截取,否则不进行操作。
            // 因为 limit() 是一个非终结方法,所以必须调用终止方法。
            listLevel.stream().limit(3).forEach(System.out::println);
    
            //如果希望跳过前几个元素,去取后面的元素,则可以使用 skip()方法,
    		//获取一个截取之后的新流,它是一个非终结方法。
            // 参数是一个 long 类型,如果 Stream 流的当前长度大于 n,则跳过前 n 个,
    		//否则将会得到一个长度为 0 的空流。
            // 因为 limit() 是一个非终结方法,所以必须调用终止方法。
            listLevel.stream().skip(3).forEach(System.out::println);
    
            //可以使用limit()方法和skip()实现分页
            //一页2条 分页操作
            //第一页
            listLevel.stream().skip(0).limit(2).forEach(System.out::println);
            //第二页
            listLevel.stream().skip(2).limit(2).forEach(System.out::println);
            //第三页
            listLevel.stream().skip(4).limit(2).forEach(System.out::println);
    
            //Stream 转成 List
            Stream<String> list = listLevel.stream().skip(0).limit(2);
            //Convert a Stream to List
            List<String> result = list.collect(Collectors.toList());
            result.forEach(System.out::println);
    
            //sorted() 方法,可以用来对 Stream 流中的数据进行排序.
            //因为 sorted() 方法是一个非终结方法,所以必须调用终止方法。
            //sorted() 方法:按照自然规律,默认为升序排序。
            //sorted(Comparator comparator)  方法,按照指定的比较器规则排序
            Stream<Integer> stream = Stream.of(66,33,11,55);
            stream.sorted().forEach(System.out::println);
    
    

    新的日期API

    概念

    Java 8 在 java.time 包下提供了很多新的 API。以下为两个比较重要的 API:

    1. Local(本地) − 简化了日期时间的处理,没有时区的问题。

    2. Zoned(时区) − 通过指定的时区处理日期时间。

      新的java.time包涵盖了所有处理日期,时间,日期/时间,时区,时刻(instants),过程(during)与时钟(clock)的操作。

    使用

    public class Test3 {
        public static void main(String[] args) {
    
            //指定格式
            DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss E");
            DateTimeFormatter dtf2 = DateTimeFormatter.ofPattern("yyyy年MM月dd日 HH:mm:ss ");
    
            LocalDateTime ldt = LocalDateTime.now();
    
            String strDate = ldt.format(dtf);
            System.out.println(strDate);
    
            String strDate2 = ldt.format(dtf2);
            System.out.println(strDate2);
    
            LocalDateTime newLdt = ldt.parse(strDate, dtf);
            System.out.println(newLdt);
    
            // 获取当前的日期时间
           // LocalDateTime ldt = LocalDateTime.now();
            System.out.println("当前时间: " + ldt);
    
            LocalDateTime ldt2 = LocalDateTime.of(2019, 11, 21, 10, 10, 10);
            System.out.println("使用指定数据: " + ldt2);
    
            LocalDateTime ldt3 = ldt2.plusYears(20);
            System.out.println("加20年: " + ldt3);
    
            LocalDateTime ldt4 = ldt2.minusMonths(2);
            System.out.println("减2个月: " + ldt4);
    
            System.out.println("年: " + ldt.getYear());
            System.out.println("月: " + ldt.getMonthValue());
            System.out.println("日: " + ldt.getDayOfMonth());
            System.out.println("时: " + ldt.getHour());
            System.out.println("分: " + ldt.getMinute());
            System.out.println("秒: " + ldt.getSecond());
    
    
            // 默认使用 UTC 时区(0时区)
            Instant ins = Instant.now();
            System.out.println(ins);
    
            // 偏移8个时区
            OffsetDateTime odt = ins.atOffset(ZoneOffset.ofHours(8));
            System.out.println(odt);
            // 获取纳秒
            System.out.println(ins.getNano());
    
            // 在 1970年1月1日 00:00:00 加5秒
            Instant ins2 = Instant.ofEpochSecond(5);
            System.out.println(ins2);
        }
    }
    
    

    1. 参考一中图片展示更直观。 ↩︎

    2. 如果不以终结方法结尾,可能会报错。 ↩︎

  • 相关阅读:
    win10 激活
    window10 将程序的快捷方式加到右键"发送到"
    UML 类图基本了解
    php move_uploaded_file 上传的文件移动带中文文件名的的问题
    php 的 PHPExcel1.8.0 使用
    msyql 数据类型存储大小及数据范围
    MySQL数据库设计规范
    测试工具
    show tables 或者 show databases 结果太多如何再筛选
    ubuntu 16.04 周期定时任务 crontab 的 使用
  • 原文地址:https://www.cnblogs.com/renxiuxing/p/12831738.html
Copyright © 2011-2022 走看看