jdk8-笔记

第3集 Java新特性玩转JDK8之时间⽇期处理类上集 简介:讲解jdk8之后处理时间的api 时间处理再熟悉不过,SimpleDateFormat,Calendar等类 旧版缺点: java.util.Date 是⾮线程安全 的 API设计⽐较差,⽇期/时间对象⽐较,加减麻烦 Java 8通过发布新的Date-Time API (JSR 310)来进⼀步加强对⽇期与时间的处理 新增了很多常⻅的api,如⽇期/时间的⽐较,加减,格式化等 包所在位置 java.time 核⼼类 LocalDate 常⽤API Base64.Decoder decoder = Base64.getDecoder(); Base64.Encoder encoder = Base64.getEncoder(); String text = "⼩滴课堂"; byte[] textByte = text.getBytes("UTF-8"); //编码 String encodedText = encoder.encodeToString(textByte); System.out.println(encodedText); //解码 System.out.println(new String(decoder.decode(encodedText), "UTF8")); LocalDate:不包含具体时间的⽇期。 LocalTime:不含⽇期的时间。 LocalDateTime:包含了⽇期及时间。 LocalDate today = LocalDate.now(); System.out.println("今天⽇期:" + today); //获取年,⽉,⽇,周⼏ System.out.println("现在是哪年:"+today.getYear()); System.out.println("现在是哪⽉:"+today.getMonth()); System.out.println("现在是哪⽉(数字):"+today.getMonthValue()); System.out.println("现在是⼏号:"+today.getDayOfMonth()); System.out.println("现在是周⼏:"+today.getDayOfWeek()); //加减年份, 加后返回的对象才是修改后的, 旧的依旧是旧的 LocalTime 常⽤API LocalDateTime 常⽤API 

愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问 xdclass.net 第1章 Java⾼级核⼼玩转JDK8~13新特性课程介绍 第1集 Java新特性玩转JDK8~13课程⼤纲讲解 简介:讲解 Java新特性玩转JDK8~13课程⼤纲讲解 课程适合⼈群:中⾼级后端⼯程师、全栈⼯程师、架构师 需要的基础:需要有javase基础,熟悉 eclipse或者IDEA,如果不会可以看IDEA教程 课程⼤纲 学后⽔平 掌握JDK8 新增的⽇期处理、⾃带加解密、Optional特性 掌握JKD8 最核⼼的lambda表达 式和可以实现⾃定义函数式接⼝ 掌握 Function、Consumer、Supplier、Predicate四⼤接⼝使⽤ 玩转Stream流式编程map、filter、reduce、match等核⼼⽅法使⽤ 玩转JKD8 Collector收集器和 分组聚合统计 掌握JDK8特性 综合实战之电商订单数据处理 掌握JVM新的内存空间MetaSpace和 try-with-resouce使⽤ 掌握JDK9新⼯具Jshell和增强API 掌握JDK10的局部变量类型推断Var实践 玩 转JDK11的标准HttpClient提交GET,POST、异步请求和Http2请求 掌握JDK13新特性多⾏⽂本块和 增强switch等 ...更多看课程⽬录和视频 第2集 Java新特性之JDK8相关开发环境准备 简介:讲解JDK8相关特性的开发环境准备 官⽅概览 https://www.oracle.com/technetwork/cn/java/javase/8-whats-new-2157071-zhs.ht ml 重点 ⽇期 lambda 函数式编程 Stream 其他 Java 8 是⽬前最被⼴泛使⽤的版本,并且其⽤户群体⾮常⼴,所以Java 8 是⼀个⾮常成功的版本, 阿⾥、京东等⼤⼚⾥⾯主流应⽤都是JDK8版本 相关环境变量安装 本地有eclipse或者idea jdk8安装包:官⽅地址 https://www.oracle.com/technetwork/java/javase/downloads/jdk 8-downloads-2133151.html 如果地址过期则使⽤本集课程资料⾥⾯的包即可 jdk8安装 Win10 https://blog.csdn.net/Coco_liukeke/article/details/79834680 Win8 https: //jingyan.baidu.com/article/7c6fb4282f1f6580642c90e1.html Linux https://www.jianshu .com/p/5cee1c7a4dd4 Mac https://www.jianshu.com/p/a85658902f26 win64位-JDK1.8下载||https://pan.baidu.com/s/1fMNaZ0JgySo2MzBT90T5Tw ||jjw3 Linux64位-JDK1.8||https://pan.baidu.com/s/1CDpW-UNYyje-p0BxaNtncQ ||nwyd Mac-JDK1.8下载||https://pan.baidu.com/s/1liT9kSLicpXEAd7AdA0nOg ||5bpk 愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问官⽹: xdclass.net 第2章 Java⾼级核⼼玩转JDK8新特性之接⼝和⽇期处理 第1集 Java新特性玩转JDK8之default关键字 简介:讲解jdk8新特性default关键字 创建⼀个java基础项⽬ 在jdk1.8以前接⼝⾥⾯是只能有抽象⽅法,不能有任何⽅法的实现的 jdk1.8⾥⾯打破了这个规定,引⼊了新的关键字default,使⽤default修饰⽅法,可以在接⼝⾥⾯ 定义具体的⽅法实现 默认⽅法: 接⼝⾥⾯定义⼀个默认⽅法,这个接⼝的实现类实现了这个接⼝之后,不⽤管这个 default修饰的⽅法就可以直接调⽤,即接⼝⽅法的默认实现 静态⽅法: 接⼝名.静态⽅法来访问接⼝中的静态⽅法 public interface Animal { void run(); void eat(); default void breath(){ System.out.println("使⽤氧⽓呼吸"); } } public interface Animal { void run(); void eat(); default void breath(){ System.out.println("使⽤氧⽓呼吸"); } static void test(){ System.out.println("这是静态⽅法"); } } 第2集 Java新特性玩转JDK8之新增base64加解密API 简介:讲解jdk1.8新增Base64 api 什么是Base64编码 Base64是⽹络上最常⻅的⽤于传输8Bit字节码的编码⽅式之⼀,Base64就是 ⼀种基于64个可打印字符来表示⼆进制数据的⽅法 基于64个字符A-Z,a-z,0-9,+,/的编码⽅式, 是⼀种能将任意⼆进制数据⽤64种字元组合成字符串的⽅法,⽽这个⼆进制数据和字符串资料之 间是可以互相转换的,在实际应⽤上,Base64除了能将⼆进制数据可视化之外,也常⽤来表示字 串加密过后的内容 推荐⼀个⽂章:https://blog.csdn.net/wo541075754/article/details/81734770 早期java要使⽤Base64怎么做 使⽤JDK⾥sun.misc套件下的BASE64Encoder和BASE64Decoder这两个类 缺点:编码和解码的效率⽐较差,公开信息说以后的版本会取消这个⽅法 Apache Commons Codec有提供Base64的编码与解码 缺点:是需要引⽤Apache Commons Codec jdk1.8之后怎么玩?(⾸选推荐) Jdk1.8的java.util包中,新增了Base64的类 好处:不⽤引包,编解码销量远⼤于 sun.misc 和 Apache Commons Codec BASE64Encoder encoder = new BASE64Encoder(); BASE64Decoder decoder = new BASE64Decoder(); String text = "⼩滴课堂"; byte[] textByte = text.getBytes("UTF-8"); //编码 String encodedText = encoder.encode(textByte); System.out.println(encodedText); //解码 System.out.println(new String(decoder.decodeBuffer(encodedText), "UTF-8")); 第3集 Java新特性玩转JDK8之时间⽇期处理类上集 简介:讲解jdk8之后处理时间的api 时间处理再熟悉不过,SimpleDateFormat,Calendar等类 旧版缺点: java.util.Date 是⾮线程安全 的 API设计⽐较差,⽇期/时间对象⽐较,加减麻烦 Java 8通过发布新的Date-Time API (JSR 310)来进⼀步加强对⽇期与时间的处理 新增了很多常⻅的api,如⽇期/时间的⽐较,加减,格式化等 包所在位置 java.time 核⼼类 LocalDate 常⽤API Base64.Decoder decoder = Base64.getDecoder(); Base64.Encoder encoder = Base64.getEncoder(); String text = "⼩滴课堂"; byte[] textByte = text.getBytes("UTF-8"); //编码 String encodedText = encoder.encodeToString(textByte); System.out.println(encodedText); //解码 System.out.println(new String(decoder.decode(encodedText), "UTF8")); LocalDate:不包含具体时间的⽇期。 LocalTime:不含⽇期的时间。 LocalDateTime:包含了⽇期及时间。 LocalDate today = LocalDate.now(); System.out.println("今天⽇期:" + today); //获取年,⽉,⽇,周⼏ System.out.println("现在是哪年:"+today.getYear()); System.out.println("现在是哪⽉:"+today.getMonth()); System.out.println("现在是哪⽉(数字):"+today.getMonthValue()); System.out.println("现在是⼏号:"+today.getDayOfMonth()); System.out.println("现在是周⼏:"+today.getDayOfWeek()); //加减年份, 加后返回的对象才是修改后的, 旧的依旧是旧的 LocalTime 常⽤API LocalDateTime 常⽤API 第4集 Java新特性玩转JDK8之时间⽇期处理类下集 简介:讲解jdk8之后处理时间的api ⽇期时间格式化 JDK8之前:SimpleDateFormat来进⾏格式化,但SimpleDateFormat并不是线程安全的 LocalDate changeDate = today.plusYears(1); System.out.println("加后是哪年:"+changeDate.getYear()); System.out.println("旧的是哪年:"+today.getYear()); //⽇期⽐较 System.out.println("isAfter: "+changeDate.isAfter(today)); //getYear() int 获取当前⽇期的年份 //getMonth() Month 获取当前⽇期的⽉份对象 //getMonthValue() int 获取当前⽇期是第⼏⽉ //getDayOfWeek() DayOfWeek 表示该对象表示的⽇期是星期⼏ //getDayOfMonth() int 表示该对象表示的⽇期是这个⽉第⼏天 //getDayOfYear() int 表示该对象表示的⽇期是今年第⼏天 //withYear(int year) LocalDate 修改当前对象的年份 //withMonth(int month) LocalDate 修改当前对象的⽉份 //withDayOfMonth(int dayOfMonth) LocalDate 修改当前对象在当⽉的⽇ 期 //plusYears(long yearsToAdd) LocalDate 当前对象增加指定的年份数 //plusMonths(long monthsToAdd) LocalDate 当前对象增加指定的⽉份数 //plusWeeks(long weeksToAdd) LocalDate 当前对象增加指定的周数 //plusDays(long daysToAdd) LocalDate 当前对象增加指定的天数 //minusYears(long yearsToSubtract) LocalDate 当前对象减去指定的年 数 //minusMonths(long monthsToSubtract) LocalDate 当前对象减去注定的 ⽉数 //minusWeeks(long weeksToSubtract) LocalDate 当前对象减去指定的周 数 //minusDays(long daysToSubtract) LocalDate 当前对象减去指定的天数 //compareTo(ChronoLocalDate other) int ⽐较当前对象和other对象在时 间上的⼤⼩,返回值如果为正,则当前对象时间较晚, //isBefore(ChronoLocalDate other) boolean ⽐较当前对象⽇期是否在 other对象⽇期之前 //isAfter(ChronoLocalDate other) boolean ⽐较当前对象⽇期是否在 other对象⽇期之后 //isEqual(ChronoLocalDate other) boolean ⽐较两个⽇期对象是否相等 JDK8之后:引⼊线程安全的⽇期与时间DateTimeFormatter 获取指定的⽇期时间对象 计算⽇期时间差 java.time.Duration 第5集 Java新特性玩转JDK8之Optional类 简介:讲解jdk8新增的Optional类 Optional 类有啥⽤ 主要解决的问题是空指针异常(NullPointerException) 怎么解决? 本质是⼀个包含有可选值的包装类,这意味着 Optional 类既可以含有对象也可以为空 创建Optional类 of() null 值作为参数传递进去,则会抛异常 LocalDateTime ldt = LocalDateTime.now(); System.out.println(ldt); DateTimeFormatter dtf = DateTimeFormatter.ofPattern("yyyy-MM-dd HH:mm:ss"); String ldtStr = dtf.format(ldt); System.out.println(ldtStr); LocalDateTime ldt = LocalDateTime.of(2020, 11, 11, 8, 20, 30); System.out.println(ldt); LocalDateTime today = LocalDateTime.now(); System.out.println(today); LocalDateTime changeDate = LocalDateTime.of(2020,10,1,10,40,30); System.out.println(changeDate); Duration duration = Duration.between( today,changeDate);//第⼆个参数减第⼀ 个参数 System.out.println(duration.toDays());//两个时间差的天数 System.out.println(duration.toHours());//两个时间差的⼩时数 System.out.println(duration.toMinutes());//两个时间差的分钟数 System.out.println(duration.toMillis());//两个时间差的毫秒数 System.out.println(duration.toNanos());//两个时间差的纳秒数 ofNullable() 如果对象即可能是 null 也可能是⾮ null,应该使⽤ ofNullable() ⽅法 访问 Optional 对象的值 get() ⽅法 如果值存在则isPresent()⽅法会返回true,调⽤get()⽅法会返回该对象⼀般使⽤get之前需要 先验证是否有值,不然还会报错 兜底 orElse⽅法 orElse()如果有值则返回该值,否则返回传递给它的参数值 Optional opt = Optional.of(user); Optional opt = Optional.ofNullable(user); Optional opt = Optional.ofNullable(student); Student s = opt.get(); public static void main(String[] args) { Student student = null; test(student); } public static void test(Student student){ Optional opt = Optional.ofNullable(student); System.out.println(opt.isPresent()); } Student student1 = null; Student student2 = new Student(2); Student result = Optional.ofNullable(student1).orElse(student2); System.out.println(result.getAge()); Student student = null; int result = Optional.ofNullable(student).map(obj- >obj.getAge()).orElse(4); System.out.println(result); 愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问官⽹: xdclass.net 第3章 Java⾼级核⼼玩转JDK8 Lambda表达式 第1集 Java新特性玩转 JDK8之 lambda表达式 简介:讲解什么是函数式编程和什么是lambda表达式 在JDK8之前,Java是不⽀持函数式编程的,所谓的函数编程,即可理解是将⼀个函数(也称为“⾏ 为”)作为⼀个参数进⾏传递, ⾯向对象编程是对数据的抽象(各种各样的POJO类),⽽函数式编 程则是对⾏为的抽象(将⾏为作为⼀个参数进⾏传递) java创建线程再熟悉不过了 jdk8之前创建线程 jdk8之后Lambda表达式则只需要使⽤⼀句话 集合容器⾥⾯的字符串排序 使⽤前 new Thread(new Runnable() { @Override public void run() { System.out.println("⼩滴课堂学习Java架构教程"); } }); new Thread(() -> System.out.println("⼩滴课堂学习Java架构教程")); 使⽤后 lambda表达式 使⽤场景(前提):⼀个接⼝中只包含⼀个⽅法,则可以使⽤Lambda表达式,这样 的接⼝称之为“函数接⼝” 语法: (params) -> expression 好处: Lambda 表达式的实现⽅式在本质是以匿名内部类的⽅式进⾏实现 List list =Arrays.asList("aaa","ggg","ffff","ccc"); Collections.sort(list, new Comparator() { @Override public int compare(String a, String b) { return b.compareTo(a); } } ); for (String string : list) { System.out.println(string); } List list =Arrays.asList("aaa","ggg","ffff","ccc"); Collections.sort(list, (a,b)->b.compareTo(a) ); for (String string : list) { System.out.println(string); } 第⼀部分为括号内⽤逗号分隔的形式参数,参数是函数式接⼝⾥⾯⽅法的参数;第⼆部分为⼀个箭 头符号:->;第三部分为⽅法体,可以是表达式和代码块 参数列表 : 括号中参数列表的数据类型可以省略不写 括号中的参数只有⼀个,那么参数类型和()都可以省略不写 ⽅法体: 如果{}中的代码只有⼀⾏,⽆论有返回值,可以省略{},return,分号,要⼀起省略,其他 则需要加上 重构现有臃肿代码,更⾼的开发效率,尤其是集合Collection操作的时候,后续会讲到 第2集 Java新特性玩转JDK8之⾃定义函数式编程实战 简介:玩转Lambda表达式,⾃定义lambda接⼝编程 ⾃定义lambda接⼝流程 定义⼀个函数式接⼝ 需要标注此接⼝ @FunctionalInterface,否则万⼀团队成员在接⼝上加 了其他⽅法则容易出故障 编写⼀个⽅法,输⼊需要操做的数据和接⼝ 在调⽤⽅法时传⼊数据 和 lambda 表达式,⽤来操作数据 需求,定义⼀个可以使⽤加减乘除的接⼝ 以前需要定义4个⽅法 使⽤Lambda表达式后 @FunctionalInterface public interface OperFunction<r,t> { R operator(T t1, T t2); } public static void main(String[] args) throws Exception { System.out.println(operator(20, 5, (Integer x, Integer y) -> { return x * y; })); System.out.println(operator(20, 5, (x, y) -> x + y)); System.out.println(operator(20, 5, (x, y) -> x - y)); System.out.println(operator(20, 5, (x, y) -> x / y)); } public static Integer operator(Integer x, Integer y, OperFunction<integer, integer=""> of) { return of.operator(x, y); } 愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问官⽹: xdclass.net 第4章 Java⾼级核⼼玩转JDK8 函数式编程 第1集 Java新特性玩转JDK8之函数式编程 Function 简介:讲解jdk8⾥⾯的函数式编程 Function接⼝的使⽤ Lambda表达式必须先定义接⼝,创建相关⽅法之后才可使⽤,这样做⼗分不便,其实java8已经 内置了许多接⼝, 例如下⾯四个功能型接⼝,所以⼀般很少会由⽤户去定义新的函数式接⼝ Java8的最⼤特性就是函数式接⼝,所有标注了@FunctionalInterface注解的接⼝都是函数式接⼝ Function 传⼊⼀个值经过函数的计算返回另⼀个值 T:⼊参类型,R:出参类型 调⽤⽅法:R apply(T t) Java8 内置的四⼤核⼼函数式接⼝ Consumer : 消费型接⼝:有⼊参,⽆返回值 void accept(T t); Supplier : 供给型接⼝:⽆⼊参,有返回值 T get(); Function<t, r=""> : 函数型接⼝:有⼊参,有返回值 R apply(T t); Predicate : 断⾔型接⼝:有⼊参,有返回值,返回值类型确定是boolean boolean test(T t); //@param the type of the input to the function //@param the type of the result of the function 作⽤:将转换逻辑提取出来,解耦合 不要看过于复杂,就是⼀个接⼝,下⾯是⾃定义实现 常规使⽤ 第2集 Java新特性玩转JDK8之函数式编程 BiFunction 简介:讲解jdk8⾥⾯的函数式编程 BiFunction接⼝的使⽤ BiFunction Function只能接收⼀个参数,如果要传递两个参数,则⽤ BiFunction @FunctionalInterface public interface Function<t, r=""> { /** * Applies this function to the given argument. * * @param t the function argument * @return the function result */ R apply(T t); } public class FunctionObj implements Function { @Override public Object apply(Object o) { return o+"经过apply处理拼接上了"; } } // 输出⼊参的10倍 Function<integer, integer=""> func = p -> p * 100; func.apply(100); @FunctionalInterface public interface BiFunction<t, u,="" r=""> { R apply(T t, U u); } 需求: 上两节课,两个数的四则运算 第3集 Java新特性玩转JDK8之函数式编程 Consumer 简介:讲解jdk8⾥⾯的函数式编程 Consumer接⼝的使⽤ Consumer 消费型接⼝:有⼊参,⽆返回值 将 T 作为输⼊,不返回任何内容 调⽤⽅法:void accept(T t); ⽤途: 因为没有出参,常⽤于打印、发送短信等消费动作 public static void main(String[] args) { System.out.println(operator(10,21,(a,b)->a+b)); System.out.println(operator(10,2,(a,b)->a-b)); System.out.println(operator(8,4,(a,b)->a*b)); System.out.println(operator(10,2,(a,b)->a/b)); } public static Integer operator(Integer a, Integer b, BiFunction<integer, integer,="" integer=""> bf) { return bf.apply(a, b); } @FunctionalInterface public interface Consumer { void accept(T t); } public static void main(String[] args) throws Exception { Consumer consumer = obj->{ System.out.println(obj); System.out.println("调⽤短信接⼝发送短信,或者打印⽇志"); }; // sendMsg("8888888",obj->{ // System.out.println(obj); // System.out.println("调⽤短信接⼝发送短信,或者打印⽇志"); 典型应⽤,集合的foreach 第4集 Java新特性玩转JDK8之函数式编程 Supplier 简介:讲解jdk8⾥⾯的函数式编程 Supplier接⼝的使⽤ Supplier: 供给型接⼝:⽆⼊参,有返回值 T:出参类型;没有⼊参 调⽤⽅法:T get(); ⽤途: 泛型⼀定和⽅法的返回值类型是⼀种类型,如果需要获得⼀个数据,并且不需要传⼊参数,可 以使⽤Supplier接⼝,例如 ⽆参的⼯⼚⽅法,即⼯⼚设计模式创建对象,简单来说就是 提供者 // }); sendMsg("8888888",consumer); } public static void sendMsg(String phone,Consumer consumer){ consumer.accept(phone); } List list = Arrays.asList("aaa","bbb"); list.forEach(obj->{ //TODO }); @FunctionalInterface public interface Supplier { T get(); } public static void main(String[] args) { //Student student = new Student(); Student student = newStudent(); System.out.println(student.getName()); } public static Student newStudent(){ Supplier supplier = ()-> { Student student = new Student(); 第5集 Java新特性玩转JDK8之函数式编程 Predicate 简介:讲解jdk8⾥⾯的函数式编程 Predicate接⼝的使⽤ Predicate: 断⾔型接⼝:有⼊参,有返回值,返回值类型确定是boolean T:⼊参类型;出参类型是Boolean 调⽤⽅法:boolean test(T t); ⽤途: 接收⼀个参数,⽤于判断是否满⾜⼀定的条件,过滤数据 student.setName("默认名称"); return student; }; return supplier.get(); } class Student{ private String name; public String getName() { return name; } public void setName(String name) { this.name = name; } } @FunctionalInterface public interface Predicate { boolean test(T t); } public static void main(String[] args) { List list = Arrays.asList("awewrwe","vdssdsd","aoooo","psdddsd"); 第6集 Java新特性玩转JDK8之⽅法与构造函数引⽤ 简介:讲解JDK8新特性中 ⽅法引⽤与构造函数引⽤ 以前⽅法调⽤ 对象.⽅法名 或者 类名.⽅法名 jdk1.8提供了另外⼀种调⽤⽅式 :: List results = filter(list,obj->obj.startsWith("a")); System.out.println(results); } public static List filter(List list, Predicate predicate) { List results = new ArrayList<>(); for (String str : list) { if (predicate.test(str)) { results.add(str); } } return results; } 说明:⽅法引⽤是⼀种更简洁易懂的lambda表达式,操作符是双冒号::,⽤来直接访问类或者实例 已经存在的⽅法或构造⽅法 通过⽅法引⽤,可以将⽅法的引⽤赋值给⼀个变量 语法:左边是容器(可以是类名,实例名),中间是" :: ",右边是相应的⽅法名 静态⽅法,则是ClassName::methodName。如 Object ::equals 实例⽅法,则是Instance::methodName 构造函数,则是 类名::new; 单个参数 Function<⼊参1, 返回类型> func = ⽅法引⽤ 应⽤ func.apply(⼊参); 2个参数 BiFunction<⼊参1,⼊参2, 返回类型> func = ⽅法引⽤ 应⽤ func.apply(⼊参1,⼊参2); public class TestJdk8 { public static void main(String[] args) { // 使⽤双冒号::来构造静态函数引⽤ Function<string, integer=""> fun = Integer::parseInt; Integer value = fun.apply("1024"); System.out.println(value); // 使⽤双冒号::来构造⾮静态函数引⽤ String content = "欢迎来到⼩滴课堂学习"; Function<integer, string=""> func = content::substring; String result = func.apply(1); System.out.println(result); // 构造函数引⽤,多个参数 BiFunction<string, integer,="" user=""> biFunction = User::new; User user1 = biFunction.apply("⼩滴课堂", 28); System.out.println(user1.toString()); //构造函数引⽤,单个参数 Function<string, user=""> function = User::new; User user2 = function.apply("⼩D"); System.out.println(user2.toString()); // 函数引⽤也是⼀种函数式接⼝,可以将函数引⽤作为⽅法的参数 sayHello(String::toUpperCase, "xdclass.net"); } /** * * @param func 函数引⽤ * @param param 对应的参数 */ private static void sayHello(Function<string, string=""> func, String param) { String result = func.apply(param); System.out.println(result); } } 愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问官⽹: xdclass.net 第5章 Java⾼级核⼼之玩转 JDK8 集合框架 第1集 Java新特性玩转JDK8之流Stream实战 简介:讲解jdk8⾥⾯的流stream的使⽤ 什么是stream Stream 中⽂称为 “流”,通过将集合转换为这么⼀种叫做 “流”的元素队列,通过声明性⽅式, 能够对集合中的每个元素进⾏⼀系列并⾏或串⾏的流⽔线操作 元素是特定类型的对象,所以元素集合看作⼀种流, 流在管道中传输, 且可以在管道的节点 上进⾏处理, ⽐如 排序,聚合,过滤等操作 class User { private String username; private Integer age; public User() { } public User(String username) { this.username = username; } public User(String username, Integer age) { this.username = username; this.age = age; } } 操作详情 数据元素便是原始集合,如List、Set、Map等 ⽣成流,可以是串⾏流stream() 或者并⾏流 parallelStream() 中间操作,可以是 排序,聚合,过滤,转换等 终端操作,很多流操作本身就会返回⼀个流,所以多个操作可以直接连接起来,最后统⼀进 ⾏收集 概览stream接⼝源码 快速上⼿ 第2集 Java新特性玩转JDK8之流操作map和filter函数 简介:讲解jdk8⾥⾯的流stream⾥的map和filter函数的使⽤ map函数 将流中的每⼀个元素 T 映射为 R(类似类型转换) 上堂课的例⼦就是,类似遍历集合,对集合的每个对象做处理 场景:转换对象,如javaweb开发中集合⾥⾯的DO对象转换为DTO对象 List list = Arrays.asList("springboot教程","微服务教程","并发编 程","压⼒测试","架构课程"); List resultList = list.stream().map(obj->"在⼩滴课堂 学:"+obj).collect(Collectors.toList()); System.out.println(resultList); filter函数 ⽤于通过设置的条件过滤出元素 需求:过滤出字符串⻓度⼤于5的字符串 场景:主要⽤于筛选过滤出符合条件的元素 第3集 Java新特性玩转JDK8之流操作limit和sorted函数 简介:讲解jdk8⾥⾯的流stream⾥的limit和sorted函数的使⽤ sorted函数 sorted() 对流进⾏⾃然排序, 其中的元素必须实现Comparable 接⼝ List list = Arrays.asList("springboot教程","微服务教程","并发编 程","压⼒测试","架构课程"); List resultList = list.stream().map(obj->"在⼩滴课堂 学:"+obj).collect(Collectors.toList()); System.out.println(resultList); List list = Arrays.asList(new User(1,"⼩东","123"),new User(21,"jack","rawer"), new User(155,"tom","sadfsdfsdfsd"), new User(231,"marry","234324"),new User(100,"⼩ D","122223")); List userDTOList = list.stream().map(obj->{ UserDTO userDTO = new UserDTO(obj.getId(),obj.getName()); return userDTO; }).collect(Collectors.toList()); System.out.println(userDTOList); List list = Arrays.asList("springboot", "springcloud", "redis", "git", "netty", "java", "html", "docker"); List resultList = list.stream().filter(obj -> obj.length() > 5).collect(Collectors.toList()); System.out.println(resultList); sorted(Comparator

