jdk1.8新特性

java8(jdk1.8),是java语言的一个主要版本,oracle公司于2014年3月18日发布的。2017年之后oracle决定每半年发布一次版本。

  • 支持Lambda表达式
  • 函数式接口
  • 新的Stream API
  • 新的日期API
  • 其他特性(接口变化:包含静态方法和默认方法)

Lambda表达式定义
Lambda表达式:特殊的匿名内部类,语法更简洁,允许把函数作为一个方法的参数
Lambda表达式语法

<函数式接口>  <变量名> =  (参数1,参数2...)->{
  方法体;
}

Lambda表达式总结

  • 箭头将表达式分为两部分,左侧为参数,右侧为方法体
  • 形参类型可以自动推断
  • 如果形参列表为空,只需保留()
  • 如果形参只有1个,()可以省略,只需参数名即可
  • 如果执行语句只有1句,且无返回值,{}可以省略,若有返回值,若想省去{},则必须同时省略returun,且执行语句也保证这有一句
  • lambad不会生成内部类文件
public static void main(String[] args) {
        System.out.println("主线程第一步");
        Runnable runnable1 = new Runnable() {
            @Override
            public void run() {
                System.out.println("正常匿名内部类无参");
            }
        };
        //new Thread()省略了
        //方法名称省略了
        //()代表无参方法,不能省略
        //->箭头表达式
        //lambad如果方法体就一句话可以省略大括号
        //Runnable接口中只有一个抽象方法
        Runnable thread2 = () -> System.out.println("Lambda无参");


        new Thread(runnable1).start();
        new Thread(thread2).start();
        new Thread(() -> System.out.println("正常匿名内部类无参")).start();
        System.out.println("主线程第二步");


        Comparator c1 = new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.length() - o2.length();
            }
        };
        //方法名可以省略
        //参数不能省略
        // Comparator接口中只有一个抽象方法 equals数据Object类的 不算
        Comparator<String> c2 = (String o1, String o2) -> {
            return o1.length() - o2.length();
        };
        //参数类型可以省略
        //参数名不可以省略
        Comparator<String> c3 = (o1, o2) -> o1.length() - o2.length();

        String[] str = {"aadsaf", "dqwd", "dqwfcsqc", "xqsccaac", "csfwffqaf", "czxca", "cas", "cacs", "casc"};
        Arrays.sort(str, c3);
        System.out.println(Arrays.toString(str));


    }

函数式接口定义

  • 如果一个接口只有一个抽象方法,则该接口称为函数式接口,函数式接口可以使用lambda表达式,lambda表达式会被匹配到这个抽象方法上
  • @FunctionalInterface判断是否函数式接口,只有标记了该注解的接口,才能使用lambad表达式

jdk中常见的函数式接口
在这里插入图片描述

@FunctionalInterface
public interface Usb {
    void service(String name);
}
public static void main(String[] args) {
        //自定义函数式接口
        Usb usb =name-> System.out.println("Usb接口实现--"+name);
        usb.service("键盘");

        paly(name-> System.out.println("Usb接口实现--"+name),"鼠标");


        //常用函数式接口实现--消费型
        consumer((t)-> System.out.println("聚餐消费:"+t),1000);
        consumer((t)-> System.out.println("唱歌消费:"+t),500);

        //常用函数式接口实现--供给型
        System.out.println(Arrays.toString(supplier(()->new Random().nextInt(9),9)));

        //常用函数式接口实现--函数型
        System.out.println("把zhangsan编程大写:"+function(name->name.toUpperCase(),"zhangsan"));
        //常用函数式接口实现--断言型
        List<String> names = Arrays.asList("zhangsan", "lisi", "wangwu");
        System.out.println("names集合中是否包含zhangsan:"+predicate(list->list.contains("zhangsan"),names));

    }
    public static Boolean predicate(Predicate<List<String>> predicate ,List<String> names){
        return predicate.test(names);

    }

    public static String function(Function<String,String> function,String name){
        return function.apply(name);
    }

    public static Integer[] supplier(Supplier<Integer> supplier,Integer count){
        Integer[] arry = new Integer[count];
        for (int i = 0; i < count; i++) {
            arry[i]=supplier.get();
        }
        return arry;
    }

    public static void consumer(Consumer<Double> consumer,double money){
        consumer.accept(money);
    }


    public  static  void paly(Usb usb,String name){
        usb.service(name);
    }

