JAVA8新特性(Stream API,LocalDate,LocalDateTime)

这篇具有很好参考价值的文章主要介绍了JAVA8新特性(Stream API,LocalDate,LocalDateTime)。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

一. Stream API

1.1 基础
代码参数准备:
package com.weige.javaskillpoint.controller;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.stream.Collectors;
@Slf4j
public class JAVA8 {

    @Data
    static class User {
        // 姓名
        private String name;
        // 手机号
        private String phone;
        // 年龄
        private Integer age;

        public User(String name, String phone, Integer age) {
            this.name = name;
            this.phone = phone;
            this.age = age;
        }

    }

    private static List<User> getUserList() {
        return new ArrayList<User>() {{
            add(new User("周润发", "166", 52));
            add(new User("周星驰", "155", 42));
            add(new User("刘德华", "177", 62));
            add(new User("伍佰", "188", 45));
            add(new User("周传雄", "133", 40));
            add(new User("甄子丹", "199", 45));
        }};
    }

}
场景一:知道一个List<User>对象,如何获取List<User>的所有用户id?
    public static void main(String[] args) {
        // 知道一个List<User>对象,如何获取List<User>的所有用户手机号?
        List<User> userList = getUserList();
        List<String> phoneList = userList.stream().map(User::getPhone).collect(Collectors.toList());
        // 打印内容 - 所有用户手机号为 [166, 155, 177, 188, 133, 199]
        log.info("所有用户手机号为 " + phoneList);
    }
场景二:知道一个List<User>对象,如何获取List<User>中年龄大于50的用户?
    public static void main(String[] args) {
        // 知道一个List<User>对象,如何获取List<User>中年龄大于50的用户?
        List<User> userList = getUserList();
        List<User> filterUserList = userList.stream().filter(u -> u.getAge() > 50).collect(Collectors.toList());
        // 打印内容 - 年龄大于50的用户为 [JAVA8.User(name=周润发, phone=166, age=52), JAVA8.User(name=刘德华, phone=177, age=62)]
        log.info("年龄大于50的用户为 " + filterUserList);
    }
场景三:知道一个List<User>对象,如何按照年龄从小到小排序,从大到小排序?
public static void main(String[] args) {
        // 知道一个List<User>对象,如何按照年龄从大到小排序?
        List<User> userList = getUserList();
        List<User> ascUserList = userList.stream().sorted(Comparator.comparing(User::getAge)).collect(Collectors.toList());
        List<User> reversedUserList = userList.stream().sorted(Comparator.comparing(User::getAge).reversed()).collect(Collectors.toList());
        // 打印内容 - 年龄从小到大 [JAVA8.User(name=周传雄, phone=133, age=40), JAVA8.User(name=周星驰, phone=155, age=42), JAVA8.User(name=伍佰, phone=188, age=45), JAVA8.User(name=甄子丹, phone=199, age=45), JAVA8.User(name=周润发, phone=166, age=52), JAVA8.User(name=刘德华, phone=177, age=62)]
        log.info("年龄从小到大 " + ascUserList);
        // 打印内容 - 年龄从大到小 [JAVA8.User(name=刘德华, phone=177, age=62), JAVA8.User(name=周润发, phone=166, age=52), JAVA8.User(name=伍佰, phone=188, age=45), JAVA8.User(name=甄子丹, phone=199, age=45), JAVA8.User(name=周星驰, phone=155, age=42), JAVA8.User(name=周传雄, phone=133, age=40)]
        log.info("年龄从大到小 " + reversedUserList);
    }
场景四:知道一个List<User>对象,如何按照相同年龄进行分组,并获取分组后的数量?
public static void main(String[] args) {
        // 知道一个List<User>对象,如何按照相同年龄进行分组?
        List<User> userList = getUserList();
        Map<Integer, List<User>> groupingUserList = userList.stream().collect(Collectors.groupingBy(User::getAge));
        // 打印内容 - 相同年龄进行分组 {52=[JAVA8.User(name=周润发, phone=166, age=52)], 40=[JAVA8.User(name=周传雄, phone=133, age=40)], 42=[JAVA8.User(name=周星驰, phone=155, age=42)], 45=[JAVA8.User(name=伍佰, phone=188, age=45), JAVA8.User(name=甄子丹, phone=199, age=45)], 62=[JAVA8.User(name=刘德华, phone=177, age=62)]}
        log.info("相同年龄进行分组 " + groupingUserList);
        // 知道一个List<User>对象,如何按照相同年龄进行分组后获取其对应数量?
        Map<Integer, Long> countUserList = userList.stream().collect(Collectors.groupingBy(User::getAge, Collectors.counting()));
        // 打印内容 - 相同年龄进行分组的数量 {52=1, 40=1, 42=1, 45=2, 62=1}
        log.info("相同年龄进行分组的数量 " + countUserList);
    }
