• java jdk8新特性学习


    1.学习lambda表达式 函数式编程

    1.1 DEMO1

    • 学习lambda表达式
    public class DMEO1 {
        public static void main(String[] args) {
            Runnable runnable = new Runnable() {
                @Override
                public void run() {
                    System.out.println("子线程执行");
                }
            };
            new Thread(runnable).start();
    
            //lambda表达式
            runnable = () -> System.out.println("子线程执行2");
            new Thread(runnable).start();
    
            new Thread(() -> System.out.println("子线程执行3")).start();
    
            //比较器
            //匿名内部类写法
            Comparator<String> com = new Comparator<String>() {
                @Override
                public int compare(String o1, String o2) {
                    return o1.length() - o2.length();
                }
            };
    
            //lambda表达式
            Comparator<String> com2 = (String o1, String o2) -> {
                return o1.length() - o2.length();
            };
            //形参类型自动推断
            Comparator<String> com3 = (o1, o2) -> o1.length() - o2.length();
            Comparator<String> com4 = Comparator.comparingInt(String::length);
            //匿名内部类会生成class文件,lambda不会生成class文件
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36

    1.2 DEMO2 Usb

    • 函数行接口入门
    • @FunctionalInterface //声明这是一个函数式接口
    public class DEMO2 {
    
        public static void main(String[] args) {
            //匿名内部类
            Usb mouse = new Usb() {
                @Override
                public void service() {
                    System.out.println("鼠标开始运动");
                }
    
            };
            mouse.service();
            //lanbda表达式
            Usb fan = () -> System.out.println("风扇开始运行。。。。");
            run(mouse);
            run(fan);
        }
    
        private static void run(Usb usb) {
            usb.service();
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    
    @FunctionalInterface //声明这是一个函数式接口
    public interface Usb {
        void service();
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5

    1.3 DEMO3

    • 四种函数型接口使用
    public class DEMO3 {
        public static void main(String[] args) {
    
            //使用lambda表达式
            happy(t -> System.out.println("聚餐消费了:" + t), 100);
            happy(t -> System.out.println("唱歌消费了:" + t), 200);
    
            int[] arr = getNums(() -> new Random().nextInt(100), 5);
            System.out.println(Arrays.toString(arr));
    
            //如果lambda表达式方法体中只是调用一个特定的已经存在的方法,则可以使用方法引用
            //常见形式有 对象::实例方法 类::静态方法 类::实例方法 类::new
            String abe = handlerString(s -> s.toUpperCase(), "abe");
            String abe1 = handlerString(String::toUpperCase, "abe"); //简写;方法引用
            String abe2 = handlerString(s -> s.trim(), " zhangsan      ");
            String abe3 = handlerString(String::trim, " zhangsan      ");
            System.out.println("abe = " + abe);
            System.out.println("abe1 = " + abe1);
            System.out.println("abe2 = " + abe2);
            System.out.println("abe3 = " + abe3);
    
            List<String> names = new ArrayList<>();
            names.add("zhangsan1");
            names.add("lisi");
            names.add("wangwu");
            names.add("zhangsan2");
    
            List<String> list = filterNames((s) -> s.startsWith("zhangsan"), names);
            System.out.println(list.toString());
    
            List<String> list2 = filterNames((s) -> s.length() > 4, names);
            System.out.println(list2.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> filterNames(Predicate<String> predicate, List<String> list) {
            List<String> resultList = new ArrayList<>();
            for (String string : list) {
                if (predicate.test(string)) {
                    resultList.add(string);
                }
            }
            return resultList;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66

    1.4 DEMO4

    • 如果lambda表达式方法体中只是调用一个特定的已经存在的方法,则可以使用方法引用
    • 常见形式有
      • 对象::实例方法
      • 类::静态方法
      • 类::实例方法
      • 类::new
    //如果lambda表达式方法体中只是调用一个特定的已经存在的方法,则可以使用方法引用
    //常见形式有 对象::实例方法 类::静态方法 类::实例方法 类::new
    public class DEMO4 {
        public static void main(String[] args) {
            //1.对象::实例方法
            Consumer<String> consumer = s -> System.out.println(s);
            Consumer<String> consumer1 = System.out::println;
            consumer.accept("hello");
            consumer1.accept("hello");
    
            //2.类::静态方法
            Comparator<Integer> com = (o1, o2) -> Integer.compare(o1, o2);
            Comparator<Integer> com1 = Integer::compare;
            int compare = com.compare(10, 9);
            int compare1 = com1.compare(10, 9);
            System.out.println("compare = " + compare);
            System.out.println("compare1 = " + compare1);
    
            //3.类::实例方法
            Function<Employee, String> function = e -> e.getName();
            Function<Employee, String> function1 = Employee::getName;
            String name = function.apply(new Employee("zhangsan", "100"));
            String name1 = function1.apply(new Employee("lisi", "100"));
            System.out.println("name = " + name);
            System.out.println("name1 = " + name1);
    
            //4.类::new
            Supplier<Employee> supplier = () -> new Employee();
            Supplier<Employee> supplier1 = Employee::new;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    public class Employee {
        private String name;
        private String money;
    
        public Employee(String name, String money) {
            this.name = name;
            this.money = money;
        }
    
        public Employee() {
    
        }
    
        public String getName() {
            return name;
        }
    
        public void setName(String name) {
            this.name = name;
        }
    
        public String getMoney() {
            return money;
        }
    
        public void setMoney(String money) {
            this.money = money;
        }
    
        @Override
        public String toString() {
            return "Employee{" +
                    "name='" + name + '\'' +
                    ", money='" + money + '\'' +
                    '}';
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37

    2.学习stream

    • Stream 自己不会存储元素
    • Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream
    • Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行

    2.1使用stream

    创建:创建一个流

    • 通过Collection对象的stream()或者parallelStream()方法;parallelStream是并行流
    • 通过Arrays类的stream()方法
    • 通过stream接口的of()、iterate()、generate()方法
    • 通过IntStream、LongStream、DoubleStream接口中的of()、range()、rangeClosed()方法
    public class Demo1 {
        public static void main(String[] args) {
            // 1.通过Collection对象的stream()或者parallelStream()方法;parallelStream是并行流
            ArrayList<String> arrayList = new ArrayList<>();
            arrayList.add("zhangsan");
            arrayList.add("lisi");
            arrayList.add("zhaowu");
    
            Stream<String> stream = arrayList.stream();
            //遍历
            //      stream.forEach(s-> System.out.println(s));
            stream.forEach(System.out::println);
    
            //并行流
            Stream<String> stream1 = arrayList.parallelStream();
            stream1.forEach(System.out::println);
    
            // 2.通过Arrays工具类的stream()方法
            String[] arr = {"aaa", "bbb", "ccc"};
            Stream<String> stream2 = Arrays.stream(arr);
            stream2.forEach(System.out::println);
    
            // 3.通过stream接口的of()、iterate()、generate()方法
            Stream<Integer> stream3 = Stream.of(10, 20, 30, 40);
            stream3.forEach(System.out::println);
            //迭代流
            Stream<Integer> iterate = Stream.iterate(0, x -> x + 2);
            iterate.limit(10).forEach(System.out::println);
            //生成流
            Stream<Integer> generate = Stream.generate(() -> new Random().nextInt(100));
            generate.limit(10).forEach(System.out::println);
    
            // 4.通过IntStream、LongStream、DoubleStream接口中的of()、range()、rangeClosed()方法
            IntStream intStream = IntStream.of(100, 200, 300);
            intStream.forEach(System.out::println);
            IntStream.range(0,50).forEach(System.out::println); //0-49
            IntStream.rangeClosed(0,50).forEach(System.out::println);//0-50
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41

    中间操作:在一个或多个步骤中,将初始stream转换到另一个stream的中间操作

    • filter 过滤
    • limit 限制
    • skip 跳过
    • distinct 去重
    • sorted 排序
    • map 映射为map
    • parallel 获取并行流
    public class DEMO2 {
        public static void main(String[] args) {
            ArrayList<Employee> list = new ArrayList<>();
            list.add(new Employee("小王",15000));
            list.add(new Employee("小张",12000));
            list.add(new Employee("小李",18000));
            list.add(new Employee("小孙",17000));
            list.add(new Employee("小刘",15000));
            list.add(new Employee("小刘",15000));
    
            //中间操作
            System.out.println("-------1. filter 过滤-----------");
            // 1. filter 过滤
            list.stream()
                    .filter(e->e.getMoney()>15000)
                    .forEach(System.out::println);
            System.out.println("-------2. limit 限制-----------");
            // 2. limit 限制
            list.stream()
                    .limit(2)
                    .forEach(System.out::println);
            System.out.println("-------3. skip 跳过-----------");
            // 3. skip 跳过
            list.stream()
                    .skip(2)
                    .forEach(System.out::println);
    
            System.out.println("-------4. distinct 去重-----------");
            // 4. distinct 去重
            list.stream()
                    .distinct()
                    .forEach(System.out::println); //去重的依据是重写hashcode和equal
    
            System.out.println("-------5. sorted 排序-----------");
            // 5. sorted 排序
            list.stream()
                    .sorted(Comparator.comparingDouble(Employee::getMoney))
                    .forEach(System.out::println);
    
            System.out.println("-------6. map 映射为map-----------");
            // 6. map 映射为map
            list.stream()
                    .map(Employee::getName)
                    .forEach(System.out::println);
            System.out.println("-------7. parallel 获取并行流-----------");
    
            // 7. parallel 获取并行流 采用多线程,效率相对高
            list.parallelStream()
                    .forEach(System.out::println);
    
    
            /**
             * 演示串行流和并行流的区别
             */
            ArrayList<String> list1 = new ArrayList<>();
            for (int i = 0; i < 500000; i++) {
                list1.add(UUID.randomUUID().toString());
            }
    
            //串行
            long start = System.currentTimeMillis();
            long count = list1.stream().sorted().count();
            System.out.println("count = " + count);
            long end = System.currentTimeMillis();
            System.out.println("用时:"+(end-start));
    
            //并行
            long start1 = System.currentTimeMillis();
            long count1 = list1.parallelStream().sorted().count();
            System.out.println("count1 = " + count1);
            long end1 = System.currentTimeMillis();
            System.out.println("用时:"+(end1-start1));
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58
    • 59
    • 60
    • 61
    • 62
    • 63
    • 64
    • 65
    • 66
    • 67
    • 68
    • 69
    • 70
    • 71
    • 72
    • 73
    • 74
    • 75

    终止操作:使用一个终止操作来产生一个结果。该操作会强制它之前的延迟操作立即执行。在这之后,该stream就不能使用了。

    • forEach
    • min
    • max
    • count
    • reduce
    • collect 收集
    public class DEMO3 {
    
        public static void main(String[] args) {
            ArrayList<Employee> list = new ArrayList<>();
            list.add(new Employee("小王", 15000));
            list.add(new Employee("小张", 12000));
            list.add(new Employee("小李", 18000));
            list.add(new Employee("小孙", 17000));
            list.add(new Employee("小刘", 15000));
            list.add(new Employee("小刘", 15000));
    
    
            //终止操作
            list.stream()
                    .filter(e -> {
                        System.out.println("执行过滤了。。。");
                        return e.getMoney() > 15000;
                    }) //中间操作延迟执行
                    .forEach(System.out::println);
    
    
            System.out.println("---------------min---------------------");
            //Optional防止空指针
            Optional<Employee> min = list.stream()
                    .min(Comparator.comparingDouble(Employee::getMoney));
            System.out.println(min.get());
    
            System.out.println("---------------count---------------------");
            long count = list.stream().count();
            System.out.println(count);
    
    
            System.out.println("---------------reduce---------------------");
            //reduce 规约
            //计算所有员工的工资和
            Optional<Integer> reduce = list.stream()
                    .map(Employee::getMoney)
                    .reduce((x, y) -> x + y);
            System.out.println(reduce.get());
    
            System.out.println("---------------collect---------------------");
            //collect
            //获取员工信息后,封装成一个list集合
            List<String> collect = list.stream()
                    .map(Employee::getName)
                    .collect(Collectors.toList());
            collect.forEach(System.out::println);
    
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    
    public class DEMO1 {
        public static void main(String[] args) {
            List<UserInfo> userInfoList = new ArrayList<>();
            userInfoList.add(new UserInfo(1L, "捡田螺的小男孩", 18));
            userInfoList.add(new UserInfo(2L, "程序员田螺", 27));
            userInfoList.add(new UserInfo(2L, "捡瓶子的小男孩", 26));
    
            System.out.println("===================1.list转map=========================");
            /**
             *  list 转 map
             *  使用Collectors.toMap的时候,如果有可以重复会报错,所以需要加(k1, k2) -> k1
             *  (k1, k2) -> k1 表示,如果有重复的key,则保留第一个,舍弃第二个
             */
            Map<Long, UserInfo> userInfoMap = userInfoList.stream().collect(Collectors.toMap(UserInfo::getId, userInfo -> userInfo, (k1, k2) -> k1));
            userInfoMap.values().forEach(a-> System.out.println(a.getName()));
    
            System.out.println("===================2.groupingBy分组=========================");
    
            List<UserInfo> originUserInfoList = new ArrayList<>();
            originUserInfoList.add(new UserInfo(1L, "捡田螺的小男孩", 18,"深圳"));
            originUserInfoList.add(new UserInfo(3L, "捡瓶子的小男孩", 26,"湛江"));
            originUserInfoList.add(new UserInfo(2L, "程序员田螺", 27,"深圳"));
            //提到分组,相信大家都会想起SQL的group by。我们经常需要一个List做分组操作。比如,按城市分组用户。在Java8之前,是这么实现的:
            HashMap<String, List<UserInfo>> result  = new HashMap<>();
            for (UserInfo userInfo : originUserInfoList) {
                String city = userInfo.getCity();
                List<UserInfo> userInfos = result.get(city);
                if (userInfos == null) {
                    userInfos = new ArrayList<>();
                    result.put(city, userInfos);
                }
                userInfos.add(userInfo);
            }
    
            //而使用Java8的groupingBy分组器,清爽无比:
            Map<String, List<UserInfo>> collect = originUserInfoList.stream()
                    .collect(Collectors.groupingBy(UserInfo::getCity));
            
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42

    3.新时间API

    3.1 之前的时间API存在问题:线程安全问题、设计混乱

    3.2 本地化日期时间API

    • LocalDate 日期
    • LocalTime 时间
    • LocalDateTime 日期时间
    //LocalDateTime的使用
    public class DEMO3 {
    
        public static void main(String[] args) {
            LocalDateTime localDateTime = LocalDateTime.now();
    //        LocalDateTime localDateTime2 = LocalDateTime.of(year,month,dayofMonth,hour,minute);
            System.out.println("localDateTime = " + localDateTime);
            System.out.println("localDateTime.getYear() = " + localDateTime.getYear());
            System.out.println("localDateTime.getMonthValue() = " + localDateTime.getMonthValue());
            System.out.println("localDateTime.getDayOfMonth() = " + localDateTime.getDayOfMonth());
    
            //添加2天
            LocalDateTime plusDays = localDateTime.plusDays(2);
            System.out.println("plusDays = " + plusDays);
    
            //减少一个月
            LocalDateTime minusMonths = localDateTime.minusMonths(1);
            System.out.println("minusMonths = " + minusMonths);
    
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    3.3 Instant 时间戳

    3.4 ZoneId 时区

    3.5 Date 、Instant 、LocalDateTime的转换

    //Instant 时间戳
    //ZoneId 时区
    public class DEMO4 {
        public static void main(String[] args) {
            //Instant 时间戳
            Instant instant = Instant.now();
            System.out.println("now = " + instant); //与当时间差8个小时
            System.out.println("+=================================");
            System.out.println(instant.toEpochMilli()); //当前时间戳
            System.out.println(System.currentTimeMillis());
            System.out.println("+=================================");
            //添加10秒钟
            Instant instant1 = instant.plusSeconds(10);
            //相差时间
            System.out.println(Duration.between(instant,instant1).toMillis());
            System.out.println("+=================================");
            //ZoneId 时区
            Set<String> availableZoneIds = ZoneId.getAvailableZoneIds();
            for (String availableZoneId : availableZoneIds) {
                System.out.println(availableZoneId);
            }
    
            System.out.println("+=================================");
    
            System.out.println(ZoneId.systemDefault().toString());
    
    
            System.out.println("+=================================");
            // Date =>Instant=>LocalDateTime
            Date date = new Date();
            Instant instant2 = date.toInstant();
            System.out.println("instant2 = " + instant2);
            LocalDateTime localDateTime = LocalDateTime.ofInstant(instant2, ZoneId.systemDefault());
            System.out.println("localDateTime = " + localDateTime);
    
            //LocalDateTime =>Instant=>Date
            System.out.println("+=================================");
            Instant instant3 = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
            System.out.println("instant3 = " + instant3);
            Date from = Date.from(instant3);
            System.out.println("from = " + from);
        }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44

    3.6 DateTimeFormatter 格式化类

    //DateTimeFormatter 格式化类
    public class DEMO5 {
        public static void main(String[] args) {
            DateTimeFormatter dft = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss");
            //把时间格式化成字符串
            String format = dft.format(LocalDateTime.now());
            System.out.println("format = " + format);
            System.out.println("+============================");
            //把字符串解析为时间
            LocalDateTime localDateTime = LocalDateTime.parse("2022-11-27 14:27:24", dft);
            System.out.println("localDateTime = " + localDateTime);
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
  • 相关阅读:
    python经典百题之特殊图形打印
    Swift--字符、字符串与集合类型
    Ubuntu 22.04.3 LTS单机私有化部署sealos desktop
    决策树与随机森林
    Panorama SCADA平台的警报通知功能配置详解
    float 浮动
    授权控制-数据库用户分类、授权(GRANT)、收权(REVOKE)
    图论篇--代码随想录算法训练营第五十六天打卡| 108. 冗余连接,109. 冗余连接II
    小白一键系统重装系统GHO文件如何下载教程
    AI智能分析网关V4智慧工厂视频智能监管与风险预警平台建设方案
  • 原文地址:https://blog.csdn.net/qq_42836388/article/details/128064167