方法引用
方法引用是lambad表达式的一种简写形式。如果lambad表达式方法体中只是调用一个特定的已经存在的方法,则可以使用方法引用
常见形式

  • 对象::实例方法
  • 类::静态方法
  • 类::实例方法
  • 类::new
public static void main(String[] args) {
        Consumer<String> consumer = fruits-> System.out.println(fruits);
        consumer.accept("香蕉");

        //如果lambad表达式中只调用了一个方法
        //并且这个lambad表达式的特点和接口的特点一样:只有一个参数  没有返回值,可以同时省略匿名函数的参数列表,和方法体中的参数列表
        //就可以使用方法引用 对象::实例方法
        Consumer<String> consumer1 =  System.out::println;
        consumer1.accept("苹果");

        //类::静态方法
        Comparator<Integer> comparator1 = (o1,o2)->Integer.compare(o1,o2);
        Comparator<Integer> comparator2 = Integer::compareTo;
        Integer[] array = {9,8,7,6,5,4};
        Arrays.sort(array, comparator2);
        System.out.println(Arrays.toString(array));

        //类::实例方法
        Function<String,String> function1= name->name.toUpperCase();
        System.out.println(function1.apply("zhangsan"));
        Function<String,String> function2= String::toUpperCase;
        System.out.println(function2.apply("zhangsan"));

        //类::new
        Supplier<ArrayList> supplier = ()->new ArrayList<>();
        System.out.println(supplier.get());
        Supplier<ArrayList> supplier1 = ArrayList::new;
        System.out.println(supplier1.get());

    }

Stream
流(Stream)中保存对集合或数组数据的操作,和集合类似,但集合中保存的是数据,类似流水线
在这里插入图片描述
特点

  • Stream自己不会存储元素
  • Stream不会改变源对象。相反,他们会返回一个特有结果的新的Stream
  • Stream操作是延迟执行的,这意味着他们会等到需要结果的时候才执行,也就是执行流的终止操作的时候才执行
  • 每次创建的stream只能使用一次,否则异常:java.lang.IllegalStateException: stream has already been operated upon or closed