1.2 进阶
场景一:有一张用户浏览记录表,一个用户可以有多条浏览记录,且有不同的浏览类型;比如小明浏览娱乐模块530秒,浏览军事模块600秒,则对应两个浏览记录数据。新建用户浏览类型统计表,根据现有的用户浏览记录表数据对用户浏览类型统计表进行新增,请用Stream优雅的实现该功能?
package com.weige.javaskillpoint.controller;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class JAVA8 {

    @Data
    static class History {
        // 用户id
        private Long userId;
        // 用户浏览类型 (1->娱乐 2->军事 3->教育)
        private Integer type;
        // 用户浏览时间(单位秒)
        private Long seconds;

        public History(Long userId, Integer type, Long seconds) {
            this.userId = userId;
            this.type = type;
            this.seconds = seconds;
        }
    }

    @Data
    static class HistoryStatistics {
        // 用户id
        private Long userId;
        // 用户浏览类型 (1->娱乐 2->军事 3->教育)
        private Integer type;
        // 浏览类型统计数量
        private Long count;

        public HistoryStatistics(Long userId, Integer type, Long count) {
            this.userId = userId;
            this.type = type;
            this.count = count;
        }
    }

    public static void main(String[] args) {
        // 模拟用户浏览记录数据
        List<History> historyList = new ArrayList<History>() {
            {
                add(new History(20231L, 1, 360L));
                add(new History(20231L, 1, 720L));
                add(new History(20231L, 2, 1360L));
                add(new History(20231L, 2, 2360L));
                add(new History(20239L, 2, 2360L));
                add(new History(20239L, 3, 360L));
                add(new History(20233L, 3, 360L));
            }
        };

        List<HistoryStatistics> insertHistoryStatisticsList = new ArrayList<>();

        // 根据用户id进行分组
        Map<Long, List<History>> groupingByUserIdMap = historyList.stream().collect(Collectors.groupingBy(History::getUserId));

        groupingByUserIdMap.forEach((key, value) -> {
            Map<Integer, Long> countMap = historyList.stream()
                    // 筛选出对应用户id的浏览记录
                    .filter(h -> key.equals(h.getUserId()))
                    // 对用户id的浏览记录根据类型进行分组并获取数量
                    .collect(Collectors.groupingBy(History::getType, Collectors.counting()));

            // 将用户浏览记录类型分组的数量Map转成List<HistoryStatistics>
            List<HistoryStatistics> historyStatisticsList = countMap.entrySet().stream().map(u -> new HistoryStatistics(key, u.getKey(), u.getValue())).collect(Collectors.toList());
            insertHistoryStatisticsList.addAll(historyStatisticsList);
        });

        // 批量新增用户浏览记录统计表
        batchInsertHistoryStatistics(insertHistoryStatisticsList);
    }

    public static void batchInsertHistoryStatistics(List<HistoryStatistics> insertHistoryStatisticsList) {
        log.info("------连接数据库------");
        log.info("------开始批量新增数据------");
        log.info("------批量新增数据: " + insertHistoryStatisticsList);
        log.info("------批量新增数据结束------");
        log.info("------关闭数据库连接------");
    }
}
场景二:有一张用户浏览记录表,一个用户可以有多条浏览记录,且有不同的浏览类型;比如小明浏览娱乐模块530秒,浏览军事模块600秒;小红浏览娱乐模块1000秒,浏览军事模块100秒,则对应四条浏览记录数据。想要得到每个用户总共的浏览时长,请用Stream优雅的实现该功能?
package com.weige.javaskillpoint.controller;

import lombok.Data;
import lombok.extern.slf4j.Slf4j;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

@Slf4j
public class JAVA8 {

    @Data
    static class History {
        // 用户姓名
        private String userName;
        // 用户浏览类型 (1->娱乐 2->军事 3->教育)
        private Integer type;
        // 用户浏览时间(单位秒)
        private Long seconds;

        public History(String userName, Integer type, Long seconds) {
            this.userName = userName;
            this.type = type;
            this.seconds = seconds;
        }
    }