comparator) ⽤来⾃定义升降序 limit函数 截断流使其最多只包含指定数量的元素 第4集 Java新特性玩转JDK8之流操作allMatch和anyMatch函数 简介:讲解jdk8⾥⾯的流stream⾥的allMatch和anyMatch函数的使⽤ allMatch函数 List list = Arrays.asList("springboot", "springcloud", "redis", "git", "netty", "java", "html", "docker"); List resultList = list.stream().sorted().collect(Collectors.toList()); List list = Arrays.asList("springboot", "springcloud", "redis", "git", "netty", "java", "html", "docker"); //根据⻓度进⾏排序 //List resultList = list.stream().sorted(Comparator.comparing(obj -> obj.length())).collect(Collectors.toList()); //List resultList = list.stream().sorted(Comparator.comparing(obj -> obj.length(),Comparator.reverseOrder())).collect(Collectors.toList() ); //List resultList = list.stream().sorted(Comparator.comparing(String::length).reversed() ).collect(Collectors.toList()); System.out.println(resultList); List list = Arrays.asList("springboot", "springcloud", "redis", "git", "netty", "java", "html", "docker"); //limit截取 List resultList = list.stream().sorted(Comparator.comparing(String::length).reversed() ).limit(3).collect(Collectors.toList()); System.out.println(resultList); 检查是否匹配所有元素,只有全部符合才返回true anyMatch函数 检查是否⾄少匹配⼀个元素 先看⽅法⼊参,返回值,再看⽅法描述 第5集 Java新特性玩转JDK8之流操作max和min函数 简介:讲解jdk8⾥⾯的流stream⾥的max和min函数的使⽤ max和min函数 最⼤值和最⼩值 List list = Arrays.asList("springboot", "springcloud", "redis", "git", "netty", "java", "html", "docker"); boolean flag = list.stream().allMatch(obj->obj.length()>1); System.out.println(flag); List list = Arrays.asList("springboot", "springcloud", "redis", "git", "netty", "java", "html", "docker"); boolean flag = list.stream().anyMatch(obj->obj.length()>18); System.out.println(flag); 愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问官⽹: xdclass.net 第6章 Java⾼级核⼼之玩转 JDK8 集合框架进阶 第1集 Java新特性玩转JDK8之并⾏流parallelStream 简介:讲解jdk8⾥⾯的并⾏流parallelStream 为什么会有这个并⾏流 集合做重复的操作,如果使⽤串⾏执⾏会相当耗时,因此⼀般会采⽤多线程来加快, Java8的 paralleStream⽤fork/join框架提供了并发执⾏能⼒ 底层原理 线程池(ForkJoinPool)维护⼀个线程队列 可以分割任务,将⽗任务拆分成⼦任务,完全贴合分治思想 两个区别 List list = Arrays.asList(new Student(32),new Student(33),new Student(21),new Student(29),new Student(18)); //list.stream().max(Comparator.comparingInt(Student::getAge)); //最⼤ Optional optional = list.stream().max((s1, s2)- >Integer.compare(s1.getAge(),s2.getAge())); //最⼩ Optional optional = list.stream().min((s1, s2)- >Integer.compare(s1.getAge(),s2.getAge())); System.out.println(optional.get().getAge()); 问题 paralleStream并⾏是否⼀定⽐Stream串⾏快? 错误,数据量少的情况,可能串⾏更快,ForkJoin会耗性能 多数情况下并⾏⽐串⾏快,是否可以都⽤并⾏ 不⾏,部分情况会有线程安全问题,parallelStream⾥⾯使⽤的外部变量,⽐如集合⼀ 定要使⽤线程安全集合,不然就会引发多线程安全问题 //顺序输出 List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); numbers.stream().forEach(System.out::println); //并⾏乱序输出 List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9); numbers.parallelStream().forEach(System.out::println); for(int i=0;i<10;i++) { List list = new ArrayList(); //List list = new CopyOnWriteArrayList(); IntStream.range(0, 100).parallel().forEach(list::add); System.out.println(list.size()); } 第2集 Java新特性玩转JDK8之reduce操作 简介:讲解jdk8⾥⾯的reduce操作 什么是reduce操作 聚合操作,中⽂意思是 “减少” 根据⼀定的规则将Stream中的元素进⾏计算后返回⼀个唯⼀的值 常⽤⽅法⼀ accumulator 计算的累加器 例⼦: 第⼀个元素相加和第⼆个元素相加,结果再和第三个元素相加,直到全部相加完 成 不⽤lambda的写法 Optional reduce(BinaryOperator accumulator); int value = Stream.of(1, 2, 3, 4, 5).reduce((item1, item2) -> item1 + item2).get(); 常⽤⽅法⼆ identity ⽤户提供⼀个循环计算的初始值 accumulator 计算的累加器 例⼦: 100作为初始值,然后和第⼀个元素相加,结果在和第⼆个元素相加,直到全部 相加完成 练习 : 求最⼤值 第3集 Java新特性玩转JDK8之集合的foreach 简介:讲解jdk8⾥⾯的list的foreach操作 集合遍历的⽅式 for循环 迭代器 Iterator Jdk8⾥⾯的新增接⼝ int result = Stream.of(1,2,3,4,5).reduce(new BinaryOperator() { @Override public Integer apply(Integer item1, Integer item2) { return item1 + item2; } }).get(); T reduce(T identity, BinaryOperator accumulator); int value = Stream.of(1, 2, 3, 4,5).reduce(100, (sum, item) -> sum + item); int value = Stream.of(1645, 234345, 32, 44434,564534,435,34343542,212).reduce( (item1, item2) -> item1 > item2 ? item1 : item2 ).get(); System.out.println(value); 注意点 不能修改包含外部的变量的值 不能⽤break或者return或者continue等关键词结束或者跳过循环 愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问官⽹: xdclass.net 第7章 Java⾼级核⼼之玩转 JDK8 收集器和集合统计 第1集 Java新特性玩转JDK8之collector收集器 简介:讲解jdk8⾥⾯的收集器collector collect()⽅法的作⽤ ⼀个终端操作, ⽤于对流中的数据进⾏归集操作,collect⽅法接受的参数是⼀个Collector 有两个重载⽅法,在Stream接⼝⾥⾯ default void forEach(Consumer

action) { Objects.requireNonNull(action); for (T t : this) { action.accept(t); } } List results = Arrays.asList(new Student(32),new Student(33),new Student(21),new Student(29),new Student(18)); results.forEach(obj->{ System.out.println(obj.toString()); }); Collector的作⽤ 就是收集器,也是⼀个接⼝, 它的⼯具类Collectors提供了很多⼯⼚⽅法 Collectors 的作⽤ ⼯具类,提供了很多常⻅的收集器实现 Collectors.toList() ArrayList::new,创建⼀个ArrayList作为累加器 List::add,对流中元素的操作就是直接添加到累加器中 reduce操作, 对⼦任务归集结果addAll,后⼀个⼦任务的结果直接全部添加到 前⼀个⼦任务结果中 CH_ID 是⼀个unmodifiableSet集合 Collectors.toMap() Collectors.toSet() Collectors.toCollection() :⽤⾃定义的实现Collection的数据结构收集 Collectors.toCollection(LinkedList::new) Collectors.toCollection(CopyOnWriteArrayList::new) Collectors.toCollection(TreeSet::new) 第2集 Java新特性玩转JDK8之joining函数 简介:讲解jdk8⾥⾯的收集器joining函数 拼接函数 Collectors.joining //重载⽅法⼀ R collect(Supplier supplier, BiConsumer<r, ?="" super="" t=""> accumulator, BiConsumer<r, r="">combiner); //重载⽅法⼆ <r, a=""> R collect(Collector

collector); public static Collector<t, ?,="" list<t="">> toList() { return new CollectorImpl<>((Supplier<list>) ArrayList::new, List::add,(left, right) -> { left.addAll(right); return left; }, CH_ID); } 其中⼀个的实现 说明: 该⽅法可以将Stream得到⼀个字符串, joining函数接受三个参数,分别表示 元素之间的连 接符、前缀和后缀。 第3集 Java新特性玩转JDK8之收集器 partitioningBy分组 简介:讲解jdk8⾥⾯的收集器partitioningBy分组 Collectors.partitioningBy 分组,key是boolean类型 练习: 根据list⾥⾯进⾏分组,字符串⻓度⼤于4的为⼀组,其他为另外⼀组 //3种重载⽅法 Collectors.joining() Collectors.joining("param") Collectors.joining("param1", "param2", "param3") public static Collector<charsequence, ?,="" string=""> joining() { return new CollectorImpl<charsequence, stringbuilder,="" string="">( StringBuilder::new, StringBuilder::append, (r1, r2) -> { r1.append(r2); return r1; }, StringBuilder::toString, CH_NOID); } String result = Stream.of("springboot", "mysql", "html5", "css3").collect(Collectors.joining(",", "[", "]")); public static Collector<t, ?,="" map<boolean,="" list<t="">>> partitioningBy(Predicate