使用步骤

  1. 创建

      新建一个流
    
    public static void main(String[] args) {
        //通过Collection对象的stream()串行流
        //通过Collection对象的parallelStream()并行流
        List<String> list = new ArrayList<>();
        list.add("苹果");
        list.add("香蕉");
        Stream<String> stream1 = list.stream();
        stream1.forEach(item -> System.out.println(item));
        System.out.println("通过Collection对象的stream()串行流----------------");
    
        //通过 Arrays.stream()方法
        int[] a = {0, 9, 8};
        IntStream stream2 = Arrays.stream(a);
        stream2.forEach(System.out::println);
        System.out.println("Arrays.stream----------------");
    
        //通过  Stream.of()、   Stream.iterate()、Stream.generate()方法
        Stream<Integer> stream3 = Stream.of(1, 2, 3);
        stream3.forEach(System.out::println);
        System.out.println("Stream.of----------------");
    
        //种子,一元操作符  从0开始 之后每次加2
        Stream<Integer> stream4 = Stream.iterate(0, x -> x + 2);
        //limit取前10
        stream4.limit(10).forEach(System.out::println);
        System.out.println(" Stream.iterate----------------");
    
        Stream<Integer> stream5 = Stream.generate(() -> new Random().nextInt(100));
        stream5.limit(2).forEach(System.out::println);
        System.out.println(" Stream.generate----------------");
    
        //通过IntStream LongStream   DoubleStream 接口中的 of range rangeClosed方法
        IntStream stream6 = IntStream.of(1, 2);
        stream6.forEach(System.out::println);
        System.out.println("IntStream.of----------------");
    
        //包括2
        IntStream stream7 = IntStream.rangeClosed(0, 2);
        stream7.forEach(System.out::println);
        System.out.println("IntStream.rangeClosed----------------");
    
        //不包括2
        IntStream stream8 = IntStream.range(0, 2);
        stream8.forEach(System.out::println);
        System.out.println("IntStream.range----------------");
    
        //public interface UnaryOperator<T> extends Function<T, T>
        //是函数型接口
        UnaryOperator<Integer> dda = x -> x + 1;
        //11
        System.out.println(dda.apply(1));
        //a1
        UnaryOperator<String> ddb = x -> x + 1;
        System.out.println(ddb.apply("aa"));
    
    }
    
  2. 中间操作

      在一个或者多个操作步骤中,将初始化Stream转化到另一个Stream的中间操作 
    
    public static void main(String[] args) {
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        list.stream()
                .filter(item->item>5)
                .forEach(System.out::println);
        System.out.println("过滤大于5的数----------");
        list.stream()
                .limit(2)
                .forEach(System.out::println);
        System.out.println("取前两个----------");
        list.stream()
                .skip(2)
                .forEach(System.out::println);
        System.out.println("跳过前两个----------");
        list.stream()
                .distinct()
                .forEach(System.out::println);
        System.out.println("去重----------");
        list.stream()
                .sorted((o1,o2)->o2-o1)
                .forEach(System.out::println);
        System.out.println("从大到小排序----------");
    
        list.stream()
                .map(e->e.doubleValue())
                .forEach(System.out::println);
        System.out.println("把一组数据映射成另外一组数据----------");
        list.parallelStream()
                .forEach(System.out::println);
        System.out.println("并行流----------");
    }
    
  3. 终止操作

      使用一个终止操作来产生一个结果。该操作会强制它之前的延迟操作立即执行。在这之后,该stream就不会使用了
    
    public static void main(String[] args) {
    
        List<Integer> list = new ArrayList<>();
        list.add(1);
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(6);
        //forEach
        list.stream().forEach(System.out::println);
        System.out.println("forEach------------");
        System.out.println(list.stream().min((o1, o2) -> o1 - o2).get());
        System.out.println("min------------");
        System.out.println(list.stream().max((o1, o2) -> o1 - o2).get());
        System.out.println("max------------");
        System.out.println(list.stream().max((o1, o2) -> o1 - o2).get());
        System.out.println(list.stream().count());
        System.out.println("count------------");
        System.out.println(list.stream().reduce((x, y) -> x + y).get());
        System.out.println("reduce------------");
        System.out.println(list.stream().collect(Collectors.toSet()));
        System.out.println("collect------------");
    }
    

新时间Api
之前时间Api存在的问题:新城安全问题,设计混乱
老的时间apid存在的线程安全问题演示

 public static void main(String[] args) throws Exception{
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd");
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        List<Future<Date>> list = new ArrayList<>();
        for (int i = 0; i <100; i++) {
            //submit有返回值 execute不能有返回值
            Future<Date> submit = executorService.submit(() -> sdf.parse("2021-04-18"));
            //放到集合里的目的是运行出下面的错误
            list.add(submit);
        }
        for (Future<Date> dateFuture : list) {
            System.out.println(dateFuture.get());
        }

        executorService.shutdown();
    }

