JDK8 新特性

一、Lambda表达式和函数式接口

// 参数e的类型是由编译器推理得出的,你也可以显式指定该参数的类型
        Arrays.asList("a","b","c").forEach(e -> System.out.println(e));
        // 指定该参数的类型
        Arrays.asList("a","b","c").forEach((String e) -> System.out.println(e));
        
        // 如果Lambda表达式需要更复杂的语句块,则可以使用花括号将该语句块括起来
        Arrays.asList("a","b","c").forEach(e -> {
            System.out.println(e + "kebi");
            System.out.println(e + "maidi");
        });
        
        // 引用类成员和局部变量(会将这些变量隐式得转换成final的)
        String pre ="connext";
        Arrays.asList("2018","2019").forEach(e -> System.out.println(pre + e));

二、方法引用

// 静态方法引用:ClassName::methodName
        List<Integer> ints = Arrays.asList(1,5, 3);
        ints.sort(Integer::compare);
        ints.forEach(i -> System.out.println(i));
        
        
        Car c1= new Car("benz");
        Car c2= new Car("bmw");
        List<Car> cars = Lists.newArrayList(c1, c2);
        cars.forEach(System.out::println);
        
        // 类的成员方法的引用 语法是Class::method,注意,这个方法没有定义入参:
        List<String> brands = cars.stream().map(Car::getBrand).collect(Collectors.toList());
        brands.forEach(e ->System.out.println(e));
        
        List<String> words = Arrays.asList("nba","cba");
        // 参数word的类型是由编译器推理得出
        words.stream().map(word -> word.length()); // lambda

三、Optional

// 如果Optional实例持有一个非空值,则isPresent()方法返回true,否则返回false;
        //Optional<String> nullStr = Optional.of(null);  空指针
        Optional<String> nullStr = Optional.ofNullable( null );
        System.out.println( "nullStr ? " + nullStr.isPresent() ); 
        
        
        Optional<String> firstName = Optional.of( "Tom" );
        System.out.println( "First Name is set? " + firstName.isPresent() );    
        
        // Optional实例持有null,则可以接受一个lambda表达式生成的默认值
        System.out.println( "First Name: " + firstName.orElseGet( () -> "[none]" ) ); 
        
        String test ="";
        System.out.println( Optional.of(test).orElse( " Hey Stranger!" ) );
        
        
        Car car = null;
        System.out.println(Optional.ofNullable(car).orElseGet(() -> new Car("bmw orElseGet")));
        System.out.println(Optional.ofNullable(car).orElse(new Car("bmw")));

四、Streams

List<Integer> strs = Arrays.asList(1,2,3,4);  
        Integer reduce = strs.stream().reduce(0,(x,y) -> x +y);
        Integer reduce2 = strs.stream().reduce(0,Integer::sum);
        System.out.println(reduce);
        // tasks集合被转换成steam表示;
        // 其次,在steam上的filter操作会过滤掉所有CLOSED的task;
        // 第三,mapToInt操作基于每个task实例的Task::getPoints方法将task流转换成Integer集合;
        // 最后,通过sum方法计算总和

        final Collection<Task> tasks = Arrays.asList(new Task(Status.OPEN, 5), new Task(Status.OPEN, 13),
                new Task(Status.CLOSED, 8));

        // 在这个task集合中一共有多少个OPEN状态的点?
        int sum = tasks.stream().filter(task -> task.getStatus() == Status.OPEN).mapToInt(Task::getPoints).sum();
        System.out.println(sum);// 18

        final double totalPoints = tasks.stream()
                // .parallel()
                .map(task -> task.getPoints()) // or map( Task::getPoints )
                .reduce(0, Integer::sum);
        System.out.println("totalPoints " + totalPoints);

        // 分组 对于一个集合,经常需要根据某些条件对其中的元素分组。
        // 利用steam提供的API可以很快完成这类任务,代码如下:
        // Group tasks by their status
        final Map<Status, List<Task>> map = tasks.stream().collect(Collectors.groupingBy(Task::getStatus));
        System.out.println(map);
        // {OPEN=[[OPEN, 5], [OPEN, 13]], CLOSED=[[CLOSED, 8]]}

    }

    private enum Status {
        OPEN, CLOSED
    };

五、Date/Time 

/**
     * 计算当前用户在1小时内发送短信的次数
     * @param now
     * @param limits
     * @return
     */
    private long hourCount(LocalDateTime now,List<Limit> limits){
        LocalDateTime preHour = now.plusHours(-1);
        return limits.stream().filter(limit -> {
            LocalDateTime insertTime = limit.getInsertTime();
            return insertTime.isBefore(preHour) && insertTime.isAfter(now);
        }).count();
    } 
    
    @Test
    public void test() {
        // 日期
        final LocalDate date = LocalDate.now();
        System.out.println( date );
        
        // 时分秒
        final LocalTime time = LocalTime.now();
        System.out.println( time );
        
        // 日期+ 时分秒
        final LocalDateTime datetime = LocalDateTime.now();
        System.out.println( datetime );
        
        // 最后看下Duration类,它持有的时间精确到秒和纳秒。这使得我们可以很容易得计算两个日期之间的不同
        final LocalDateTime from = LocalDateTime.of( 2014, Month.APRIL, 16, 0, 0, 0 );
        final LocalDateTime to = LocalDateTime.of( 2015, Month.APRIL, 16, 23, 59, 59 );

        final Duration duration = Duration.between( from, to );
        System.out.println( "Duration in days: " + duration.toDays() );
        System.out.println( "Duration in hours: " + duration.toHours() );
        //这个例子用于计算2014年4月16日和2015年4月16日之间的天数和小时数,输出结果如下:
    }
    
    class Limit{
        private LocalDateTime insertTime;
        private int phone;

Base64

final String text = "Base64 finally in Java 8!";

        final String encoded = Base64
            .getEncoder()
            .encodeToString( text.getBytes( StandardCharsets.UTF_8 ) );
        System.out.println( encoded );

        final String decoded = new String( 
            Base64.getDecoder().decode( encoded ),
            StandardCharsets.UTF_8 );
        System.out.println( decoded );

参考:

https://www.cnblogs.com/xingzc/p/6002873.html

分组参考;

https://blog.csdn.net/u011191463/article/details/62431421

原文地址:https://www.cnblogs.com/lyon91/p/10276587.html