    public static void main(String[] args) {
        List<History> historyList = new ArrayList<History>() {
            {
                add(new History("小明", 1, 360L));
                add(new History("小明", 1, 720L));
                add(new History("小明", 2, 1360L));
                add(new History("小明", 2, 2360L));
                add(new History("小红", 2, 2360L));
                add(new History("小白", 3, 360L));
                add(new History("小红", 3, 360L));
                add(new History("小白", 3, 1060L));
            }
        };

        // 串行流中reduce的第三个参数combiner无作用 返回值可以写为null
        HashMap<String, Long> reduce = historyList.stream().reduce(new HashMap<>(), (m, e) -> {
            m.put(e.getUserName(), m.getOrDefault(e.getUserName(), 0L) + e.getSeconds());
            return m;
        }, (m1,m2) -> null);
        // 返回结果 - {小明=4800, 小白=1420, 小红=2720}
        log.info("数据为: " + reduce);

        // 并行流中reduce的第三个参数combiner有作用 如果返回结果为map 则应用putAll()来解决并发情况下数据不一致问题 同时返回值应用ConcurrentHashMap接收
        ConcurrentHashMap<String, Long> parallelReduce = historyList.stream().parallel().reduce(new ConcurrentHashMap<>(), (m, e) -> {
            m.put(e.getUserName(), m.getOrDefault(e.getUserName(), 0L) + e.getSeconds());
            return m;
        }, (m1,m2) -> {
            m1.putAll(m2);
            return m1;
        });
        // 返回结果 - {小明=4800, 小白=1420, 小红=2720}
        log.info("数据为: " + parallelReduce);


        // 这里举个例子:如果reduce第一个参数为1,则stream执行时,分两个阶段;
        // 第一个阶段分3步:1 + 1 = 2,1 + 2 = 3,1 + 3 = 4;
        // 第二个阶段 2 * 3 * 4 = 24
        List<Integer> intList = new ArrayList<Integer>(){{
            add(1);
            add(2);
            add(3);
        }};
        Integer sum = intList.stream().parallel().reduce(1, new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer integer, Integer integer2) {
                return integer + integer2;
            }
        }, (integer, integer2) -> integer * integer2);
        // 返回结果 - 并行流中用第三个参数(类似于函数表达式对参数进行乘法操作): 24
        log.info("并行流中用第三个参数(类似于函数表达式对参数进行乘法操作): " + sum);

        Integer multipliers = intList.stream().parallel().reduce(1, new BinaryOperator<Integer>() {
            @Override
            public Integer apply(Integer integer, Integer integer2) {
                return integer + integer2;
            }
        });
        // 返回结果 - 并行流中第三个参数返回自己本身,不进行任何操作: 9
        log.info("并行流中第三个参数返回自己本身,不进行任何操作: " + multipliers);

        Integer num = intList.stream().reduce(1,Integer::sum);
        // 返回结果 - 串行流不使用第三个参数 7
        log.info("串行流不使用第三个参数 " + num);
    }
    
}

二. LocalDate,LocalDateTime

2.1 基础
一般前端传给后端的时间参数,都是字符串拼接,比如"2023-07-19","2023 -07-19 20:00:00",这都是字符串;而查询数据库时,是需要根据Date时间类型来查询,所以这里需要将字符串转成Date,如果中间需要操作时间(年,月,日,时,分加减)
LocalDate
    public static void main(String[] args) {
        // 模拟前端传过来的时间参数
        String dateString = "2023-07-19";

        // 将字符串转成LocalDateTime  这里看前端传的时间格式 ofPattern里面对应时间格式 不然会报错
        // 2023-07-19 -> yyyy-MM-dd
        // LocalDate只能操作年 月 日
        LocalDate localDate = LocalDate.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd"));
        // 减1年
        LocalDate minusYears = localDate.minusYears(1);
        // 加1年
        LocalDate plusYears = localDate.plusYears(1);
        // 减1月
        LocalDate minusMonths = localDate.minusMonths(1);
        // 加1月
        LocalDate plusMonths = localDate.plusMonths(1);
        // 减1日
        LocalDate minusDays = localDate.minusDays(1);
        // 加1日
        LocalDate plusDays = localDate.plusDays(1);
        // 通过LocalDate操作时间参数得到自己想要的结果时 转换成Date类型查询数据库
        // LocalDate转Date
        Date date = localDateTurnDate(minusYears);
        getListByDate(date);
        System.out.println(date);

    }

    public static Date localDateTurnDate(LocalDate localDate) {
        ZoneId zone = ZoneId.systemDefault();
        Instant instant = localDate.atStartOfDay().atZone(zone).toInstant();
        return Date.from(instant);
    }

    public static void getListByDate(Date date) {
        // 模拟查询结果
        ArrayList<String> arrayList = new ArrayList<String>() {{
            add("一辈子");
            add("下辈子");
        }};
        System.out.println("根据时间" + date + "查询结果为 : " + arrayList);
    }
