JAVA8新特性详细演示(代码)

JAVA8新特性

1、Lambda表达式

1.1 Lambda表达式的介绍

  • 定义:特殊的匿名内部类 匿名内部类一种简化写法

  • 作用:使特殊的匿名内部类语法更简洁

  • 语法:

    <函数式接口> <变量名> =(参数1,参数2…)- >{

    ​ //方法体

    };

定义一个函数式接口
package com.my;

/**
 * 函数式接口 --一个接口只有一个抽象方法
 *
 * @FunctionalInterface 检测是否是函数式接口
 */
@FunctionalInterface
public interface Demo_Interface {
    void service();
}

1.2 Lambda的使用一

package com.my;

import java.util.Comparator;
import java.util.TreeSet;

/**
 * Lambda表达式
 *
 * 定义:特殊的匿名内部类 匿名内部类一种简化写法
 *
 * 作用:使特殊的匿名内部类语法更简洁
 *
 * 语法:
 *  <函数式接口> <变量名> =(参数1,参数2...)- >{
 *      //方法提
 *  };
 *
 */
public class Demo {
    public static void main(String[] args) {
        Demo_Interface demo=()-> System.out.println("Demo_Interface--被三次调用");
        run(demo);
        //Runnable创建线程
        Runnable runnable=new Runnable() {
            @Override
            public void run() {
                System.out.println("runnable被执行一次");
            }
        };
        new Thread(runnable).start();
        Runnable runnable2=()->System.out.println("runnable被执行二次");//方法体只有一句 可省略大括号
        new Thread(runnable2).start();
        new Thread(()-> System.out.println("runnable被执行三次")).start();//把lambda表达式当作参数传递


        //comparator比较器
        Comparator<String> comparable=new Comparator<String>() {
            @Override
            public int compare(String o1, String o2) {
                return o1.length()-o2.length();
            }
        };
        //Lambda表达式简化
        Comparator<String> comparable2=(o1, o2) ->o1.length()-o2.length();

        Comparator<String> comparable3=(String o1, String o2) ->{
                return o1.length()-o2.length();
        };
        //TreeSet中的比较器
        TreeSet<String> treeSet=new TreeSet<>(comparable);
        TreeSet<String> treeSet2=new TreeSet<>(comparable2);
        TreeSet<String> treeSet3=new TreeSet<>(comparable3);

    }

    public static void run(Demo_Interface demoInterface) {
        demoInterface.service();
    }

}

1.3 Lambda的使用二

package com.my;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;
import java.util.function.Consumer;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.function.Supplier;

public class Demo02 {
    public static void main(String[] args) {

        //匿名内部类方式 Consumer消费接口
        Consumer<Double> consumer=new Consumer<Double>() {
            @Override
            public void accept(Double aDouble) {
                System.out.println("第一次聚餐消费:"+aDouble);
            }
        };
        //Lambda表达式
        Consumer<Double> consumer2=(Double aDouble)-> System.out.println("第二次聚餐消费:"+aDouble);

        happy(consumer,200);
        happy(consumer2,400);
        happy(aDouble-> System.out.println("第三次聚餐消费:"+aDouble),600);

        int[] arr = getNums(() -> new Random().nextInt(100), 5);
        System.out.println(Arrays.toString(arr));

        String s1 = handlerString(s -> s.toUpperCase(), "    hello bb");
        String s2 = handlerString(s -> s.trim(), "    hello bb");
        System.out.println(s1);
        System.out.println(s2);

        List<String> names=new ArrayList<String>();
        names.add("张国光");
        names.add("李鸿章");
        names.add("张玲玲");
        names.add("王琦");
        List<String> stringList = filterName(s -> s.startsWith("张"), names);
        System.out.println(stringList.toString());
        List<String> stringList2 = filterName(s -> s.length()>2, names);
        System.out.println(stringList2.toString());

    }
    //Consumer 消费型接口
    public static void happy(Consumer<Double> consumer,double money){
        consumer.accept(money);
    }
    //Supplier 供给型接口
    public static int[] getNums(Supplier<Integer> supplier,int count){
        int[]arr=new int[count];
        for (int i=0;i<count;i++) {
            arr[i]=supplier.get();
        }
        return arr;
    }
    //Function 函数型接口 --既有参数又有返回值
    public static String handlerString(Function<String,String> function,String str){
        return function.apply(str);
    }
    //Predicate 断言型接口
    public static List<String> filterName(Predicate<String> predicate,List<String> list){
        List<String> resultList=new ArrayList<String>();
        for (String str:list){
            if(predicate.test(str)){
                resultList.add(str);//如果符合要求放进集合
            }
        }
        return resultList;
    }
}

1.4 方法引用

  •  定义:对Lambda表达式的简写形式
    
  •  条件:Lambda表达式方法体中只是调用一个特定已经存在的方法
    
  • 常见形式:
    •      对象::实例方法
      
    •      类::静态方法
      
    •      类::实例方法
      
    •      类::new
      
package com.my;

import java.util.Comparator;
import java.util.function.Consumer;
import java.util.function.Function;

/**
 * 方法引用的使用
 */
public class Demo04 {
    public static void main(String[] args) {

        //对象::实例方法
        Consumer<String> consumer=s-> System.out.println(s);
        consumer.accept("hello");
        Consumer<String> consumer1=System.out::println;

        //类::静态方法
        Comparator<Integer> comparator=(o1,o2) ->Integer.compare(o1,02);
        Comparator<Integer> comparator1=Integer::compare;


        //类::实例方法

        Function<User,Integer> user=u->u.getAge();

        Function<User,String> user2=User::getName;
        System.out.println(user.apply(new User("张三", 19)));
        //类::new
    }
}

2、Stream

2.1 什么是Stream?

流(Stream)中保存对集合或数组数据的操作。和集合类似,但集合中保存的是数据。这个流类似生活中的流水线,由原料用过一系列操作成产品

2.2 Stream特点

  • 不会存储数据
  • 不会改变源对象,会返回一个持有结果的新Stream
  • 操作是延迟执行,意味它们会等到需要结果的时候才执行

2.3 Stream使用步骤

  • 创建
    • ​ 新建一个流
  • 中间操作
    • 在一个或多个步骤中,将初始化Stream转化到另一个Stream的中间操作
  • 终止操作
    • 使用一个终止操作来产生一个结果,该操作会强制它之前的延迟操作立即执行。在这之后,该Stream再无法使用

2.4 创建Stream的几种方法

  • 通过Collection对象的Stream()–(单线程)或parallelStream()–(多线程可使用)方法

  • 通过Arrays类的stream()方法

  • 通过Stream接口of()、iterate()、generate()方法

  • 通过IntStream、LongStream、DoubleStream接口中的of、range、rangeClosed方法

    package com.my;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Random;
    import java.util.stream.IntStream;
    import java.util.stream.Stream;
    
    /**
     * Stream的创建方式
     */
    public class Demo05 {
        public static void main(String[] args) {
            System.out.println("--------1、Collection对象的Stream()----------");
            ArrayList<String> list=new ArrayList<>();
            list.add("哈哈");
            list.add("好好");
            list.add("嘿嘿");
            list.add("嘻嘻");
            list.add("嘎嘎");
            Stream<String> stream=list.stream();
            // Lambda遍历
            //stream.forEach(s->System.out.println(s));
            stream.forEach(System.out::println);
            System.out.println("--------2、Arrays的工具类的Stream方法----------");
            //2、Arrays的工具类的Stream方法
            String[] arr={"aa","bb","cc"};
            Stream<String> stringStream= Arrays.stream(arr);
            stringStream.forEach(System.out::println);
            //3、Stream接口中的of iterate generate方法
            System.out.println("--------Stream接口中的方法----------");
            //of
            Stream<Integer> stream1=Stream.of(10,20,30,40,50);
            stream1.forEach(System.out::println);
            System.out.println("--------迭代流---------");
            //迭代流 iterate
            Stream<Integer> iterate = Stream.iterate(0, x -> x + 2);
            //中间操作 十个数 0-10
            iterate.limit(10).forEach(System.out::println);
            System.out.println("--------生成流---------");
            //generate方法
            Stream<Integer> generate = Stream.generate(() -> new Random().nextInt(100));
            generate.limit(10).forEach(System.out::println);
    
            //4、通过IntStream、LongStream、DoubleStream接口中的of、range、rangeClosed方法
            System.out.println("-----IntStream的of------");
            IntStream stream2=IntStream.of(100,200,300);
            stream2.forEach(System.out::println);
            System.out.println("-----IntStream的range------");
            //IntStream的range开合  rangeClosed方法闭合
            IntStream stream3=IntStream.range(0,10);
            stream3.forEach(System.out::println);
            IntStream stream4=IntStream.rangeClosed(0,5);
            stream4.forEach(System.out::println);
        }
    }
    
    

2.5 常见的Stream中间操作、终止操作

2.5.1 中间操作

  • filter:过滤 limit限制 skip跳过 distinct去重 sorted排序
  • map 映射成另一组数据
  • parallel

2.5.2 终止操作

  • forEach min max count

  • reduce collect

    package com.my;
    
    import java.util.ArrayList;
    import java.util.List;
    import java.util.Optional;
    import java.util.stream.Collectors;
    
    /**
     * 关于Stream的中间操作、终止操作
     */
    public class Demo06 {
        public static void main(String[] args) {
            ArrayList<User> list=new ArrayList<User>();
            list.add(new User("哈哈",20));
            list.add(new User("嘻嘻",66));
            list.add(new User("嘿嘿",40));
            list.add(new User("谔谔",88));
            list.add(new User("嘻嘻",66));
            //过滤filter
            System.out.println("过滤filter");
            list.stream()
                    .filter(e->e.getAge()>40)
                    .forEach(System.out::println);
            //limit 限制
            System.out.println("limit 限制");
            list.stream().limit(2).forEach(System.out::println);
            //skip
            System.out.println("skip 跳过");
            list.stream().skip(2).forEach(System.out::println);
            //distinct 去重
            System.out.println("distinct 去重");
            list.stream().distinct().forEach(System.out::println);
            //sorted parallelStream比stream效率高 并行的
            System.out.println("sorted 排序");
            list.parallelStream().sorted((e1,e2)->Double.compare(e1.getAge(),e2.getAge()))
                    .forEach(System.out::println);
            //map 获取所有年龄
            System.out.println("map方式------获取所有年龄");
            list.stream().map(e->e.getAge())
                    .forEach(System.out::println);
            System.out.println("parallel 采用多线程效率");
            //parallel 采用多线程效率高
            list.stream().parallel().forEach(System.out::println);
            System.out.println("----------终止操作-------------------------");
            list.stream().filter(e->{
                System.out.println("终止操作过滤");
                return e.getAge() > 40;
            }).forEach(System.out::println);
            System.out.println("-----------计算最小年龄----------");
            Optional<User> user=list.stream()
                    .min((e1,e2)->Double.compare(e1.getAge(),e2.getAge()));
            System.out.println(user.get());
           System.out.println("计算数目");
            long count=list.stream().count();
            System.out.println("人数:"+count);
            System.out.println("终止操作reduce规约,计算所有任年龄和");
            Optional<Integer> sum=list.stream()
                    .map(e->e.getAge())
                    .reduce((x,y)->x+y);
            System.out.println(sum.get());
            System.out.println("终止操作collect收集,获取所有人员信息,封装成一个List集合");
    
            List<String> collect = list.stream()
                    .map(s -> s.getName())
                    .collect(Collectors.toList());
    
            for(String str:collect){
                System.out.println(str);
            }
    
        }
    }
    
    

3、 新时间API

3.1 遗留时间问题

jdk1.8之前时间API存在线程安全问题,设计混乱

注释的为jdk1.8之前,多线程运行多次会出现异常,注释下面的代码为jdk1.8的日期使用,避免问题

package com.my;

import java.text.SimpleDateFormat;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.concurrent.*;

/**
 * 存在线程安全问题
 */

public class Demo07 {
    public static void main(String[] args) throws ExecutionException, InterruptedException {

        //jdk1.6
        //SimpleDateFormat simple=new SimpleDateFormat("yyyyMMdd");
        //jdk1.8 解决以前时间线程安全问题
        DateTimeFormatter date = DateTimeFormatter.ofPattern("yyyyMMdd");
        //创建固定大小线程池
        ExecutorService executorService = Executors.newFixedThreadPool(10);
        //提交十个任务 每个任务都获取时间
        //Callable<Date> callable=new Callable<Date>() {
        Callable<LocalDate> callable = new Callable<LocalDate>() {
            /*@Override
            public Date call() throws Exception {
                //采用同步块使线程安全
                synchronized (simple){
                    return simple.parse("20200606");
                }
            }*/
            @Override
            public LocalDate call() throws Exception {
                return LocalDate.parse("20200606", date);
            }
        };

        //List<Future<Date>> list=new ArrayList<>();
        List<Future<LocalDate>> list=new ArrayList<>();
        for (int i=0;i<10;i++){
            //Future<Date> future=executorService.submit(callable);
            Future<LocalDate> future=executorService.submit(callable);
            list.add(future);
        }
        //for(Future<Date> future:list){
        for(Future<LocalDate> future:list){
                System.out.println(future.get());
            }
        
        executorService.shutdown();

    }
}

3.2 LocalDateTime的使用

package com.my;

import java.time.LocalDateTime;

public class Demo08 {
    public static void main(String[] args) {

        //LocalDateTime的使用
        LocalDateTime localDateTime=LocalDateTime.now();

        System.out.println(localDateTime);

        System.out.println(localDateTime.getYear());

        System.out.println(localDateTime.getMonthValue());

        //添加时间 两天
        LocalDateTime localDateTime1=localDateTime.plusDays(2);
        System.out.println(localDateTime1);

        //减少时间

        LocalDateTime localDateTime2=localDateTime.minusMonths(1);
        System.out.println(localDateTime2);
    }
}

3.3 Instant ZoneId的使用

package com.my;

import java.time.Duration;
import java.time.Instant;
import java.time.ZoneId;
import java.util.Set;

public class Demo09 {
    public static void main(String[] args) {

        //创建时间戳
        Instant instant=Instant.now();
        //格林尼治时区 错差八个小时
        System.out.println(instant.toString());
        //自1970-01-01T00:00:00Z时代以来的毫秒数。
        System.out.println(instant.toEpochMilli());
        //当前时间毫米数
        System.out.println(System.currentTimeMillis());

        //获取某个毫秒数的时间 Instant.ofEpochMilli()
        //获取某秒数的时间 Instant.ofEpochSecond()

        //2 添加  减少时间
        // 加 10s
        Instant instant1=instant.plusSeconds(10);
        //打印的是差毫秒单位
        System.out.println(Duration.between(instant, instant1).toMillis());

        //3 时区 当前系统支持时间的时区
        Set<String> set= ZoneId.getAvailableZoneIds();
        for (String str:set){
            System.out.println(str);
        }
        //获取当前时区
        System.out.println(ZoneId.systemDefault().toString());
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值