Java8新特性

一、java8新特性内容概述

  1. Lambda表达式;
  2. 方法引用、构造器引用;
  3. stream流:并行流、串行流;
  4. 接口的增强:静态方法、动态方法;
  5. Optional类;
  6. 新的时间的日期API
  7. 其他:重复注解、类型注解、通用目标类型判断;

速度更快
代码更少:增加了新的语法,lambda表达式
stream流
便于并行
最大化减少空指针异常:Optinal
Nashorn引擎,允许在jvm上运行js应用

二、Lambda表达式

写法:6种

public class Lambda {

    @Test
    public void test3(){
        // 语法格式一:无参无返回值
        Runnable er2 = ()-> System.out.println("345345346456");
        er2.run();

        // 语法格式二:有参无返回值
        Consumer<String> consumer = new Consumer<String>() {
            @Override
            public void accept(String s) {
                System.out.println(s);
            }
        };
        consumer.accept("5345345");

        // 语法格式二:有参无返回值
        Consumer<String> consumer2 = (String s) -> {
            System.out.println(s);
        };
        consumer2.accept("343543");

        // 引用写法
        Consumer<String> consumer3 = System.out::println;
        consumer3.accept("343543");

        // 语法格式三:类型推断,可以省略类型
        Consumer<String> consumer4 = (s) -> {
            System.out.println(s);
        };

        consumer4.accept("3435434343");

        // 语法格式四:参数只有一个,()可以省略
        Consumer<String> consumer5 = s -> {
            System.out.println(s);
        };

        consumer5.accept("343455434343");

    }


    @Test
    public void test2(){
        Comparator<Integer> comparator = new Comparator<Integer>() {
            @Override
            public int compare(Integer o1, Integer o2) {
                return Integer.compare(o1, o2);
            }
        };
        int compare = comparator.compare(12, 32);
        System.out.println(compare);

        // lambda表达式写法
        // 语法格式五:有参有返回值
        Comparator<Integer> comparator1 = (o1,o2) -> {
            return Integer.compare(o1, o2);
        };
        int compare1 = comparator1.compare(43, 22);
        System.out.println(compare1);

        // 方法引用
        Comparator<Integer> comparator2 = Integer::compareTo;
        int compare2= comparator2.compare(43, 22);
        System.out.println(compare2);

        // 语法格式六:lambda只有一条语句,{}和return都可以省略
        Comparator<Integer> comparator3 = (o1,o2) -> Integer.compare(o1, o2);
        int comparator33 = comparator3.compare(43, 22);
        System.out.println(comparator33);
        

    }

}

三、函数式接口

如果一个接口中只声明了一个抽象的方法,就叫函数式接口;
Lambda表达式的本质就是作为函数式接口的实例;
接口加@FunctionalInterface 注解定义可以验证,是不是函数式接口
在这里插入图片描述
在这里插入图片描述

四、方法引用与构造器引用

/**
 * 使用场景:
 *  1、对象::非静态方法(实例方法)
 *  2、类::静态方法
 *  3、类::非静态方法
 *
 *  使用要求:接口中的抽象方法的形参列表和返回值类型 和
 *  方法引用的方法形参列表和返回值类型 相同
 */
public class MethodRefTest {

    @Test
    void test1(){
        Consumer<String> consumer = str -> System.out.println(str);
        consumer.accept("被急加速");

        // 方法引用写法一 对象::非静态方法
        Consumer<String> consumer2 = System.out::println;
        // 或者
        PrintStream ps = System.out;
        Consumer<String> consumer3 = ps::println;

    }

    @Test
    void test2(){
        // 方法引用写法二 类::静态方法
        Comparator<Integer> comparator = Integer::compare;

    }

    @Test
    void test3(){
        Comparator<Integer> comparator = (s1,s2)-> s1.compareTo(s2);

        // 方法引用写法三 类::非静态方法(实例方法)
        Comparator<Integer> comparator3 = Integer::compareTo;
    }

}

五、构造器引用和数组引用

在这里插入图片描述

在这里插入图片描述

六、Stream API 666

是数据渠道。用于操作数据源所生成的元素序列。

public class StreamTest {

    // 通过集合创建Stream流

    @Test
    void test1(){
        UserData data = new UserData();
        List<User> userList = data.getUserList();
        // 默认是串行流
        Stream<User> stream = userList.stream();

        // 并行流
        Stream<User> userStream = userList.parallelStream();
    }


    // 通过数组创建Stream流
    @Test
    void test2(){

        IntStream stream = Arrays.stream(new int[]{1, 2, 3});

        UserData data = new UserData();
        User[] userArr = data.getUserArr();
        Stream<User> userStream = Arrays.stream(userArr);
    }

    // 通过Stream的of方法
    @Test
    void test3(){

        Stream<Integer> integerStream = Stream.of(1, 2, 3);
    }
}