LocalDateTime
    public static void main(String[] args) {
        // 模拟前端传过来的时间参数
        String dateString = "2023-07-19 20:20:20";

        // 将字符串转成LocalDateTime  这里看前端传的时间格式 ofPattern里面对应时间格式 不然会报错
        // 2023-07-19 20:20:20 -> yyyy-MM-dd HH:mm:ss
        // 2023-07-19 20:20 -> yyyy-MM-dd HH:mm
        // 2023-07-19 -> yyyy-MM-dd
        LocalDateTime localDateTime = LocalDateTime.parse(dateString, DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"));
        // 减1年
        LocalDateTime minusYears = localDateTime.minusYears(1);
        // 加1年
        LocalDateTime plusYears = localDateTime.plusYears(1);
        // 减1月
        LocalDateTime minusMonths = localDateTime.minusMonths(1);
        // 加1月
        LocalDateTime plusMonths = localDateTime.plusMonths(1);
        // 减1日
        LocalDateTime minusDays = localDateTime.minusDays(1);
        // 加1日
        LocalDateTime plusDays = localDateTime.plusDays(1);
        // 减1小时
        LocalDateTime minusHours = localDateTime.minusHours(1);
        // 加1小时
        LocalDateTime plusHours = localDateTime.plusHours(1);
        // 通过LocalDateTime操作时间参数得到自己想要的结果时 转换成Date类型查询数据库
        // LocalDateTime转Date
        Date date = localDateTimeTurnDate(minusYears);
        getListByDate(date);
        System.out.println(date);

    }

    public static Date localDateTimeTurnDate(LocalDateTime localDateTime) {
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }

    public static void getListByDate(Date date) {
        // 模拟查询结果
        ArrayList<String> arrayList = new ArrayList<String>() {{
            add("一辈子");
            add("下辈子");
        }};
        System.out.println("根据时间" + date + "查询结果为 : " + arrayList);
    }
2.2 进阶
对时间参数进行比较
通过当前时间,查询前6个小时数据库的数据
    public static void main(String[] args) {
        // 近6个小时
        String format = DateUtils.format(new Date(), "yyyy-MM-dd HH");
        LocalDateTime now = LocalDateTime.parse(format, DateTimeFormatter.ofPattern("yyyy-MM-dd HH"));
        for (LocalDateTime currentdate = now.minusHours(5); currentdate.isBefore(now) || currentdate.isEqual(now); currentdate = currentdate.plusHours(1)) {
            Date date = localDateTimeTurnDate(currentdate);
            getListByDate(date);
        }
    }

    public static Date localDateTimeTurnDate(LocalDateTime localDateTime) {
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }
    
    public static void getListByDate(Date date) {
        // 模拟查询结果
        ArrayList<String> arrayList = new ArrayList<String>() {{
            add("一辈子");
            add("下辈子");
        }};
        System.out.println("根据时间" + date + "查询结果为 : " + arrayList);
    }
通过当前时间,查询近7天数据库的数据
    public static void main(String[] args) {
        // 近7天
        String format = DateUtils.format(new Date(), "yyyy-MM-dd");
        LocalDateTime now = LocalDate.parse(format, DateTimeFormatter.ofPattern("yyyy-MM-dd")).atStartOfDay();
        for (LocalDateTime currentdate = now.minusDays(6); currentdate.isBefore(now) || currentdate.isEqual(now); currentdate = currentdate.plusDays(1)) {
            Date date = localDateTimeTurnDate(currentdate);
            getListByDate(date);
        }
    }

    public static Date localDateTimeTurnDate(LocalDateTime localDateTime) {
        Instant instant = localDateTime.atZone(ZoneId.systemDefault()).toInstant();
        return Date.from(instant);
    }


    public static void getListByDate(Date date) {
        // 模拟查询结果
        ArrayList<String> arrayList = new ArrayList<String>() {{
            add("一辈子");
            add("下辈子");
        }};
        System.out.println("根据时间" + date + "查询结果为 : " + arrayList);
    }

文章来源地址https://www.toymoban.com/news/detail-585942.html

到了这里,关于JAVA8新特性(Stream API,LocalDate,LocalDateTime)的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包赞助服务器费用

相关文章

  • 带你走进Java8新特性Stream流的小世界

    带你走进Java8新特性Stream流的小世界

    目录 一. 什么是流(Stream) 1.1 流的定义 1.2 流的特点 1.3 操作流 1.4 创建流 二. 流的中间操作 2.1 流的筛选与切片 2.1.1 filter 2.1.2 limit 2.1.3 skip 2.1.4 distinct 2.2 流的映射 2.2.1 map 2.2.2 flatMap 2.3 流的排序 2.3.1 sort 三. 流的终止操作 3.1 流的查找与匹配 3.1.1 allMatch 3.1.2 anyMatch 3.1.3 none

    2024年01月24日
    浏览(20)
  • java8新特性Stream流中anyMatch和allMatch和noneMatch的使用!!!

    判断数据列表中是否存在任意一个元素符合设置的predicate条件,如果是就返回true,否则返回false。 接口定义: boolean anyMatch(Predicate? super T predicate); 方法描述: 在anyMatch 接口定义中是接收 Predicate 类型参数,在Lamdba表达式中 PredicateT 是接收一个T类型参数,然后经过逻辑验证返

    2024年02月08日
    浏览(15)
  • JAVA8新特性stream流收集为Map,value为null导致空指针的问题

    JAVA8新特性stream流收集为Map,value为null导致空指针的问题

    jdk8 新特性stream深受喜爱,平时使用比较多,其中有: MapString, String collect2 =  list.stream().collect(Collectors.toMap(Book::getName, Book::getIdNO,(pre, after) - pre));  现象如下: 问题:JDK8环境下,如果Book::getIdNo 为null的话会报空指针,即JDK8环境下的,该接口不支持value为null(key为null没这个问

    2024年02月06日
    浏览(46)
  • 使用java8 新特性stream流对List<Map<String, Object>>集合进行遍历、过滤、查询、去重、排序、分组

    对于一个ListMapString, Object类型的数据,可以使用Java 8的新特性stream流来进行遍历、过滤、查询、去重、排序、分组等操作。 遍历: 过滤: 查询: 去重: 排序: 分组:

    2024年02月10日
    浏览(55)
  • Java中LocalDate、LocalTime、LocalDateTime时间类介绍

    Java中LocalDate、LocalTime、LocalDateTime时间类介绍

    目录         一、三者的介绍         二、实例化 1、普通实例化  2、实例化并设置日期:  3、利用格式化工具实例化并将日期字符串设置为日期         三、常用方法介绍 1、获取星期几 2、获取月份 3、对年月日时分秒进行加减 4、计算两个日期之间的天数 5、

    2024年02月08日
    浏览(14)
  • Java String、Date、Calendar、LocalDate和LocalDateTime互转

    目录 一、String和Date互转 1.1 String时间转为Date 1.2 Date转为String 二、String和Calendar互转 2.1 String时间转为Calendar 2.2 Calendar转为String 三、String和LocalDate(LocalDateTime)互转 3.1 String时间转为LocalDate(LocalDateTime) 3.2 LocalDate(LocalDateTime)转为String 四、Date和Calendar互转 4.1 Date转为Calen

    2024年02月06日
    浏览(18)
  • Java8的Stream流的学习

    Stream可以由数组或集合创建,对流的操作分为两种: 中间操作,每次返回一个新的流,可以有多个。 终端操作,每个流只能进行一次终端操作,终端操作结束后流无法再次使用。终端操作会产生一个新的集合或值。 stream和parallelStream的简单区分: stream是顺序流,由主线程按

    2024年02月07日
    浏览(14)
  • Data与Java8中的LocalDate相互转换

    Data与Java8中的LocalDate相互转换

    一、前言 Date这个类在 java.util包 中,始于jdk1.0。后来在jdk1.8时,针对日期类进行了一个大的更新,专门新建了 java.time包 ,新的日期类LocalDateTime就在这个包中。 日常工作中,很容易碰到旧日期类Date,与新日期类LocalDateTime的相互转换。下面就介绍一下如何进行转换 二、思路

    2024年02月16日
    浏览(9)
  • Java8新特性lambda学习

    Lambda是一个 匿名函数 ,我们可以把Lambda表达式理解为是一段可以传递的代码(将代码像数据一样进行传递)。使用它可以写出更简洁、更灵活的代码。作为一种更紧凑的代码风格,使Java的语言表达能力得到了提升。 本质: 作为 函数式接口 的实例, 没有接口就没意义了. 这两

    2024年02月05日
    浏览(9)
  • Java8日期时间类LocalDateTime格式化

    Java8日期时间类LocalDateTime格式化

    LocalDateTime日期时间格式化 LocalDateTime localDateTime = LocalDateTime.now() System.out.println(now.format( DateTimeFormatter.ofPattern(\\\"yyyy-MM-dd HH:mm:ss\\\") )); 测试1 测试2 测试2的结果

    2024年02月08日
    浏览(12)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包