predicate) { return partitioningBy(predicate, toList()); } List list = Arrays.asList("java", "springboot", "HTML5","nodejs","CSS3"); Map<boolean, list<string="">> result = list.stream().collect(partitioningBy(obj -> obj.length() > 4)); 第4集 Java新特性玩转JDK8之收集器 group by分组 简介:讲解jdk8⾥⾯的收集器 group by分组 分组 Collectors.groupingBy() 练习:根据学⽣所在的省份,进⾏分组 public static <t, k=""> Collector<t, ?,="" map<k,="" list<t="">>> groupingBy(Function

classifier) { return groupingBy(classifier, toList()); } List students = Arrays.asList(new Student("⼴东", 23), new Student("⼴东", 24), new Student("⼴东", 23),new Student("北京", 22), new Student("北京", 20), new Student("北京", 20),new Student("海南", 25)); Map<string, list<student="">> listMap = students.stream().collect(Collectors.groupingBy(obj -> obj.getProvince())); listMap.forEach((key, value) -> { System.out.println("========"); System.out.println(key); value.forEach(obj -> { System.out.println(obj.getAge()); }); }); class Student { private String province; private int age; public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } public int getAge() { return age; 第5集 Java新特性玩转JDK8之收集器 group by进阶 简介:讲解jdk8⾥⾯的收集器 group by进阶 分组统计 聚合函数进⾏统计查询,分组后统计个数 Collectors.counting() 统计元素个数 需求:统计各个省份的⼈数 } public void setAge(int age) { this.age = age; } public Student(String province, int age) { this.age = age; this.province = province; } } public static <t, k,="" a,="" d=""> Collector<t, ?,="" map<k,="" d="">> groupingBy(Function

classifier,Collector

downstream) { return groupingBy(classifier, HashMap::new, downstream); } List students = Arrays.asList(new Student("⼴东", 23), new Student("⼴东", 24), new Student("⼴东", 23),new Student("北京", 22), new Student("北京", 20), new Student("北京", 20),new Student("海南", 25)); Map<string, long=""> listMap = students.stream().collect(Collectors.groupingBy(Student::getProvince, Collectors.counting())); listMap.forEach((key, value) -> {System.out.println(key+"省⼈数有 "+value);}); 第6集 Java新特性玩转JDK8之summarizing集合统计 简介:讲解jdk8⾥⾯的收集器 group by进阶 summarizing 统计相关, 下⾯是summarizingInt的源码 作⽤:可以⼀个⽅法把统计相关的基本上都完成 分类 summarizingInt summarizingLong summarizingDouble 需求:统计学⽣的各个年龄信息 public static Collector<t, ?,="" intsummarystatistics=""> summarizingInt(ToIntFunction

mapper) { return new CollectorImpl<t, intsummarystatistics,="" intsummarystatistics="">( IntSummaryStatistics::new, (r, t) -> r.accept(mapper.applyAsInt(t)), (l, r) -> { l.combine(r); return l; }, CH_ID); } List students = Arrays.asList(new Student("⼴东", 23), new Student("⼴东", 24), new Student("⼴东", 23),new Student("北京", 22), new Student("北京", 20), new Student("北京", 20),new Student("海南", 25)); IntSummaryStatistics summaryStatistics = students.stream().collect(Collectors.summarizingInt(Student::getAge)); System.out.println("平均值:" + summaryStatistics.getAverage()); System.out.println("⼈数:" + summaryStatistics.getCount()); System.out.println("最⼤值:" + summaryStatistics.getMax()); System.out.println("最⼩值:" + summaryStatistics.getMin()); System.out.println("总和:" + summaryStatistics.getSum()); class Student { private String province; private int age; public String getProvince() { return province; } public void setProvince(String province) { this.province = province; } 愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问官⽹: xdclass.net 第8章 Java⾼级核⼼之玩转 JDK8 Collection和Lambda实战 第1集 Collection和Lambda电商数据处理实战需求说明 简介:综合jdk8新特性,collection和lambda完成数据处理需求整理 需求描述:电商订单数据处理,根据下⾯的list1和list2 各10个订单 统计出同时被两个⼈购买的商品列表(交集) 统计出两个⼈购买商品的差集 统计出全部被购买商品的去重并集 统计两个⼈的分别购买订单的平均价格 public int getAge() { return age; } public void setAge(int age) { this.age = age; } public Student(String province, int age) { this.age = age; this.province = province; } } 统计两个⼈的分别购买订单的总价格 //总价 35 List videoOrders1 = Arrays.asList( new VideoOrder("20190242812", "springboot教程", 3), new VideoOrder("20194350812", "微服务SpringCloud", 5), new VideoOrder("20190814232", "Redis教程", 9), new VideoOrder("20190523812", "⽹⻚开发教程", 9), new VideoOrder("201932324", "百万并发实战Netty", 9)); //总价 54 List videoOrders2 = Arrays.asList( new VideoOrder("2019024285312", "springboot教程", 3), new VideoOrder("2019081453232", "Redis教程", 9), new VideoOrder("20190522338312", "⽹⻚开发教程", 9), new VideoOrder("2019435230812", "Jmeter压⼒测试", 5), new VideoOrder("2019323542411", "Git+Jenkins持续集成", 7), new VideoOrder("2019323542424", "Idea全套教程", 21)); public class VideoOrder { private String tradeNo; private int money; private String title; public VideoOrder(String tradeNo,String title, int money ){ this.tradeNo = tradeNo; this.title = title; this.money = money; } public String getTradeNo() { return tradeNo; } public void setTradeNo(String tradeNo) { this.tradeNo = tradeNo; } public int getMoney() { return money; } public void setMoney(int money) { this.money = money; } 第2集 JDK8新特性处理电商订单数据之答案讲解上集 简介:讲解使⽤jdk8新特性完成订单需求⼀、⼆、三 public String getTitle() { return title; } public void setTitle(String title) { this.title = title; } } @Override public boolean equals(Object obj) { if(obj instanceof VideoOrder) { VideoOrder o1 = (VideoOrder)obj; return title.equals(o1.getTitle()); } return super.equals(obj); } @Override public String toString() { return "VideoOrder{" + "money=" + money + ", title='" + title + '\'' + '}'; } @Override public int hashCode() { return title.hashCode(); } //交集 List intersectionList = videoOrders1.stream().filter(videoOrders2::contains).collect( Collectors.toList()); System.out.println("交集="+intersectionList); //差集1 第3集 JDK8新特性处理电商订单数据之答案讲解下集 简介:讲解使⽤jdk8新特性完成订单需求四、五 List diffList1 = videoOrders1.stream().filter(obj- >!videoOrders2.contains(obj)).collect(Collectors.toList()); System.out.println("差集1="+diffList1); //差集2 List diffList2 = videoOrders2.stream().filter(obj- >!videoOrders1.contains(obj)).collect(Collectors.toList()); System.out.println("差集2="+diffList2); //并集 List allVideoOrder = videoOrders1.parallelStream().collect(Collectors.toList()); allVideoOrder.addAll(videoOrders2); System.out.println("并集 = "+allVideoOrder); //去重并集 List allVideoOrderDistinct = allVideoOrder.stream().distinct().collect(Collectors.toList()); System.out.println("去重并集 = "+allVideoOrderDistinct); //两个订单平均价格 double videoOrderAvg1 = videoOrders1.stream().collect(Collectors.averagingInt(VideoOrder::getMoney)) .doubleValue(); System.out.println("订单列表1平均价格="+videoOrderAvg1); double videoOrderAvg2 = videoOrders2.stream().collect(Collectors.averagingInt(VideoOrder::getMoney)) .doubleValue(); System.out.println("订单列表2平均价格="+videoOrderAvg2); //订单总价 int totalMoney1 = videoOrders1.stream().collect(Collectors.summingInt(VideoOrder::getMoney)).i ntValue(); int totalMoney2 = videoOrders2.stream().collect(Collectors.summingInt(VideoOrder::getMoney)).i ntValue(); System.out.println("订单列表1总价="+totalMoney1); System.out.println("订单列表2总价="+totalMoney2); 愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问官⽹: xdclass.net 第9章 Java⾼级核⼼之玩转 JDK8 新的内存空间和异常处理 第1集 JDK8新特性之新内存空间Matespace 简介:讲解JDK8⾥⾯的新的内存空间MetaSpace JVM 种类有很多,⽐如 Oralce-Sun Hotspot, Oralce JRockit, IBM J9, Taobao JVM,我们讲的是 Hotspot才有,JRockit以及J9是没有这个区域 JVM内存知识 在JDK8之前的HotSpot JVM,有个区域叫做“永久代(permanent generation), 通过 在命令⾏设置参数-XX:MaxPermSize来设定永久代最⼤可分配的内存空间 如果JDK8⾥⾯设置了PermSize 和 MaxPermSize 会被忽略并给出警告 作⽤:该块内存主要是被JVM⽤来存放 class 和 mate 信息的,当 class 被加载 loader 的时候就会 被存储到该内存区中,如⽅法的编译信息及字节码、常量池和符号解析、类的层级信息,字段,名 字等 有⼤项⽬经验的同学对下⾯这个异常应该熟悉 java.lang.OutOfMemoryError: PermGen space 原因是: 永久代空间不够,类太多导致 jdk8的修改 JDK8 HotSpot JVM 使⽤本地内存来存储类元数据信息,叫做 元空间(Metaspace) 在默认情况下Metaspace的⼤⼩只与本地内存⼤⼩有关 常⽤的两个参数 -XX:MetaspaceSize=N 指Metaspace扩容时触发FullGC的初始化阈值 -XX:MaxMetaspaceSize=N 指⽤于限制Metaspace增⻓的上限,防⽌因为某些情况导致 Metaspace⽆限的使⽤本地内存 不管两个参数如何设置,都会从20.8M开始,然后随着类加载越来越多不断扩容调整直到最⼤ 查看⼤⼩ jstat -gc pid MC: current metaspace capacity MU: mateaspace utilization 单位是KB 第2集 JDK7新特性之try-with-resources 简介:讲解JDK7⾥⾯的try-with-resources资源处理 什么是try-with-resources 资源的关闭很多⼈停留在旧的流程上,jdk7新特性就有,但是很多⼈以为是jdk8的 在try( ...)⾥声 明的资源,会在try-catch代码块结束后⾃动关闭掉 旧的 新的 注意点 1、实现了AutoCloseable接⼝的类,在try()⾥声明该类实例的时候,try结束后⾃动调⽤的 close⽅法,这个动作会早于finally⾥调⽤的⽅法 2、不管是否出现异常,try()⾥的实例都会被调⽤close⽅法 public static void main(String[] args) throws IOException { String path = "/Users/jack/Desktop/t.txt"; test(path); } private static void test(String filepath) throws FileNotFoundException { OutputStream out = new FileOutputStream(filepath); try { out.write((filepath+"可以学习java架构课程").getBytes()); } catch (Exception e) { e.printStackTrace(); }finally { try { out.close(); } catch (IOException e) { e.printStackTrace(); } } } private static void test(String filepath){ try(OutputStream out = new FileOutputStream(filepath);) { out.write((filepath+"可以学习java架构课程").getBytes()); } catch (Exception e) { e.printStackTrace(); } } 3、try⾥⾯可以声明多个⾃动关闭的对象,越早声明的对象,会越晚被close掉 愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问官⽹: xdclass.net 第10章 Java⾼级核⼼之玩转JDK9常⻅特性讲解 第1集 新版JDK13下载和本章课程说明 简介:讲解JDK13版本的下载和后续课程说明 为什么⽤JDK13 版本太多,直接⽤最新的进⾏安装讲解 JDK 13的官⽅地址(如果地址过期,则百度搜索,官⽅经常改动) https://www.oracle.com/tech network/java/javase/downloads/index.html 环境变量配置 相关环境变量配置 idea配置各个版本jdK https://blog.csdn.net/blueboz/article/details/81270242 window7配置环境变量 https://www.cnblogs.com/sunzhentian/p/11577154.html window10配置环境变量 https://www.cnblogs.com/huainanhai/p/11592729.html https://www.cnblogs.com/rever/p/7792826.html JDK9~13新增特性很多但不会全部都讲解 会讲解: 常⻅的有利于提⾼开发效率,常⻅API增强 不讲解:不常⽤的API, 或者只是试验性的功能, 如AOT静态编译 第2集 java⾼级核⼼之JDK9常⽤Jshell实战 简介:讲解jdk9新增测试⼯具jshell实战 什么是jshell 从java9开始,jdk引⼊了交互式 REPL(Read-Eval-Print-Loop,读取-求值-输出-循环) 官⽅⽂档 https://docs.oracle.com/en/java/javase/12/jshell/introduction-jshell.html#GUID-63 0F27C8-1195-4989-9F6B-2C51D46F52C8 常⽤命令 帮助命令 /help /help intro 列出输⼊的源 /list 编辑某个源 /edit 删除 /drop 退出jshell命令 解压到指定⽬录 vim .bash_profile JAVA_HOME="/Users/xdclass/Documents/software/jdk13/Contents/Home" /exit 重置 /reset 查看历史编辑 /history ⾃动化补⻬功能 Tab键 第3集 接⼝⽅法进阶之JDK9私有⽅法 简介:讲解jdk9新增的接⼝私有⽅法 什么是jdk9新增的接⼝私有⽅法 JDK8新增了静态⽅法和默认⽅法,但是不⽀持私有⽅法 jdk9中新增了私有⽅法 public interface OrderPay { void pay(); default void defaultPay(){ privateMethod(); } //接⼝的私有⽅法可以在JDK9中使⽤ private void privateMethod(){ System.out.println("调⽤接⼝的私有⽅法"); } } public class OrderPayImpl implements OrderPay { @Override public void pay() { System.out.println("我实现了接⼝"); } } public static void main(String[] args) throws Exception { OrderPay orderPay = new OrderPayImpl(); orderPay.defaultPay(); orderPay.pay(); } 注意点(⾯试题!!!): 接⼝中的静态⽅法不能被实现类继承和⼦接⼝继承,但是接⼝中的⾮静态的默认⽅法可以被 实现类继承 例如List.of() ⽅法,ArrayList虽然继承了List,但是不能⽤ArrayList.of()⽅法 类的静态⽅法可以被继承 第4集 JDK9新特性之增强try-with-resource 简介:讲解jdk9新增的接⼝私有⽅法 什么是try-with-resource 在JDK7中,新增了try-with-resources语句,可以在try后的括号中初始化资源,可以实现资 源⾃动关闭 什么是增强try-with-resource 在JDK9中,改进了try-with-resources语句,在try外进⾏初始化,在括号内引⽤,即可实现 资源⾃动关闭,多个变量则⽤分号进⾏分割 不需要声明资源 out 就可以使⽤它,并得到相同的结果 OutputStream out = new FileOutputStream(filepath); try(OutputStream temp = out;) { temp.write((filepath+"可以学习java架构课程").getBytes()); }catch (Exception e){ e.printStackTrace(); } public static void main(String[] args) throws Exception { String path = "/Users/xdclass/Desktop/t.txt"; test(path); } private static void test(String filepath) throws FileNotFoundException { OutputStream out = new FileOutputStream(filepath); try (out) { out.write((filepath + "可以学习java架构课程").getBytes()); } catch (Exception e) { e.printStackTrace(); } } 愿景:"让编程不在难学,让技术与⽣活更加有趣" 第11章 Java⾼级核⼼之玩转JDK9的Stream和集合API 第1集 JDK9之快速创建只读集合 简介:讲解jdk9⾥⾯新增的集合容器API,快速创建只读集合 什么是只读集合 集合只能读取,不能增加或者删除⾥⾯的元素 JDK9之前创建只读集合 JDK9后创建只读集合 查看of()源码 List list = new ArrayList<>(); list.add("SpringBoot课程"); list.add("架构课程"); list.add("微服务SpringCloud课程"); //设置为只读List集合 list = Collections.unmodifiableList(list); System.out.println(list); Set set = new HashSet<>(); set.add("Mysql教程"); set.add("Linux服务器教程"); set.add("Git教程"); //设置为只读Set集合 set = Collections.unmodifiableSet(set); System.out.println(set); Map<string, string=""> map = new HashMap<>(); map.put("key1", "课程1"); map.put("key2", "课程2"); //设置为只读Map集合 map = Collections.unmodifiableMap(map); System.out.println(map); 第2集 JDK9之新增Stream API讲解 简介:讲解jdk9⾥⾯新增的Stream API JDK8⾥⾯新增的Stream流式编程,⽅便了很多数据的处理 jdk9⾥⾯新增了部分API takeWhile 有序的集合:从 Stream 中获取⼀部分数据, 返回从头开始的尽可能多的元素, 直到遇到第⼀ 个false结果,如果第⼀个值不满⾜断⾔条件,将返回⼀个空的 Stream List list = List.of("SpringBoot课程", "架构课程", "微服务SpringCloud课 程"); System.out.println(list); Set set = Set.of("Mysql教程", "Linux服务器教程", "Git教程"); System.out.println(set); Map<string, string=""> map = Map.of("key1", "课程1", "key2", "课程2"); System.out.println(map); List list = List.of("springboot","java","html","","git").stream().takeWhile(obj- >!obj.isEmpty()).collect(Collectors.toList()); //⽆序集合,返回元素不固定,暂⽆⽆实际使⽤场景 Set set = Set.of("springboot","java","html","","git").stream().takeWhile(obj- >!obj.isEmpty()).collect(Collectors.toList()); dropWhile 与 takeWhile相反,返回剩余的元素,和takeWhile⽅法形成互补 ⽆序Stream⾥⾯也⽆实际使⽤场景 bug ,计划在jdk10⾥⾯进⾏修复 https://bugs.openjdk.java.net/browse/JDK-8193856 愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问官⽹: xdclass.net 第12章 Java⾼级核⼼之玩转JDK10和JDK11常⻅特性 第1集 JDK10之局部变量类型推断var讲解 简介:讲解JDK10新增局部变量类型推断var List list = List.of("springboot","java","html","","git").stream().dropWhile(obj- >!obj.isEmpty()).collect(Collectors.toList()); Java是⼀种强类型, 许多流⾏的编程语⾔都已经⽀持局部变量类型推断,如js,Python,C++等 JDK10 可以使⽤var作为局部变量类型推断标识符 Local-Variable Type Inference(局部变量类型推断),顾名思义只能⽤做为局部变量 注意 仅适⽤于局部变量,如 增强for循环的索引,传统for循环局部变量 不能使⽤于⽅法形参、构造函数形参、⽅法返回类型或任何其他类型的变量声明 标识符var不是关键字,⽽是⼀个保留类型名称,⽽且不⽀持类或接⼝叫var,也不符合命 名规范 可以⽤jshell试验或者IDEA //根据推断为 字符串类型 var strVar = "springboot"; System.out.println(strVar instanceof String); //根据10L 推断long 类型 var longVar = 10L; //根据 true推断 boolean 类型 var flag = true; //var flag = Boolean.valueOf("true"); //System.out.println(flag instanceof Boolean); // 推断 ArrayList var listVar = new ArrayList(); System.out.println(listVar instanceof ArrayList); // 推断 Stream var streamVar = Stream.of("aa", "bb", "cc"); System.out.println(streamVar instanceof Stream); if(flag){ System.out.println("这个是 flag 变量,值为true"); } for (var i = 0; i < 10; i++) { System.out.println(i); } try (var input = new FileInputStream("validation.txt")) { } 第2集 JDK11之新增HttpClient客户端快速⼊⻔ 简介:讲解JDK11新增Http客户端 这个功能在JDK 9中引⼊并在JDK 10中得到了更新 最终JDK11正式发布,⽀持 HTT/1.1, HTTP/2,(JDK10相关课程⾥⾯未讲解该知识点) 官⽅⽂档 http://openjdk.java.net/jeps/321 常⽤类和接⼝讲解 HttpClient.Builder HttpClient 构建⼯具类 HttpRequest.Builder HttpRequest 构建⼯具类 HttpRequest.BodyPublisher 将java 对象转换为可发送的HTTP request body字节流, 如form表单提交 HttpResponse.BodyHandler 处理接收到的 Response Body 创建HttpClient, 下⾯结果是⼀致的底层调⽤ 创建get请求 //var httpClient = HttpClient.newBuilder().build(); var httpClient = HttpClient.newHttpClient(); //private static final String targetUrl = "http://api.xdclass.net/pub/api/v1/web/all_category"; private static final URI uri = URI.create(targetUrl); //GET请求 private static void testGet() { //var httpClient = HttpClient.newHttpClient(); //设置建⽴连接超时 connect timeout var httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofMillis(5000)).build(); //设置读取数据超时 read timeout var request = HttpRequest.newBuilder().timeout(Duration.ofMillis(3000)) .header("key1", "v1") .header("key2", "v2") .uri(uri).build(); try { 第3集 JDK11之标准HttpClient提交Post和异步请求 简介:讲解JDK11新增Http客户端提交post请求和异步请求 使⽤HttpClient提交Post请求 var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); } catch (Exception e) { e.printStackTrace(); } } private static final String targetUrl ="https://api.xdclass.net/pub/api/v1/web/web_login"; private static final URI uri = URI.create(targetUrl); //POST请求 private static void testPost() { var httpClient = HttpClient.newHttpClient(); var request = HttpRequest.newBuilder() .uri(uri) //json格式则使⽤下⾯数据 //.header("Content-Type", "application/json") //.POST(HttpRequest.BodyPublishers.ofString(" {\"phone\":\"13113777337\",\"pwd\":\"1234567890\"}")) //form表单则使⽤下⾯配置 .header("Content-Type", "application/x-www-formurlencoded") .POST(HttpRequest.BodyPublishers.ofString("phone=13113777337&pwd=1234567 890")) .build(); try { var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); } catch (Exception e) { 使⽤HttpClient提交异步GET请求 第4集 JDK11之标准HttpClient提交Http2请求 简介:讲解JDK11新增Http客户端提交http2请求 HTTP2 百科 https://baike.baidu.com/item/HTTP%202.0/12520156?fr=aladdin e.printStackTrace(); } } //异步GET请求 //private static final String targetUrl = "http://api.xdclass.net/pub/api/v1/web/all_category"; private static final URI uri = URI.create(targetUrl); //异步请求通过CompletableFuture实现。 private static void testAsynGet() { var httpClient = HttpClient.newBuilder().build(); var request = HttpRequest.newBuilder().timeout(Duration.ofMillis(3000)) .header("key1", "v1") .header("key2", "v2") .uri(uri).build(); try { //CompletableFuture result = httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenApply(HttpResponse::body); var result = httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString()) .thenApply(HttpResponse::body); System.out.println(result.get()); } catch (Exception e) { e.printStackTrace(); } } HTTP2协议的强制要求https,如果⽬标URI是HTTP的,则⽆法使⽤HTTP 2协议 如何判断⽹站是否是http2协议,浏览器,network⾯板,选择protocol private static final String targetUrl = "https://http2.akamai.com/demo"; private static final URI uri = URI.create(targetUrl); private static void testHttp2() { var httpClient = HttpClient.newBuilder() .connectTimeout(Duration.ofMillis(3000)) .version(HttpClient.Version.HTTP_2) .build(); var request = HttpRequest.newBuilder() .timeout(Duration.ofMillis(3000)) .header("key1", "v1") .header("key2", "v2") .uri(uri) .build(); try { var response = httpClient.send(request, HttpResponse.BodyHandlers.ofString()); System.out.println(response.body()); System.out.println(response.version()); } catch (Exception e) { e.printStackTrace(); } } 第5集 JDK11之javac和java命令优化 简介:讲解java编译运⾏命令在jdk11中的改善 jdk11前运⾏java程序 编译 javac xxx.java 运⾏ java xxx jdk11后运⾏java程序(本地不会⽣成class⽂件) java xxxx.java 愿景:"让编程不在难学,让技术与⽣活更加有趣" 更多架构课程请访问官⽹: xdclass.net 第13章 Java⾼级核⼼之⼤话JDK12和JDK13 第1集 ⼤话JDK各个版本常⻅问题讲解 简介:讲解JDK⼀些基础知识科普 OpenJDK和OracleJDK版本区别 public class Main { public static void main(String[] args) throws Exception { String text = "xdclass.net"; //String类新增repeat(int num) ⽅法,⽤于字符串循环输出 System.out.println(text.repeat(2)); } } OpenJDK是JDK的开放源码版本,以GPL协议的形式发布(General Public License) Oracle JDK采⽤了商业实现 LTS 是啥意思? Long Term Support ⻓期⽀持的版本,如JDK8、JDK11都是属于LTS JDK9 和 JDK10 这两个被称为“功能性的版本”不同, 两者均只提供半年的技术⽀持 甲⻣⽂释出Java的政策,每6个⽉会有⼀个版本的释出,⻓期⽀持版本每三年发布⼀次,根据 后续的发布计划,下⼀个⻓期⽀持版 Java 17 将于2021年发布 8u20、11u20是啥意思? 就是Java的补丁,⽐如JDK8的 8u20版本、8u60版本; java11的 11u20、11u40版本 JDK要收费了???? 问题的产⽣由来 Oracle 宣布 Java8 在 2019 年 1⽉之后停⽌更新,另外 Java11 及以后版本将不再提供免 费的 long-term support (LTS) ⽀持,猜测未来将有越来越多 Java 开发者转向使⽤ OpenJDK OpenJDK是免费的,想要不断体验新特性的developer来说是不错的选择 OracleJDK不是免费的,对于企业⽤户来说,有钱的情况下就选择OracleJDK 对应oracleJDK ,我们可以⾃⼰⽤来写代码,调试,学习即可 第2集 玩转JDK13新特性之多⾏⽂本块 简介:讲解JDk13⾥⾯新增的多⾏⽂本块 JDK13发布,主要更新点 https://openjdk.java.net/projects/jdk/13/ https://www.oracle.com/technetwork/java/javase/13-relnote-issues-5460548.html#New Feature JEP全称 :JDK Enhancement Proposal 特性增强提议 多⾏⽂本块 旧:在java代码⾥⾯编写多⾏源码带有特殊字符则需要转义,如HTML,sql等 新:原⽣字符串⽂字(raw string literals),它可以跨多⾏源码⽽不对转义字符进⾏转义 旧: String html = "\n" + " \n" + "