多运行几次出现的bug
Exception in thread “main” java.util.concurrent.ExecutionException: java.lang.NumberFormatException: For input string: “”
at java.util.concurrent.FutureTask.report(FutureTask.java:122)
at java.util.concurrent.FutureTask.get(FutureTask.java:192)
at time.Problem.main(Problem.java:22)
Caused by: java.lang.NumberFormatException: For input string: “”
at java.lang.NumberFormatException.forInputString(NumberFormatException.java:65)
at java.lang.Long.parseLong(Long.java:601)
at java.lang.Long.parseLong(Long.java:631)
at java.text.DigitList.getLong(DigitList.java:195)
at java.text.DecimalFormat.parse(DecimalFormat.java:2051)
at java.text.SimpleDateFormat.subParse(SimpleDateFormat.java:1869)
at java.text.SimpleDateFormat.parse(SimpleDateFormat.java:1514)
at java.text.DateFormat.parse(DateFormat.java:364)
at time.Problem.lambda$main 0 ( P r o b l e m . j a v a : 17 ) a t j a v a . u t i l . c o n c u r r e n t . F u t u r e T a s k . r u n 0(Problem.java:17) at java.util.concurrent.FutureTask.run 0(Problem.java:17)atjava.util.concurrent.FutureTask.run$ c a p t u r e ( F u t u r e T a s k . j a v a : 266 ) a t j a v a . u t i l . c o n c u r r e n t . F u t u r e T a s k . r u n ( F u t u r e T a s k . j a v a ) a t j a v a . u t i l . c o n c u r r e n t . T h r e a d P o o l E x e c u t o r . r u n W o r k e r ( T h r e a d P o o l E x e c u t o r . j a v a : 1149 ) a t j a v a . u t i l . c o n c u r r e n t . T h r e a d P o o l E x e c u t o r capture(FutureTask.java:266) at java.util.concurrent.FutureTask.run(FutureTask.java) at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) at java.util.concurrent.ThreadPoolExecutor capture(FutureTask.java:266)atjava.util.concurrent.FutureTask.run(FutureTask.java)atjava.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)atjava.util.concurrent.ThreadPoolExecutorWorker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)

LocalDateTime LocalDate LocalTime用法一样

public static void main(String[] args) {
        LocalDateTime now = LocalDateTime.now();
        System.out.println(now);
        System.out.println(now.getYear());
        System.out.println(now.getMonth());
        System.out.println(now.getMonthValue());
        //新的时间对象
        LocalDateTime localDateTime = now.plusDays(2);
        System.out.println(localDateTime);
        System.out.println(now.minusMonths(1));
    }

Instant、 ZoneId、以及三种时间格式的转化

public static void main(String[] args) {
        Instant now = Instant.now();
        //咱们地区和格林泥治时间差了8个小时
        System.out.println(now.toString());
        //比1970-01-01所差时间不差
        System.out.println(now.toEpochMilli());
        System.out.println(System.currentTimeMillis());
        //添加和减少时间
        Instant instant = now.plusSeconds(2);
        System.out.println(Duration.between(now,instant).getSeconds());
        //获取所有时区
        Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
        for (String availableZoneId : availableZoneIds) {
            System.out.println(availableZoneId);
        }
        //获取当前时区
        System.out.println( ZoneId.systemDefault());

        //Date--->Instant---->LocalDateTime
        System.out.println("Date--->Instant---->LocalDateTime");
        Date date = new Date();
        System.out.println(date);
        Instant instant1 = date.toInstant();
        System.out.println(instant1);
        LocalDateTime localDateTime = LocalDateTime.ofInstant(instant1, ZoneId.systemDefault());
        System.out.println(localDateTime);

        System.out.println("LocalDateTime--->Instant---->Date");
        ZonedDateTime zonedDateTime = localDateTime.atZone(ZoneId.systemDefault());
        Instant instant2 = zonedDateTime.toInstant();
        System.out.println(instant2);
        Date from = Date.from(instant2);
        System.out.println(from);

    }

DateTimeFormatter 的使用

public static void main(String[] args) {
        DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern("yyyy-MM-dd");
        String format = dateTimeFormatter.format(LocalDate.now());
        System.out.println(format);
        LocalDate parse = LocalDate.parse("2021-04-18", dateTimeFormatter);
        System.out.println(parse);
    }

其他新特性:接口中可以包含的组成部分

1.抽象方法

2.常量

3.默认方法(JDK8)

4.静态方法(JDK8)

5.私有方法(JDK9)
  在这里插入图片描述

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值