Stream流的方法操作

 // stream的筛选与切片
    @Test
    public void test4(){
        UserData data = new UserData();
        List<User> userList = data.getUserList();
        
        // 查询手机号码是110d的用户,输出
        userList.stream().filter(e -> e.getPhone().equals("110")).forEach(System.out::println);
        System.out.println("===============");
        // limit(n) 截断流,使其元素不超过n
        userList.stream().limit(2).forEach(System.out::println);
        System.out.println("===============");
        // skip(n) 跳过元素前2个元素
        userList.stream().skip(2).forEach(System.out::println);
        System.out.println("===============");
        // distinct 去重,通过流所生成元素的hashcode()和equals()去重
        // 注意:distinct()用于基本数据类型和String可以去重,但对于对象,不能做到去重;
        // 可以在对象中重写hashcode()和equals()方法去重,或者
        //根据name属性去重
        userList.stream().filter(distinctByKey(User::getId)).forEach(System.out::println);
        // 或者,利用TreeSet
        userList.stream().collect(Collectors.collectingAndThen(
                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(User::getName))), ArrayList::new))
                .forEach(System.out::println);

    }

    public static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor){
        Map<Object,Boolean> seen = new ConcurrentHashMap<>();
        return t -> seen.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

map 与 flatmap 映射

// stream的映射 map  flatmap
    @Test
    public void test5(){
        UserData data = new UserData();
        List<User> userList = data.getUserList();
        // 拿到用户姓名长度大于3的用户姓名
        userList.stream().filter(user -> user.getName().length() > 3)
                .map(User::getName).forEach(System.out::println);

        // 转换成大小写
        List<String> strings = Arrays.asList("aa", "bb", "cc");
        strings.stream().map(String::toUpperCase).forEach(System.out::println);

        // Stream嵌套stream 比较map和flatmap的区别
        // map需要foreach两次
        Stream<Stream<Character>> streamStream = strings.stream().map(StreamTest::fromstreamToStream);
        streamStream.forEach(s -> {
            s.forEach(System.out::println);
        });
        // flatmap只需要一次foreach ,对于集合套集合的情况,优先flatmap
        Stream<Character> characterStream = strings.stream().flatMap(StreamTest::fromstreamToStream);
        characterStream.forEach(System.out::println);

    }

    public static Stream<Character> fromstreamToStream(String str){
          ArrayList<Character> list = new ArrayList<>();
          for(Character a : str.toCharArray()){
              list.add(a);
          }
           return list.stream();
    }
// 排序
    @Test
    public void test6() {

        // sorted 自然排序 数字默认从小到大排序 如果排序对象会报错,因为对象没有实现Compable排序接口
        List<Integer> integers = Arrays.asList(666, 44, -98, 1, 33, 44, 66, 77);
        integers.stream().sorted().forEach(System.out::println);
        System.out.println("============================");
        List<String> integers2 = Arrays.asList("斩杀", "ed", "44", "我的世界", "43534");
        integers2.stream().sorted().forEach(System.out::println);
        // sorted(Compator c) 定制排序
        UserData userData = new UserData();
        List<User> userList = userData.getUserList();
        // 默认从小到大
        userList.stream().sorted(Comparator.comparingInt(User::getPhone)).forEach(System.out::println);
        // 按照电话从小到大,按照从大到小
        userList.stream().sorted((e1, e2) -> {
           int v = Integer.compare(e1.getPhone(),e2.getPhone());
           if (v == 0){
               return v;
           }else {
               // 在前面加 - 负号
               return -Integer.compare(e1.getId(),e2.getId());
           }
        }).forEach(System.out::println);
    }

Stream流的终止操作

 // stream流的终止操作
    // 1、匹配与查找
    @Test
    public void test8(){
        // allMatch(Predicate e) 判断是否匹配所有元素
        List<User> userList = new UserData().getUserList();
        boolean b = userList.stream().allMatch(e -> e.getId() > 2);
        System.out.println(b);  // ----false
        List<User> userList2 = new UserData().getUserList();
        boolean c = userList.stream().allMatch(e -> e.getId() > 0);
        System.out.println(c); // ----true

        // anyMatch 判断是否至少匹配一个元素
        boolean d = userList.stream().anyMatch(e -> e.getId() > 0);
        System.out.println(d); // ----true

        // noneMatch 没有一个存在的,判断是否没有匹配的元素
        boolean f = userList.stream().noneMatch(e -> e.getId() < 0);
        System.out.println(f); // ----true

        // findFirst --返回第一个元素

        // findAny 返回任意一个元素
        Optional<User> any = userList.parallelStream().findAny();
        System.out.println(any);

        // count 返回元素的个数
        // max 返回流中的最大值
        // min 返回流中的最小值 --返回id最小的用户
        Optional<User> min = userList.stream().min(Comparator.comparingInt(User::getId));
        System.out.println(min);

    }
// 归约 reduce  收集collect
    @Test
    public void test9(){
        // 求1-5的和
        List<Integer> list = Arrays.asList(1,2,3,4,5);
        Integer reduce = list.stream().reduce(0, Integer::sum);
        System.out.println(reduce);
    }

在这里插入图片描述

七、Optional类

Optional类是一个容器类。可以避免空指针异常。是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回这个对象
在这里插入图片描述
在这里插入图片描述

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值