Hello, world

\n" + " \n" + "\n"; String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" + "WHERE `CITY` = 'INDIANAPOLIS'\n" + "ORDER BY `EMP_ID`, `LAST_NAME`;\n"; 新: String html = """

Hello, world

开启新版⽀持 jshell --enable-preview """; String query = """ SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB` WHERE `CITY` = 'INDIANAPOLIS' ORDER BY `EMP_ID`, `LAST_NAME`; """; 对⽐⼀ """ line 1 line 2 line 3 """ 等效于字符串⽂字: "line 1\nline 2\nline 3\n" 对⽐⼆ """ line 1 line 2 line 3""" 等效于字符串⽂字: "line 1\nline 2\nline 3" 对⽐三 ⽂本块可以表示空字符串,但不建议这样做,因为它需要两⾏代码: String empty = """ """; 注意:错误例⼦ String a = """"""; // no line terminator after opening delimiter String b = """ """; // no line terminator after opening delimiter String c = """ "; 第3集 玩转JDK13新特性之增强switch表达式 简介:讲解JDk13⾥⾯优化了switch表达式 旧:没有break,则匹配的case后⾯会⼀直输出, value类型 可以是 byte、short、int 、char、 String 类型 新:使⽤箭头函数,不⽤声明break,会⾃动终⽌,⽀持多个值匹配,使⽤逗号分隔 public void testOldSwitch1(){ int i = 1; switch(i){ case 0: System.out.println("zero"); case 1: System.out.println("one"); case 2: System.out.println("two"); default: System.out.println("default"); } } public void testOldSwitch2(int i){ switch(i){ case 0: System.out.println("zero"); break; case 1: System.out.println("one"); break; case 2: System.out.println("two"); break; default: System.out.println("default"); } } 更多架构课程请访问官⽹: xdclass.net 第14章 Java⾼级核⼼之JDK8~13课程总结 第1集 玩转JDK8~13新特性课程总结和学习路线规划 简介:JDK8~13课程总结和学习路线规划 回顾课程⼤纲 多关注LTS版本如JDK8,JDK11,JDK17(未发布),这个是重点需要学的;功能性的则挑选常⽤的 特性进⾏掌握即可; 预览性的可以先不学或者简单知道就⾏,例如 AOT,ZGC,CDS 这些,未来的LTS版本中会更 新,所以可以关注未来的LTS版本 学习建议 看视频+记笔记+加实操+官⽅⽂档 后端主流技术栈学习 已有的路线图 ⾼级⼯程师路线图 public void testNewSwitch(int i){ switch(i){ case 0 -> { System.out.println("zero"); System.out.println("这是多⾏语句"); } case 1,11,111 -> System.out.println("one"); case 2 -> System.out.println("two"); default -> System.out.println("default"); } } ⼩滴课堂,愿景:让编程不在难学,让技术与⽣活更加有趣 相信我们,这个是可以让你学习更加轻松的平台,⾥⾯的课程绝对会让你技术不断提升 欢迎加⼩D讲师的微信: jack794666918 我们官⽅⽹站:https://xdclass.net 千⼈IT技术交流QQ群: 718617859 重点来啦:免费赠送你⼲货⽂档⼤集合,包含前端,后端,测试,⼤数据,运维主流技术⽂档(持续更 新) https://mp.weixin.qq.com/s/qYnjcDYGFDQorWmSfE7lpQ

猜你喜欢

转载自www.cnblogs.com/yuefeng123/p/12153478.html
今日推荐