龙空技术网

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

爱摸鱼的程序员 177

前言:

现时看官们对“java后端接收list对象参数”大概比较着重,小伙伴们都需要学习一些“java后端接收list对象参数”的相关资讯。那么小编在网络上收集了一些对于“java后端接收list对象参数””的相关资讯,希望我们能喜欢,你们快快来学习一下吧!

一. Stream API1.1 基础代码参数准备:

java复制代码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;@Slf4jpublic 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对象,如何获取List的所有用户id?
scss复制代码    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对象,如何获取List中年龄大于50的用户?
scss复制代码    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对象,如何按照年龄从小到小排序,从大到小排序?
scss复制代码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对象,如何按照相同年龄进行分组,并获取分组后的数量?
ini复制代码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优雅的实现该功能?
java复制代码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;@Slf4jpublic 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优雅的实现该功能?
java复制代码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;@Slf4jpublic 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,LocalDateTime2.1 基础一般前端传给后端的时间参数,都是字符串拼接,比如"2023-07-19","2023 -07-19 20:00:00",这都是字符串;而查询数据库时,是需要根据Date时间类型来查询,所以这里需要将字符串转成Date,如果中间需要操作时间(年,月,日,时,分加减)LocalDate
ini复制代码    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
ini复制代码    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个小时数据库的数据
typescript复制代码    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天数据库的数据
typescript复制代码    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);    }

标签: #java后端接收list对象参数