SpringBoot(五)(springboot五大组件和作用)

  本篇文章为你整理了SpringBoot(五)(springboot五大组件和作用)的详细内容,包含有springboot五大中间件原理 springboot五大组件和作用 springboot五层架构 springboot五大中间件 SpringBoot(五),希望能帮助你了解 SpringBoot(五)。

  1、Lambda表达式

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

  1.1 语法组成

  操作符为" - " ,被称为 Lambda 操作符或箭头操作符;

  将 Lambda 分为两个部分:

  左侧:指定了 Lambda 表达式需要的参数列表;

  右侧:指定了 Lambda 体,是抽象方法的实现逻辑,也即Lambda 表达式要执行的功能。

  
// 使用lambda表达式,创建一个线程

   Runnable runnable2 = () - log.info("------ 使用lambda表达式,创建一个线程 ------");

   // 启动线程2

   new Thread(runnable2).start();

   public static void main(String[] args) {

   //测试 未使用和使用lambda表达式,对比

   testRunLambdaContrast();

  

 

 

  总结:未使用和使用Lambda表达式都可以实现抽象方法,但是使用Lambda方法后会更加简洁;

  1.2.2 带一个参数没有返回值

  1.2.2.1 带一个参数没有返回值 标准写法

  

// 借助java8中 消费型函数式接口,讲解基本用法

 

  // 不使用lambda表达式实现

  Consumer String consumer1 = new Consumer String () {

   @Override

   public void accept(String s) {

   log.info("------ 不使用lambda表达式,实现Consumer1接口,消费数据:{} ------",s);

  // 使用消费型接口1

  consumer1.accept("kh96正在学习lambda表达式,标准写法");

  // 使用lambda表达式,用法:带 1 个参数,没有返回值,标准写法

  Consumer String consumer2 = (String s) - {

   log.info("------ 使用lambda表达式,实现Consumer2接口,消费数据:{} ------",s);

  // 使用消费型接口2

  consumer2.accept("kh96正在学习lambda表达式,标准写法");

  

 

  1.2.2.2 简化写法:一个参数,可以省略类型声明

  

//一个参数,可以省略类型声明

 

  Consumer String consumer3 = (s) - {

   log.info("------ 使用lambda表达式,实现Consumer3接口,消费数据:{} ------",s);

  consumer3.accept("kh96正在学习lambda表达式,一个参数,可以省略类型声明");

  

 

  1.2.2.3 简化写法:一个参数,可以省略小括号(没有参数,多个参数不能省略)

  

//一个参数,可以省略小括号(没有参数,多个参数不能省略)

 

  Consumer String consumer4 = s - {

   log.info("------ 使用lambda表达式,实现Consumer4接口,消费数据:{} ------",s);

  consumer4.accept("kh96正在学习lambda表达式,一个参数,可以省略小括号");

  

 

  1.2.2.4 简化写法:实现只有一条语句,可以省略大括号(有多条语句,不可以省略)

  

//实现只有一条语句,可以省略大括号(有多条语句,不可以省略)

 

  Consumer String consumer5 = s - log.info("------ 使用lambda表达式,实现Consumer3接口,消费数据:{} ------",s);

  consumer5.accept("kh96正在学习lambda表达式,实现只有一条语句,可以省略大括号");

  

 

  1.2.2.5 简化写法:实现有多条语句,不可以省略大括号

  

//实现有多条语句,不可以省略大括号

 

  Consumer String consumer6 = s - {

   log.info("------ 使用lambda表达式,实现Consumer3接口,消费数据:{} ------",s);

   log.info("------ 使用lambda表达式,实现Consumer3接口,消费数据:{} ------",s);

  consumer6.accept("kh96正在学习lambda表达式,实现有多条语句,不可以省略大括号");

  

 

  1.2.3 带多个参数,有返回值

  1.2.3.1 未使用 lambda 表达式,用法:带多个参数,有返回值

  

// 借助Comparator接口,讲解多个参数

 

  Comparator Integer comparator1 = new Comparator Integer () {

   @Override

   public int compare(Integer o1, Integer o2) {

   return o1.compareTo(o2);

  // 未使用lambda表达式,用法:带多个参数,有返回值

  log.info("------ 不使用lambda表达式,实现Comparator接口,比较12,23的大小:{} ------",comparator1.compare(12,23));// 小于 -1,大于 1,等于 0

  

 

  1.2.3.2 简化写法:省略参数类型,但是不可以省略小括号,一条语句省略大括号,跟返回值无关(不用手动加return)

  

//省略参数类型,但是不可以省略小括号,一条语句省略大括号,跟返回值无关(不用手动加return)

 

  Comparator Integer comparator2 = (o1,o2) - o1.compareTo(o2);

  log.info("------ 使用lambda表达式,实现Comparator接口,比较23,12的大小:{} ------",comparator2.compare(23,12));// 大于 1

  

 

  1.2.3.3 简化写法:多条语句不可以省略大括号,带返回值(需手动加return)

  

//多条语句不可以省略大括号,带返回值(需手动加return)

 

  Comparator Integer comparator3 = (o1,o2) - {

   log.info("------ 比较原数值为:{},{}",o1,o2);

   return o1.compareTo(o2);

  log.info("------ 使用lambda表达式,实现Comparator接口,比较22,22的大小:{} ------",comparator3.compare(22,22));// 等于 0

  

 

  1.3 java8中提供的函数式接口

  1.3.1 消费型接口 Consumer (方法有一个参数,没有返回值)

  1.3.1.1 自定义方法 (使用接口的 void accept(T t) )

  

//自定义方法,带有一个消费型接口参数,可以实现一个方法,处理不同的业务场景

 

  static void useConsumer(Double salary,Consumer Double consumerDate){

   consumerDate.accept(salary);

  

 

  1.3.1.2 方法调用

  

static void testLambdaConsumer(){

 

   //场景,同一个接口,有多个实现,以前,必须要创建接口的多个实现类,现在使用lambda,把接口的实现交给调用方法传递

   //实现1:Tom发了5000工资,去买手机,模拟接口的第一个实现

   //以前,必须提供接口的实现类对象

   useConsumer(5000.0,salary - log.info("Tom,工资:{},5000买手机",salary));

   //实现1:Tom发了10000工资,去买手机,买平板,模拟接口的第二个实现

   //以前,必须提供接口的 两个 实现类对象

   useConsumer(10000.0,slary - {

   log.info("JiMe工资:{},5000买手机",slary);

   log.info("JiMe工资:{},4000买平板",slary);

  

 

  1.3.1.3 测试结果

  1.3.2 供给型接口 Supplier(方法没有参数,可以返回任意类型的结果)

  1.3.2.1 自定义方法 (使用接口的 T get() )

  

//带一个供给型参数,可以实现同一个方法,处理实现同一个方法,处理不同的业务场景,给的数据不同,返回的结果不同

 

  static String useSupplier(Double salary, Supplier Double supplierData){

   //判断是否高薪的逻辑

   if(salary supplierData.get()){

   return "高薪";

   return "底薪";

  

 

  1.3.2.2 方法调用

  

static void testLambdaSupplier(){

 

   //场景:不同的部门,针对高薪的判断条件不同,比如:学术部高于8000算高薪,教职部门高于5000算高薪

   //以前的写法:根据不同的不同,增加if...else 判断,随着部门的增加,你分的判断会越来越复杂

   log.info("--- 学术部:工资:{},是否高薪:{} ---",9000.0,useSupplier(9000.0,() - 8000.0));

   log.info("--- 学术部:工资:{},是否高薪:{} ---",7000.0,useSupplier(7000.0,() - 8000.0));

   log.info("--- 教职部:工资:{},是否高薪:{} ---",7000.0,useSupplier(7000.0,() - 5000.0));

   log.info("--- 教职部:工资:{},是否高薪:{} ---",4000.0,useSupplier(7000.0,() - 5000.0));

  

 

  1.3.2.3 测试结果

  1.3.3 断言型接口 Predicate(方法有一个参数,有返回值-布尔类型)

  1.3.3.1 自定义方法 (使用接口的 boolean test(T t) )

  

//将判断条件交给调用方法

 

  static List String userPredicate(List String nameList, Predicate String predicateData){

   //定义要返回的姓名集合

   List String returnNameList = new ArrayList();

   //使用断言型接口,根据传过来的实现,返回不同的结果

   nameList.forEach(name - {

   //调用断言型接口的test方法,进行挑选数据

   if(predicateData.test(name)){

   returnNameList.add(name);

   //返回符合条件的集合数据

   return returnNameList;

  

 

  1.3.3.2 方法调用

  

static void testLambdaPredicate(){

 

   //使用场景

   //已知姓名集合,根据不同的场景,筛选不同的姓名结果

   List String nameList = Arrays.asList("Lilei","Hanmeinei","lisi","zhangsan","xiaolong","xiaohu");

   //获取姓名集合中所有包含n的姓名集合,可以定义第一个方法,实现

   //获取集合中包含i 或者a的姓名集合,可以定义第二个方法,实现

   //随着规则的改变,实现的方法越来越多,去简化,所有的方法就是判断规则不同,其他都一样,可以使用断言型接口,优化

   //获取姓名集合中所有包含n的姓名集合

   List String nameList_n = userPredicate(nameList,name - name.contains("n"));

   log.info("姓名集合中所有包含n的姓名集合:{}",nameList_n);

   //获取集合中包含i 或者a的姓名集合

   List String nameList_i_a = userPredicate(nameList,name - name.contains("i") name.contains("a"));

   log.info("获取集合中包含i 或者a的姓名集合:{}",nameList_i_a);

  

 

  1.3.3.3 测试结果

  1.3.4 函数接口 Function,有任意类型参数,有任意类型返回值

  1.3.4.1 自定义方法(使用接口的R apply(T t) ) 和 方法调用

  

static void testLambdaFunction(){

 

   Function Integer,Double function = num - new Random().nextInt(num)*1.0;

   log.info("--- 使用函数型接口,接收整数:{},返回随机浮点型结果:{} ---",96,function.apply(96));

  

 

  1.3.4.2 测试结果

  1.3.5 自定义函数式接口

  

// 自定义的函数式接口:带一个任意类型参数,返回String类型值

 

  // 定义:凡是一个接口中,只有一个抽象方法,那这个接口就是函数式接口,可以别注解 //@FunctionalInterface修饰

  @FunctionalInterface

  public interface MyFunctionInterface T {

   //函数式接口中的唯一抽象方法

   String helloKh96(T t);

   //可以增加默认方法,允许的

   default void hiKH96(){

   //默认方法

  

 

  2、StreamAPI

  2.1 创建流 有限流 和 无限流

  2.1.1 有限流

  

//有限流, 输出1,3,5,7,9 的平方

 

  log.info("\n----- 输出1,3,5,7,9 的平方 -----");

  Stream.of(1,3,5,7,9).forEach(num - System.out.print(num * num + ";"));

  

 

  测试结果:

  2.1.2 无线流

  2.1.2.1 iterate

  

//无限流:输出前18个奇数

 

  log.info("\n ----- 输出前18个奇数 ------");

  Stream.iterate(1,n - n+2).limit(10).forEach(num - System.out.print(num + ";"));

  

 

  2.1.2.2 generate

  

//无限流:输出10个随机数

 

  log.info("\n ----- 输出前18个随机数 ------");

  Stream.generate(() - new Random().nextInt(100)).limit(10).forEach(num - System.out.print(num+";"));

  

 

  测试结果:

  2.2 创建流 基于数组 和 集合

  2.2.1 基于数组

  

//基于数组

 

  int[] nums = {66,99,44,11,22,55,77,88};

  //通过Arrays工具类提供的stream 方法

  int min = Arrays.stream(nums).min().getAsInt();

  int max = Arrays.stream(nums).max().getAsInt();

  log.info("\n ------ 数组最小值为 :{} --------",min);

  log.info("\n ------ 数组最大值为 :{} --------",max);

  

 

  测试结果:

  2.2.2 基于集合

  

//基于集合

 

  List String nameList = Arrays.asList("Lilei","Hanmeinei","lisi","zhangsan","xiaolong","xiaohu");

  //通过集合对象的stream方法

  nameList.stream().map(name - name.toLowerCase()).forEach(System.out::println);

  

 

  测试结果:

  2.3 流的中间操作

  2.3.1 筛选和切片

  2.3.1.0 数据准备

  2.3.1.0.1 bean

  

//小说实体

 

  @Data

  @Builder

  @NoArgsConstructor

  @AllArgsConstructor

  public class Story {

   // 编号

   private Integer id;

   // 书名

   private String name;

   // 作者

   private String author;

   // 价格

   private Double price;

   // 章节

   private Integer sections;

   // 分类

   private String category;

  

 

  2.3.1.0.2 StoryUtil

  

//小说工具类

 

  public class StoryUtil {

   public static List Story stories = new ArrayList ();

   static {

   stories.add(Story.builder().id(101).name("斗破苍穹").author("zhangsan").price(109.9).sections(1202).category("玄幻").build());

   stories.add(Story.builder().id(201).name("斗罗大陆").author("lisi").price(88.9).sections(999).category("科幻").build());

   stories.add(Story.builder().id(301).name("凡人修仙传").author("wangwu").price(77.9).sections(1303).category("武侠").build());

   stories.add(Story.builder().id(401).name("圣墟").author("zhuliu").price(121.9).sections(1404).category("玄幻").build());

   stories.add(Story.builder().id(501).name("吞噬星空").author("sunqi").price(135.9).sections(996).category("历史").build());

   stories.add(Story.builder().id(601).name("完美世界").author("zhaoba").price(66.9).sections(999).category("玄幻").build());

   stories.add(Story.builder().id(701).name("大王饶命").author("qianjiu").price(135.9).sections(997).category("玄幻").build());

   stories.add(Story.builder().id(801).name("大奉打更人").author("zhoushi").price(133.9).sections(1606).category("军事").build());

  

 

  2.3.1.1 筛选:filter

  

//筛选: filter,相当于数据库中的where条件

 

  log.info("-------------- 筛选: filter ----------------");

  //查看小说集合中,价格大于100块的所有小说

  StoryUtil.stories.stream().filter(story - story.getPrice() 100).forEach(System.out::println);

  //练习:查看小说集合中,所有章节数大于1000且作者中包含n的小说

  log.info("\n------- 查看小说集合中,所有章节数大于1000且作者中包含n的小说 ---------");

  StoryUtil.stories.stream().filter(story - story.getSections() 1000 story.getAuthor().contains("n") ).forEach(System.out::println);

  

 

  测试结果1:

  测试结果2:

  2.3.1.2 截断:limit

  

//截断: limit 相当于数据库的limit条数

 

  log.info("\n---------- 截断: limit ---------");

  //查询小说集合,所有价格大于100的前三本

  StoryUtil.stories.stream().filter(story - story.getPrice() 100).limit(3).forEach(System.out::println);

  

 

  测试结果:

  2.3.1.3 跳过:skip

  

//跳过:skip,相当于数据库跳过数据条数

 

  log.info("\n------------- 跳过:skip-----------------");

  //查询小说集合,所有价格大于100的前三本,后的所有小说

  log.info("\n------------- 查询小说集合,所有价格大于100的前三本,后的所有小说-----------------");

  StoryUtil.stories.stream().filter(story - story.getPrice() 100).skip(3).forEach(System.out::println);

  

 

  测试结果:

  2.3.1.4 去重:distinct

  

//去重:distinct,相当于数据库中的去重,了解

 

  log.info("\n------------- 去重:distinct,相当于数据库中的去重 -----------------");

  Stream.of(22,33,55,11,66,33,55,11,55).distinct().forEach(System.out::println);

  

 

  测试结果:

  2.3.2 映射和排序

  2.3.2.1 映射:map

  

 //已知姓名集合

 

  List String nameList = Arrays.asList("Lilei","Hanmeinei","lisi","zhangsan","xiaolong","xiaohu");

  //映射:map,可以将流中发的元素进行转换或这提取,会自动指定的规则作用到所有的元素上,并返回一个新的流

  log.info("-------------- 映射: map ----------------");

  //将姓名集合中,所有包含i的姓名,转换为大写并输出

  //nameList.stream().filter(name - name.contains("i")).map(name - name.toUpperCase()).forEach(System.out::println);

  nameList.stream().filter(name - name.contains("i")).map(String::toUpperCase).forEach(System.out::println);

  

 

  测试结果:

  2.3.2.2 映射:map 输出单个属性

  

 //将小说集合中,章节小于1000的作者转换为大写,输出作者

 

  log.info("\n-------------- 将小说集合中,章节小于1000的作者转换为大写,输出作者 --------------");

  //StoryUtil.stories.stream().filter(story - story.getSections() 1000).map(story - story.getAuthor()).map(string - string.toUpperCase()).forEach(System.out::println);

  StoryUtil.stories.stream().filter(story - story.getSections() 1000).map(Story::getAuthor).map(string - string.toUpperCase()).forEach(System.out::println);

  

 

  测试结果:

  2.3.2.3 映射: mapToInt

  

//获取所有小说的书名长度

 

  log.info("\n-------------- 获取所有小说的书名长度 --------------");

  // StoryUtil.stories.stream().map(story - story.getName().length()).forEach(System.out::println);

  StoryUtil.stories.stream().mapToInt(story - story.getName().length()).forEach(System.out::println);

  

 

  测试结果:
 

  2.3.2.4 消费:peek

  

//消费:peek, 将小说价格增加50元后,价格大于130的

 

  log.info("\n-------------- 消费:peek, 将小说价格增加50元后,价格大于130的 --------------");

  StoryUtil.stories.stream().peek(story - story.setPrice(story.getPrice()+50)).filter(story - story.getPrice() 130).forEach(System.out::println);

  

 

  测试结果:

  2.3.2.5 排序:sorted

  

 //排序:sorted ,给姓名排序

 

  log.info("\n -------------- 排序:sorted ,给姓名排序 --------------");

  nameList.stream().sorted().forEach(System.out::println);

  

 

  2.3.2.6 自定义排序规则

  

//自定义排序,先按照价格排序,价格相同,按照章节排序

 

  log.info("\n--------- 自定义排序,先按照价格排序,价格相同,按照章节排序 ---------");

  StoryUtil.stories.stream().sorted((s1,s2)- {

   int sortPrice = Double.compare(s1.getPrice(),s2.getPrice());

   if(sortPrice == 0){

   return Double.compare(s1.getSections(),s2.getSections());

   return sortPrice;

  }).forEach(System.out::println);

  

 

  测试结果:
 

  2.4 流的终止操作

  2.4.1 匹配和查找

  2.4.1.1 全匹配:allMatch

  

//全匹配:allMatch

 

  log.info("------------ 全匹配:allMatch --------------");

  //全匹配:allMatch ,所有的元素都要满足匹配条件,返回true,只要有一个不满足,就返回false;

  //判断所有的小说价格都是大于60的

  boolean allMatchFlag = StoryUtil.stories.stream().allMatch(story - story.getPrice() 60);

  log.info("----- 是否所有的小说价格都是大于60:{} ------",allMatchFlag);

  

 

  测试结果:

  2.4.1.2 任意匹配:mnyMatch

  

log.info("------------ 任意匹配:mnyMatch --------------");

 

  //全任意匹配:mnyMatch ,所有的元素 只要有一个 满足匹配条件,返回false,全部不满足,就返回false;

  //判断所有的小说 章节 有 小于990的

  boolean mnyMatchFlag = StoryUtil.stories.stream().anyMatch(story - story.getSections() 990);

  log.info("----- 是否所有的小说 章节 有 小于990的:{} ------",mnyMatchFlag);

  

 

  测试结果:

  2.4.1.3 全不匹配:noneMatch

  

log.info("------------ 全不匹配:noneMatch --------------");

 

  //全不匹配:noneMatch ,所有的元素都 不 满足匹配条件,返回true,只要有一个满足,就返回false;

  //判断存在武侠类小说

  boolean noneMatchFlag = StoryUtil.stories.stream().noneMatch(story - story.getCategory().equals("武侠"));

  log.info("----- 是否 不 存在武侠类小说:{} ------",noneMatchFlag);

  //判断存在 都市类小说

  boolean noneMatchFlag2 = StoryUtil.stories.stream().noneMatch(story - story.getCategory().equals("都市"));

  log.info("----- 是否 不 存在都市类小说:{} ------",noneMatchFlag2);

  

 

  测试结果:

  2.4.1.4 统计:count

  

log.info("------------ 统计:count --------------");

 

  //统计:count,统计所有的元素满足条件的元素个数

  //统计小说作者名字中包含a的数量

  long count = StoryUtil.stories.stream().filter(story - story.getAuthor().contains("a")).count();

  log.info("------- 统计小说作者名字中包含a的数量:{} -------------",count);

  

 

  测试结果:

  2.4.1.5 最大值:max

  

log.info("------------ 最大值:max --------------");

 

  //最大值:max,获取所有的元素满足条件的元素最大值

  //获取所有小说中,最多的章节

  Optional Integer maxSections = StoryUtil.stories.stream().map(story - story.getSections()).max(Integer::compareTo);

  log.info("------- 获取所有小说中,最多的章节:{} -------------",maxSections.get());

  

 

  测试结果:

  2.4.1.6 最小值:min

  

log.info("------------ 最小值:min --------------");

 

  //最小值:min,获取所有的元素满足条件的元素最小值

  //获取所有小说中,最低价格

  Optional Double minPrice = StoryUtil.stories.stream().map(story - story.getPrice()).min(Double::compareTo);

  log.info("------- 获取所有小说中,最低价格:{} -------------",minPrice.get());

  

 

  测试结果:

  2.4.2 收集:collect

  2.4.2.1 Collectors.toList()

  

//获取所有小说中,分类为玄幻的小说,收集为新的小说结合

 

  List Story storyList = StoryUtil.stories.stream().filter(story - story.getCategory().equals("玄幻")).collect(Collectors.toList());

  log.info("获取所有小说中,分类为玄幻的小说,收集为新的小说结合:{}",storyList);

  

 

  测试结果:

  2.4.2.2 Collectors.toSet()

  

//获取所有小说中,所有的分类集合(要去重)

 

  Set String categorySet = StoryUtil.stories.stream().map(Story::getCategory).collect(Collectors.toSet());

  log.info("------ 获取所有小说中,所有的分类集合(要去重):{} -----",categorySet);

  

 

  测试结果:
 

  2.4.2.3 Collectors.toMap(Story::getId,Story::getName)

  

//获取所有小说中,将小说编号作为key,小说名称作为value,收集map集合

 

  Map Integer,String storyMap = StoryUtil.stories.stream().collect(Collectors.toMap(Story::getId,Story::getName));

  log.info("------- 获取所有小说中,将小说编号作为key,小说名称作为value,收集map集合:{} ------",storyMap);

  

 

  测试结果:

  2.4.2.4 Collectors.groupingBy(Story::getCategory)

  

//获取所有小说中,根据小说的分类进行分组,同一个分类收集为新的集合

 

  Map String,List Story storyCategoryMap = StoryUtil.stories.stream().collect(Collectors.groupingBy(Story::getCategory));

  log.info("------- 取所有小说中,根据小说的分类进行分组,同一个分类收集为新的集合:{} ------",storyCategoryMap);

  

 

  测试结果:

  2.4.2.5 Collectors.averagingDouble(Double::doubleValue)

  

//求所有小说的平均价格

 

  Double avgPrice = StoryUtil.stories.stream().map(Story::getPrice).collect(Collectors.averagingDouble(Double::doubleValue));

  log.info("------- 求所有小说的平均价格:{} -------",avgPrice);

  

 

  测试结果:

  2.4.3 遍历

  2.4.3.1 forEach

  

//一般遍历都是集合list或者map,如果需要遍历,不需要的中间操作,就可以直接调用forEach

 

  StoryUtil.stories.forEach(story - {

   if(story.getCategory().equals("玄幻") story.getAuthor().contains("a")){

   log.info("满足条件的,小说:{}",story);

  

 

  测试结果:

  2.4.3.2 map遍历

  

//map遍历,也支持,相对与以前,会更简洁

 

  Map Integer,String storyMap = StoryUtil.stories.stream().collect(Collectors.toMap(Story::getId,Story::getName));

  storyMap.forEach((k,v)- log.info("key:{},value:{}",k,v));

  

 

  测试结果:

  2.4.4 规约:reduce

  规约:一般时将流中的元素进行求和操作;

  2.4.4.1 常规写法

  

//一直数值结合

 

  List Integer numList = Arrays.asList(11,22,33,44,5,66);

  //常规写法

  Optional Integer reduceSum1 = numList.stream().reduce((n, m) - n + m);

  log.info("--------- 所有的数值之和为:{} ----------",reduceSum1.get());

  

 

  测试结果:

  2.4.4.2 简化写法

  

 //简化写法

 

  Optional Integer reduceSum2 = numList.stream().reduce(Integer::sum);

  log.info("--------- 所有的数值之和为:{} ----------",reduceSum2.get());

  

 

  测试结果:

  2.4.4.3 原理

  

//原理

 

  Optional Integer reduceSum3 = numList.stream().reduce((x,y) - {

   log.info("x = {}",x);

   x += y;

   log.info("y = {}",y);

   log.info("x_new = {}",y);

   return x;

  log.info("--------- 所有的数值之和为:{} ----------",reduceSum3.get());

  

 

  测试结果:

  2.4.4.4 练习

  

//计算所有小说的章节总和

 

  Optional Integer reduceSection = StoryUtil.stories.stream().map(Story::getSections).reduce(Integer::sum);

  log.info("-------- 计算所有小说的章节总和:{} ----------",reduceSection.get());

  

 

  测试结果:

  3、新日期处理

  3.1 当前时间的毫秒数

  

// 当前时间的毫秒数

 

  long currentMilli1 = Instant.now().toEpochMilli();

  long currentMilli2 = System.currentTimeMillis(); // 只取毫秒,推荐

  log.info("当前毫秒:{},{}", currentMilli1, currentMilli2);

  //当前毫秒:1666168947407,1666168947407

  

 

  3.2 当前日期,只有年月日,没有时间

  

// 当前日期,只有年月日,没有时间

 

  LocalDate localDate1 = LocalDate.now();

  log.info("当前日期:{}", localDate1);

  log.info("当前日期:年-{},月-{},日-{}", localDate1.getYear(), localDate1.getMonthValue(), localDate1.getDayOfMonth());

  //当前日期:2022-10-19

  //当前日期:年-2022,月-10,日-19

  

 

  3.3 指定日期

  

// 指定日期

 

  LocalDate localDate2 = LocalDate.of(2020, 8, 10);

  log.info("指定日期:{}", localDate2);

  //指定日期:2020-08-10

  

 

  3.4 日期比较

  

// 日期比较

 

  log.info("日期是否相等:{}", localDate1.equals(localDate2));

  log.info("日期之前:{}", localDate1.isBefore(localDate2));

  log.info("日期之后:{}", localDate1.isAfter(localDate2));

  //日期是否相等:false

  //日期之前:false

  //日期之后:true

  

 

  3.5 当前时间,只有时间,没有年月日

  

// 当前时间,只有时间,没有年月日

 

  log.info("当前时间:{}", LocalTime.now());

  //当前时间:16:42:27.480

  

 

  3.6 当前时间增加一个小时

  

// 当前时间增加一个小时

 

  log.info("当前时间增加1个小时:{}", LocalTime.now().plusHours(1));

  //当前时间增加1个小时:17:42:27.480

  

 

  3.7 判断当前年是否是闰年

  

// 判断当前年是否是闰年

 

  log.info("当前年是否是闰年:{}", localDate2.isLeapYear());

  //当前年是否是闰年:true

  

 

  3.8 当前日期时间

  

// 当前日期时间

 

  log.info("当前日期时间:{}", LocalDateTime.now());

  //当前日期时间:2022-10-19T16:42:27.480

  

 

  3.9 日期格式化

  

// 日期格式化

 

  log.info("当前日期格式化字符串:{}", LocalDateTime.now().format(DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss")));

  //当前日期格式化字符串:2022-10-19 16:42:27

  

 

  3.10 判断2月多少天

  

// 判断2月多少天

 

  log.info("2028年的2月份有多少天:{}", YearMonth.of(2028, Month.FEBRUARY).lengthOfMonth());

  //2028年的2月份有多少天:29

  

 

  3.11 判断是否是生日

  

// 判断是否是生日

 

  LocalDate birthday = LocalDate.of(2000, 5, 7);

  MonthDay birthdayMonthDay = MonthDay.of(birthday.getMonth(), birthday.getDayOfMonth());

  MonthDay currentMonthDay = MonthDay.from(LocalDate.now());

  log.info("今天是生日吗?{}", currentMonthDay.equals(birthdayMonthDay));

  //今天是生日吗?false

  

 

  3.12 时区处理

  3.12.1 获取系统默认时区

  

// 获取系统默认时区

 

  log.info("默认时区:{}", ZoneId.systemDefault());

  //默认时区:Asia/Shanghai

  

 

  3.12.2 指定时区

  

// 指定时区

 

  log.info("指定时区:{}", ZoneId.of("America/Chicago"));

  //指定时区:America/Chicago

  

 

  3.12.3 时区对应时间

  

// 时区对应时间

 

  LocalDateTime localDateTime = LocalDateTime.now(ZoneId.of("Europe/Paris"));

  //时区-Europe/Paris的时间:2022-10-19T10:42:27.508

  

 

  3.12.4 带时区的时间

  

// 带时区的时间

 

  ZonedDateTime zonedDateTime = LocalDateTime.now().atZone(ZoneId.of("Asia/Shanghai"));

  log.info("时区-Europe/Paris的时间:{} ", localDateTime);

  log.info("时区-Asia/Shanghai的时间:{} ", zonedDateTime);

  //时区-Asia/Shanghai的时间:2022-10-19T16:42:27.510+08:00[Asia/Shanghai]

  

 

  3.13 日期工具类 DateUtil

  点击查看代码

  

/**

 

   * Created On : 2022/10/19.

   * p

   * Author : zhukang

   * p

   * Description: 日期工具类

  public class DateUtil {

   * 显示年月日时分秒,例如 2022-05-07 09:09:09.

   public static final String DATE_PATTERN_ALL = "yyyy-MM-dd HH:mm:ss";

   * 仅显示年月日,例如 2022-05-07.

   public static final String DATE_PATTERN_YMD = "yyyy-MM-dd";

   * 仅显示时分秒,例如 09:09:09.

   public static final String DATE_PATTERN_HMS = "HH:mm:ss";

   * 显示年月日时分秒(无分隔符),例如 20220507090909.

   public static final String UNSIGNED_DATE_PATTERN_ALL = "yyyyMMddHHmmss";

   * 仅显示年月日(无分隔符),例如 20220507.

   public static final String UNSIGNED_DATE_PATTERN_YMD = "yyyyMMdd";

   * 星期日;

   public static final String WEEK_SUNDAY = "星期日";

   * 星期一;

   public static final String WEEK_MONDAY = "星期一";

   * 星期二;

   public static final String WEEK_TUESDAY = "星期二";

   * 星期三;

   public static final String WEEK_WEDNESDAY = "星期三";

   * 星期四;

   public static final String WEEK_THURSDAY = "星期四";

   * 星期五;

   public static final String WEEK_FRIDAY = "星期五";

   * 星期六;

   public static final String WEEK_SATURDAY = "星期六";

   * 获取日期时间字符串

   * @param temporal 需要转化的日期时间

   * @param pattern 时间格式

   * @return String 日期时间字符串,例如 2022-05-07 17:25:05

   public static String format(TemporalAccessor temporal, String pattern) {

   DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);

   return dateTimeFormatter.format(temporal);

   * 获取当前日期和时间字符串.

   * @return String 日期时间字符串,例如 2022-05-07 09:09:09

   public static String formatLocalDateTime2String() {

   return format(LocalDateTime.now(), DATE_PATTERN_ALL);

   * 获取当前日期和时间字符串,无符号

   * @return String 日期时间字符串,例如 20220507090909

   public static String formatUnsignedLocalDateTime2String() {

   return format(LocalDateTime.now(), UNSIGNED_DATE_PATTERN_ALL);

   * 获取当前日期字符串.

   * @return String 日期字符串,例如2022-05-07

   public static String formatLocalDate2String() {

   return format(LocalDate.now(), DATE_PATTERN_YMD);

   * 获取当前日期字符串,无符号

   * @return String 日期字符串,例如2022-05-07

   public static String formatUnsignedLocalDate2String() {

   return format(LocalDate.now(), UNSIGNED_DATE_PATTERN_YMD);

   * 日期时间字符串转换为日期时间(java.time.LocalDateTime)

   * @param localDateTime 日期时间字符串

   * @param pattern 日期时间格式 例如DATETIME_PATTERN

   * @return LocalDateTime 日期时间

   public static LocalDateTime parseLocalDateTime(String localDateTime, String pattern) {

   DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);

   return LocalDateTime.parse(localDateTime, dateTimeFormatter);

   * 日期字符串转换为日期(java.time.LocalDate)

   * @param localDate 日期字符串

   * @param pattern 日期格式 例如DATE_PATTERN

   * @return LocalDate 日期

   public static LocalDate parseLocalDate(String localDate, String pattern) {

   DateTimeFormatter dateTimeFormatter = DateTimeFormatter.ofPattern(pattern);

   return LocalDate.parse(localDate, dateTimeFormatter);

   * 将Date转换为LocalDatetime,系统默认时区

   * @param date 指定日期对象

   * @return LocalDateTime 新的日期时间

   public static LocalDateTime parseDate2LocalDateTime(Date date) {

   return LocalDateTime.ofInstant(date.toInstant(), ZoneId.systemDefault());

   * 将LocalDatetime转换为Date

   * @return Date java.util.Date日期对象

   public static Date parseLocalDateTime2Date() {

   return Date.from(LocalDateTime.now().atZone(ZoneId.systemDefault()).toInstant());

   * 获取当前时间字符串.

   * @return String 时间字符串,例如 17:25:05

   public static String formatLocalTime2String() {

   return format(LocalTime.now(), DATE_PATTERN_HMS);

   * 获取当前星期字符串.

   * @return String 当前星期字符串,例如 星期二

   public static String getDayOfWeek() {

   return format(LocalDate.now(), "E");

   * 获取指定日期是星期几

   * @param localDate 日期

   * @return String 星期几

   public static String getDayOfWeek(LocalDate localDate) {

   String[] weekOfDays = {WEEK_MONDAY, WEEK_TUESDAY, WEEK_WEDNESDAY, WEEK_THURSDAY, WEEK_FRIDAY, WEEK_SATURDAY, WEEK_SUNDAY};

   int dayOfWeek = localDate.getDayOfWeek().getValue() - 1;

   return weekOfDays[dayOfWeek];

   * 获取指定日期时间加上指定时间单位的数量日期之后的日期时间.

   * @param localDateTime 日期时间

   * @param num 数量

   * @param chronoUnit 日期时间单位

   * @return LocalDateTime 新的日期时间

   public static LocalDateTime addDatetimeByUnit(LocalDateTime localDateTime, int num, ChronoUnit chronoUnit) {

   return localDateTime.plus(num, chronoUnit);

   * 获取指定日期时间减去指定时间单位的数量日期之后的日期时间.

   * @param localDateTime 日期时间

   * @param num 数量

   * @param chronoUnit 日期时间单位

   * @return LocalDateTime 新的日期时间

   public static LocalDateTime subByDatetimeByUnit(LocalDateTime localDateTime, int num, ChronoUnit chronoUnit) {

   return localDateTime.minus(num, chronoUnit);

   * 在指定日期时间的基础上增加月份和天数

   * @param localDateTime 日期时间

   * @param months 月份

   * @param days 天数

   * @return LocalDateTime 新的日期时间

   public static LocalDateTime addDatetimeMD(LocalDateTime localDateTime, int months, int days) {

   return localDateTime.now()

   .plus(months, ChronoUnit.MONTHS)

   .plus(days, ChronoUnit.DAYS);

   * 在指定日期时间的基础上增加hour小时,minutes分钟和seconds秒

   * @param hour 小时

   * @param minutes 分钟

   * @param seconds 秒

   * @return LocalDateTime 新的日期时间

   public static LocalDateTime addDatetimeHms(int hour, int minutes, int seconds) {

   return LocalDateTime.now()

   .plus(hour, ChronoUnit.HOURS)

   .plus(minutes, ChronoUnit.MINUTES)

   .plus(seconds, ChronoUnit.SECONDS);

   * 在当前时间的基础上减少hour小。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: