阅读本文大概需要 22.8 分钟。
某次面试中,面试官问到我这个问题,只勉强说出了 JDK 8 的部分特性,今天就来盘一盘!
画外音:JDK 8 就是 JDK 1.8 版本的意思,后续同理。
/*** jdk8中接口可以使用声明default和static修饰的方法* static修饰的方法和普通的方法一样,可以被直接调用* default修饰的方法有方法体,就和普通的方法一样,可以被重写,有点像抽象类的方法一样,但是java是单继承多实现的*/public interface Today {void dream();void striver();default void victory(){System.out.println("公众号:程序员的成长之路");}static void test(){System.out.println("接口里的静态方法");}// jdk9 中还新增了private方法private void test3() {System.out.println("私有方法");};}
BASE64Encoder encoder = new BASE64Encoder();BASE64Decoder decoder = new BASE64Decoder();byte[] textByte = "公众号:程序员的成长之路".getBytes("UTF-8");//编码String encodedText = encoder.encode(textByte);//5Zyj6a2U5a+85biI(类似这样的)System.out.println(encodedText);//解码//公众号:程序员的成长之路System.out.println(new String(decoder.decodeBuffer(encodedText),"UTF-8"));
Base64.Decoder decoder2 = Base64.getDecoder();Base64.Encoder encoder2 = Base64.getEncoder();byte[] textByte2 = "公众号:程序员的成长之路".getBytes("UTF-8");//编码String encodedText2 = encoder2.encodeToString(textByte2);//5Zyj6a2U5a+85biI(类似这样的)System.out.println(encodedText);//解码//公众号:程序员的成长之路System.out.println(new String(decoder2.decode(encodedText2), "UTF-8"));
LocalTime localTime = LocalTime.now();// 现在时间:18:00:49.476System.out.println("现在时间:"+localTime);
import java.util.Optional;public class Java8Tester {public static void main(String args[]){Java8Tester java8Tester = new Java8Tester();Integer value1 = null;Integer value2 = new Integer(10);// Optional.ofNullable - 允许传递为 null 参数Optional<Integer> a = Optional.ofNullable(value1);// Optional.of - 如果传递的参数是 null,抛出异常 NullPointerExceptionOptional<Integer> b = Optional.of(value2);System.out.println(java8Tester.sum(a,b));}public Integer sum(Optional<Integer> a, Optional<Integer> b){// Optional.isPresent - 判断值是否存在System.out.println("第一个参数值存在: " + a.isPresent());System.out.println("第二个参数值存在: " + b.isPresent());// Optional.orElse - 如果值存在,返回它,否则返回默认值Integer value1 = a.orElse(new Integer(0));//Optional.get - 获取值,值需要存在Integer value2 = b.get();return value1 + value2;}}
第一个参数值存在: false第二个参数值存在: true10
Demo demo = Demo::new;
Demo::静态方法();
Demo::方法名();
demo::方法名();
面向对象编程是对数据的抽象(各种各样的POJO类);
函数式编程则是对行为的抽象(将行为作为一个参数进行传递);
所谓的函数编程,即可理解是将一个函数(也称为“行为”)作为⼀个参数进行传递。
================== 自定义函数是编程(1) ====================/*** 像Runnable接口一样用FunctionalInterface注解修饰* 加了这个注解后,接口里面必须有且只能有一个方法*/public interface Test1<R,T>{// R表示返回值,T表示参数类型,t1 t2是具体参数R operator(T t1, T t2);}public class Compute {/*** 定义一个函数方法* 需要传入a和b两个参数,* 后面的Test1<Integer,Integer> of就是传入的一个函数(行为),of是随便起的一个别名*/public static Integer operator(Integer a,Integer b,Test1<Integer,Integer> of){return of.operator(a,b);}}public class Main {public static void main(String[] args) throws Exception {System.out.println(Compute.operator(2,3,(a,b)-> a+b));System.out.println(Compute.operator(2,3,(a,b)-> a-b));System.out.println(Compute.operator(2,3,(a,b)-> a*b));System.out.println(Compute.operator(2,3,(a,b)-> a/b));}}================== 自定义函数是编程(2) ====================public interface Test2{void test();}public class Main {public static void main(String[] args) throws Exception {Main.casesc(()-> System.out.println("函数式编程案例二"));}public static void casesc(Test2 t){t.test();}}
Lambda表达式,使⽤场景:接口中只能有一个方法;
比如Runnable接口里的run方法;Comparator接口里的compareTo方法;
Lambda 表达式的实现方式在本质是以匿名内部类的方式进行实现的。
public static void main(String[] args) throws Exception {new Thread(new Runnable() {public void run() {System.out.println("jdk8以前创建线程");}});//()对应run()没有一个参数,->后面是方法体内容//如果{}中的代码只有⼀行,⽆论有返回值,可以省略{}、return、分号,其他则需要加上new Thread(()-> System.out.println("lambda表达式创建线程"));List<String> list = Arrays.asList("a","c","d","b","e");// jdk8以前排序Collections.sort(list, new Comparator<String>() {public int compare(String o1, String o2) {return o2.compareTo(o1);}});// lambda表达式排序//,前面的对应接口前面的参数,a b 对应compare里面的参数Collections.sort(list,(a,b)->b.compareTo(a));}
public class Main {public static void main(String[] args) throws Exception {Consumer<String> c1 = obj->System.out.println(obj+": 调⽤用短信接⼝口发送短信,或者打印⽇日志");c1.accept("订单id—001");Consumer<List> c2 = obj->{if(obj==null || obj.size()<1)return;obj.forEach(o-> System.out.println(o));};List<Integer> list = Arrays.asList(2,4,,8,9,7);c2.accept(list);}}
public class Main {public static void main(String[] args) throws Exception {Student student = newStudent();System.out.println(student);}public static Student newStudent(){Supplier<Student> supplier = ()-> {Student student = new Student();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;}@Overridepublic String toString() {return "Student{" +"name='" + name + '\'' +'}';}}
Function:只能接受一个参数用法一(用一个类实现接口里面的逻辑,然后直接调用)public class FunctionObj implements Function {public Object apply(Object o) {return "对参数:"+o+"经过处理后返回结果";}}public class Main {public static void main(String[] args) throws Exception {System.out.println(test("hello",new FunctionObj()));}public static String test(String a ,FunctionObj functionObj){return functionObj.apply(a).toString();}}用法二(左边规定好参数和返回值类型,右边写方法体具体逻辑)public class Main {public static void main(String[] args) throws Exception {Function<Integer,Integer> func = p->{return p*100;};System.out.println(func.apply(12));Function<Integer,Boolean> function = a->a<100;System.out.println(function.apply(97));}}=================================================================BiFunctionObj:能接受两个参数// 用法一public class BiFunctionObj implements BiFunction {public Object apply(Object o, Object o2) {return (Integer.valueOf(o.toString())+Integer.valueOf(o2.toString()));}}public class Main {public static void main(String[] args) throws Exception {System.out.println(test(2,5,new BiFunctionObj()));}public static Integer test(Integer a,Integer b, BiFunctionObj func){return Integer.valueOf(func.apply(a,b).toString());}}// 用法二public class Main {public static void main(String[] args) throws Exception {BiFunction<Integer, Integer,Boolean> func1 = (a,b)->{return a>b;};System.out.println(func1.apply(1,5));BiFunction<String, String,String> func2 = (a,b)->a+b;System.out.println(func2.apply("hellow","world"));}}
public class Main {public static void main(String[] args) throws Exception {Predicate<Integer> predicate = a->a>10;List<Integer> list = Arrays.asList(1,54,9,34,3);for(Integer l : list){if(predicate.test(l)) System.out.println(l);}}}
数据元素便是原始集合:如List、Set、Map等
生成流:可以是串行流stream() 或者并行流 parallelStream()
中间操作:可以是 排序,聚合,过滤,转换等
终端操作:统一收集返回一个流
public class Main {public static void main(String[] args) {List<String> list = Arrays.asList("张麻子","李蛋","王二狗","Angell");List<Student> users = Arrays.asList(new Student("张三", 23),new Student("赵四", 24),new Student("二狗", 23),new Student("田七", 22),new Student("皮特", 20),new Student("Tony", 20),new Student("二柱子", 25));/*** map:对集合的每个对象做处理*/List<String> collect = list.stream().map(obj->"哈哈"+obj).collect(Collectors.toList());list.forEach(obj->System.out.println(obj));System.out.println("----------------");collect.forEach(obj->System.out.println(obj));/*** filter:boolean判断,用于条件过滤*/System.out.println("----------------");Set<String> set = list.stream().filter(obj->obj.length()>2).collect(Collectors.toSet());set.forEach(obj->System.out.println(obj));/*** sorted:对流进行自然排序*/System.out.println("----------------");Set<String> sorteds = list.stream().sorted().collect(Collectors.toSet());sorteds.forEach(obj->System.out.println(obj));// 自定义排序规则// 根据长度排序(正序)System.out.println("----------------");List<String> resultList = list.stream().sorted(Comparator.comparing(obj -> obj.length())).collect(Collectors.toList());resultList.forEach(obj->System.out.println(obj));System.out.println("----------------");// 根据长度排序(倒序)List<String> resultList2 = list.stream().sorted(Comparator.comparing(obj -> obj.length(),Comparator.reverseOrder())).collect(Collectors.toList());resultList2.forEach(obj->System.out.println(obj));System.out.println("----------------");// 手动指定排序规则(根据年龄大小排序)List<Student> collect2 = users.stream().sorted(Comparator.comparing(Student::getAge,(x,y)->{if(x>y) {return 1;}else {return -1;}})).collect(Collectors.toList());collect2.forEach(obj->System.out.println(obj.getAge()+" : "+obj.getProvince()));/*** limit:截取包含指定数量的元素*/System.out.println("----------------");List<String> collect3 = list.stream().limit(2).collect(Collectors.toList());collect3.forEach(obj->System.out.println(obj));/*** allMatch:匹配所有元素,只有全部符合才返回true*/System.out.println("----------------");boolean flag = list.stream().allMatch(obj->obj.length()>2);System.out.println(flag);System.out.println("----------------");/*** anyMatch:匹配所有元素,至少一个元素满足就为true*/boolean flag2 = list.stream().anyMatch(obj->obj.length()>2);System.out.println(flag2);System.out.println("----------------");/*** max和min:最大值和最小值*/Optional<Student> max = users.stream().max(Comparator.comparingInt(Student::getAge));System.out.println(max.get().getAge()+" : "+max.get().getProvince());System.out.println("----------------");Optional<Student> min = users.stream().min((s1, s2)->Integer.compare(s1.getAge(),s2.getAge()));System.out.println(min.get().getAge()+" : "+min.get().getProvince());/*** reduce:对Stream中的元素进行计算后返回一个唯一的值*/// 计算所有值的累加int value = Stream.of(1, 2, 3, 4, 5).reduce((item1, item2) -> item1 + item2).get();// 100作为初始值,然后累加所有值int value2 =Stream.of(1, 2, 3, 4, 5).reduce(100, (sum, item) -> sum + item);// 找出最大值int value3 =Stream.of(1, 4, 5, 2, 3).reduce((x,y)->x>y?x:y).get();System.out.println(value);System.out.println(value2);System.out.println(value3);}}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;}public void setAge(int age) {this.age = age;}public Student(String province, int age) {this.age = age;this.province = province;}}
/*** 数据结构收集:Collectors*/public class Main {public static void main(String[] args) throws Exception {List<String> data = Arrays.asList("张三","王五","李四");List<String> list = data.stream().collect(Collectors.toList());Set<String> set = data.stream().collect(Collectors.toSet());LinkedList<String> linkedList = data.stream().collect(Collectors.toCollection(LinkedList::new));System.out.println(list);System.out.println(set);System.out.println(linkedList);/*Collectors.toMap()Collectors.toSet()Collectors.toCollection() :⽤用⾃自定义的实现Collection的数据结构收集Collectors.toCollection(LinkedList::new)Collectors.toCollection(CopyOnWriteArrayList::new)Collectors.toCollection(TreeSet::new)*/}}//============================================================/*** 拼接函数:joining*/public class Main {public static void main(String[] args) throws Exception {List<String> list = Arrays.asList("springBoot","springCloud","netty");String result1 = list.stream().collect(Collectors.joining());String result2 = list.stream().collect(Collectors.joining("——"));String result3 = list.stream().collect(Collectors.joining("—", "【",""));String result4 = Stream.of("hello", "world").collect(Collectors.joining("—", "【", "】"));System.out.println(result1);System.out.println(result2);System.out.println(result3);System.out.println(result4);}}//============================================================/*** 分组:partitioningBy*/public class Main {public static void main(String[] args) throws Exception {List<String> list = Arrays.asList("sdfsdf","xxxx","bbb","bbb");Map<Boolean, List<String>> collect = list.stream().collect(Collectors.partitioningBy(obj -> obj.length() > 3));System.out.println(collect);}}//============================================================/*** 分组:group by* 统计:counting*/public class Main {public static void main(String[] args) throws Exception {List<Student> 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());});});System.out.println("~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~");// 根据名称分组,并统计每个分组的个数Map<String, Long> map = students.stream().collect(Collectors.groupingBy(Student::getProvince, Collectors.counting()));map.forEach((key,value)->{System.out.println(key+"省人数有"+value);});}}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;}public void setAge(int age) {this.age = age;}public Student(String province, int age) {this.age = age;this.province = province;}}//============================================================/*** 统计函数:summarizing*/public class Main {public static void main(String[] args) throws Exception {List<Student> students = Arrays.asList( new Student("⼴东", 23),new Student("⼴东", 24),new Student("⼴东", 23),new Student("北京", 22),new Student("北京", 20),new Student("北京", 20),new Student("海南", 25));// summarizingInt;summarizingLong;summarizingDoubleIntSummaryStatistics 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());}}/*** reduce:对Stream中的元素进行计算后返回一个唯一的值*/// 计算所有值的累加int value = Stream.of(1, 2, 3, 4, 5).reduce((item1, item2) -> item1 + item2).get();// 100作为初始值,然后累加所有值int value2 =Stream.of(1, 2, 3, 4, 5).reduce(100, (sum, item) -> sum + item);// 找出最大值int value3 =Stream.of(1, 4, 5, 2, 3).reduce((x,y)->x>y?x:y).get();System.out.println(value);System.out.println(value2);System.out.println(value3);
import java.io.FileOutputStream;import java.io.IOException;import java.io.OutputStream;public class Main {public static void main(String[] args) throws Exception {String path = "/Users/jack/Desktop/t.txt";/*** jdk 1.7以前关闭资源一般是在finally里面操作的*/OutputStream out = new FileOutputStream(path);try {out.write(("公众号:程序员的成长之路").getBytes());} catch (Exception e) {e.printStackTrace();}finally {try {out.close();} catch (IOException e) {e.printStackTrace();}}/*** jdk1.7的时候,可以在try()里声明资源,会在try-catch代码块结束后自动关闭掉。* try结束后自动调用的close方法,这个动作会早于finally里调用的方法* bu管是否出现异常,try()里的实例都会被调用close方法* try里面可以声明多个自动关闭的对象,越早声明的对象,会越晚被close掉*/try (OutputStream out2 = new FileOutputStream(path);){out2.write(("公众号:程序员的成长之路").getBytes());} catch (Exception e) {e.printStackTrace();}/*** jdk1.9之后,对try()做了改进,在try外进行初始化,在括号内引用*/OutputStream out3 = new FileOutputStream(path);try (out3) {out3.write(("公众号:程序员的成长之路").getBytes());} catch (Exception e) {e.printStackTrace();}}}
public class Main {/*** jdk9中的Stream流新增了两个api*/public static void main(String[] args) throws Exception {/*** takeWhile:遍历每个对象,直到遇到第⼀个false时,返回前面所有元素,如果没有false,将返回⼀一个空的 Stream*/List<String> list1 = List.of("springboot","java","html","","git").stream().takeWhile(obj->!obj.isEmpty()).collect(Collectors.toList());System.out.println(list1);/*** dropWhile:与takeWhile相反*/List<String> list2 = List.of("springboot","java","html","","git").stream().dropWhile(obj->!obj.isEmpty()).collect(Collectors.toList());System.out.println(list2);}}
public class Main {public static void main(String[] args) throws Exception {/*** JDK9之前创建只读集合*/List<String> list = new ArrayList<String>();list.add("张三");list.add("李四");list.add("王五");list.remove();System.out.println(list);//设置为只读List集合// unmodifiableMap(map); unmodifiableMap(set);list = Collections.unmodifiableList(list);// 报错:java.lang.UnsupportedOperationException//list.remove(0);System.out.println(list);/*** jdk9创建只读集合*/List<String> list2 = List.of("mysql", "linux", "redis");list2.remove();System.out.println(list2);}}
public class Main {// var作为局部变量类型推断标识符public static void main(String[] args) throws Exception {var strVar = "springboot";System.out.println(strVar instanceof String);//根据10L 推断long 类型var longVar = Long.valueOf(10l);System.out.println(longVar instanceof Long);//根据 true推断 boolean 类型var flag = Boolean.valueOf("true");System.out.println(flag instanceof Boolean);// 推断 ArrayList<String>var listVar = new ArrayList<String>();System.out.println(listVar instanceof ArrayList);// 推断 Stream<String>var streamVar = Stream.of("aa", "bb", "cc");System.out.println(streamVar instanceof Stream);if(flag){System.out.println("这个是 flag 变量,值为true");}for (var i = ; i < 10; i++) {System.out.println(i);}try (var input = new FileInputStream("validation.txt")) {}}}
import java.net.URI;import java.net.http.HttpClient;import java.net.http.HttpRequest;import java.net.http.HttpResponse;import java.time.Duration;import java.util.concurrent.CompletableFuture;/*** 这个功能在JDK9中引入,在JDK10中得到了更新,在JDK11才发布*/public class Main {private static final URI uri = URI.create("https://www.cnblogs.com/wlwl/");public static void main(String[] args) {testHttp2();}/*** get请求*/private static void testGet() {// 创建连接两种方式:var httpClient = HttpClient.newHttpClient();var httpClient = HttpClient.newBuilder().connectTimeout(Duration.ofMillis(5000)).build();// 封装请求参数(默认get请求)HttpRequest request = HttpRequest.newBuilder().timeout(Duration.ofMillis(3000)).header("key1", "v1").uri(uri).build();try {var response = httpClient.send(request,HttpResponse.BodyHandlers.ofString());System.out.println(response.body());} catch (Exception e) {e.printStackTrace();}}/*** post请求*/private static void testPost() {HttpClient httpClient = HttpClient.newHttpClient();HttpRequest request = HttpRequest.newBuilder().uri(uri).POST(HttpRequest.BodyPublishers.ofString("phone=13113777337&pwd=1234567890"))// from表单要用下面格式发送//.header("Content-Type", "application/json")//.POST(HttpRequest.BodyPublishers.ofString("{\"phone\":\"13113777337\",\"pwd\":\"1234567890\"}")).build();try {var response = httpClient.send(request,HttpResponse.BodyHandlers.ofString());System.out.println(response.body());} catch (Exception e) {e.printStackTrace();}}/*** 异步GET请求*/private static void testAsynGet() {var httpClient = HttpClient.newBuilder().build();var request =HttpRequest.newBuilder().timeout(Duration.ofMillis(3000)).header("key1", "v1").uri(uri).build();try {// 异步请求通过CompletableFuture实现CompletableFuture<String> result = httpClient.sendAsync(request, HttpResponse.BodyHandlers.ofString()).thenApply(HttpResponse::body);System.out.println(result.get());} catch (Exception e) {e.printStackTrace();}}/*** 发送http2请求* HTTP2协议的强制要求https,如果目标URI是HTTP的,则无法使用HTTP 2协议*/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").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();}}}


public class Main {public static void main(String[] args) {testOldSwitch1();}/*** 旧:没有break,则匹配的case后⾯面会⼀一直输出*/public static void testOldSwitch1(){int i = 1;switch(i){case :System.out.println("zero");//break;case 1:System.out.println("one");//break;case 2:System.out.println("two");//break;default:System.out.println("default");}}/*** 新:使用箭头函数,不用声明break,会自动终止,支持多个值匹配,使用逗号分隔*/public void testNewSwitch(int i){switch(i){case -> {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");}}}
public class Main {public static void main(String[] args) {/*** 旧:在java代码里面编写多行源码带有特殊字符则需要转义,如HTML,sql等*/String html = "<html>\n" +"<body>\n" +"<p>Hello, world</p>\n" +"</body>\n" +"</html>\n";String query = "SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`\n" +"WHERE `CITY` = 'INDIANAPOLIS'\n" +"ORDER BY `EMP_ID`, `LAST_NAME`;\n";/*** 新:不用对转义字符进行转义*/String html2 = """"<html><body><p>Hello, world</p></body></html>""";String query = """SELECT `EMP_ID`, `LAST_NAME` FROM `EMPLOYEE_TB`WHERE `CITY` = 'INDIANAPOLIS'ORDER BY `EMP_ID`, `LAST_NAME`;""";}}

<END>
推荐阅读:
IntelliJ IDEA 2020.1 稳定版发布

微信扫描二维码,关注我的公众号
朕已阅 
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/69902700/viewspace-3120347/ ,如需转载,请注明出处,否则将追究法律责任。