java11开箱简评
最近刚好有一点时间,看到java都快更新到14了。不过主流的稳定版本还是java11,因此还是用java11来做一个简单的开箱测试吧。
首先是下载,以下是下载路径,我选择的是zip文件。
jdk11的下载路径:https://www.oracle.com/java/technologies/javase-jdk11-downloads.html
然后就是简单的解压文件,在intelliJ里面引入即可使用。
接下来就是参考https://juejin.im/post/5dc0e1caf265da4d47042543#heading-19该文章,进行对java11的一些新特性进行测试。
新特性:
1.新增var关键字,自动推断变量类型
public static void varTest(){ // 自动推断name为String类型 var name = "bestlmc"; var number = 1000000; System.out.println(name); System.out.println(number); }
测试结果:
bestlmc
1000000
Process finished with exit code 0
for循环也可以使用:
public static void forTest(){ var upList1 = List.of( "鸣人", "佐助", "小樱" ); var upList2 = List.of( "自来也", "大蛇丸", "纲手" ); var upList3 = List.of( "弥彦", "长门", "小南" ); var upListAll = List.of( upList1, upList2, upList3 ); // 用var接受局部变量的确非常简洁! for( var i : upListAll ) { for( var j : i ) { System.out.println(j); } } }
测试结果:
鸣人
佐助
小樱
自来也
大蛇丸
纲手
弥彦
长门
小南
Process finished with exit code 0
2.字符串加强
从Java 9开始 String 数据承载由 char[] 改为 byte[] 紧凑的字符串,在很多时候只包含Latin-1里的字符,这些字符可节省一半内存。
public static void test(){ String testStr = " bestlmc "; "A\nB\nC".lines().count(); // 3 System.out.println(" ".isBlank()); // 打印:true System.out.println(" ".isEmpty()); // 打印:false System.out.println(testStr.strip()); // 前后空格均移除 System.out.println(testStr.stripLeading()); // 仅头部空格移除 System.out.println(testStr.stripTrailing()); // 仅尾部空格移除 System.out.println(testStr.repeat(2)); // 复制字符串 bestlmc bestlmc System.out.println("A\nB\nC".lines().count()); // 行数统计 3 }
测试结果:
true
false
bestlmc
bestlmc
bestlmc
bestlmc bestlmc
3
Process finished with exit code 0
3.集合加强
public static void test(){ var upList = List.of( "鸣人", "佐助", "小樱" ); var upListCopy = List.copyOf( upList ); System.out.println(upList); // 打印 [鸣人, 佐助, 小樱] System.out.println(upListCopy); // 打印 [鸣人, 佐助, 小樱] var upSet = Set.of("鸣人","佐助"); var upSetCopy = Set.copyOf( upSet ); System.out.println(upSet); // 打印 [佐助, 鸣人] System.out.println(upSetCopy); // 打印 [佐助, 鸣人] var upMap = Map.of("鸣人","下忍","佐助","下忍"); var upMapCopy = Map.copyOf( upMap ); System.out.println(upMap); // 打印 {鸣人=下忍, 佐助=下忍} System.out.println(upMapCopy); // 打印 {鸣人=下忍, 佐助=下忍} }
测试结果:
[鸣人, 佐助, 小樱]
[鸣人, 佐助, 小樱]
[佐助, 鸣人]
[佐助, 鸣人]
{鸣人=下忍, 佐助=下忍}
{鸣人=下忍, 佐助=下忍}
Process finished with exit code 0
注意:使用 of 和 copyOf 创建的集合为不可变集合,不能进行添加、删除、替换、排序等操作,不然会报java.lang.UnsupportedOperationException异常,使用Set.of()不能出现重复元素、Map.of()不能出现重复key,否则会报java.lang.IllegalArgumentException。
4.stream增强
Stream是Java 8 中的特性,在Java 9 中为其新增了4个方法
ofNullable(T t):此方法可以接收null来创建一个空流
public static void nullTest(){
// 以前
// Stream.of(null); //报错
// 现在
Stream.ofNullable(null);
}
takeWhile(Predicate<? super T> predicate)
此方法根据Predicate接口来判断如果为true就 取出 来生成一个新的流,只要碰到false就终止,不管后边的元素是否符合条件。
dropWhile(Predicate<? super T> predicate)
此方法根据Predicate接口来判断如果为true就 丢弃 来生成一个新的流,只要碰到false就终止,不管后边的元素是否符合条件。
public static void streamTest(){ var upList = List.of( "鸣人", "佐助", "小樱" ); // 从集合中依次删除满足条件的元素,直到不满足条件为止 var upListSub1 = upList.stream() .dropWhile( item -> item.equals("鸣人") ) .collect( Collectors.toList() ); System.out.println(upListSub1); // 打印 [佐助, 小樱] // 从集合中依次获取满足条件的元素,知道不满足条件为止 var upListSub2 = upList.stream() .takeWhile( item -> item.equals("鸣人") ) .collect( Collectors.toList() ); System.out.println( upListSub2 ); // 打印 [鸣人] }
测试结果:
[佐助, 小樱]
[鸣人]
Process finished with exit code 0
iterate重载
public static void iterateTest(){ // 以前使用iterate方法生成无限流需要配合limit进行截断 Stream<Integer> limit = Stream.iterate(1, i -> i + 1).limit(5); limit.forEach(System.out::print); //1,2,3,4,5 System.out.println(); // 复制代码现在重载后这个方法增加了个判断参数 Stream<Integer> iterate = Stream.iterate(6, i -> i <= 10, i -> i + 1); iterate.forEach(System.out::print); //6,7,8,9,10 }
测试结果:
12345
678910
Process finished with exit code 0
5.Optional增强
stream()
如果为空返回一个空流,如果不为空将Optional的值转成一个流。
public static void streamTest(){ //返回Optional值的流 Stream<String> stream = Optional.of("Java 11").stream(); stream.forEach(System.out::println); // Java 11 //返回空流 Stream<Object> streamBf = Optional.ofNullable(null).stream(); streamBf.forEach(System.out::println); // }
测试结果:
Java 11
Process finished with exit code 0
ifPresentOrElse(Consumer<? super T> action, Runnable emptyAction)
ifPresentOrElse 方法的用途是,如果一个 Optional 包含值,则对其包含的值调用函数 action,即 action.accept(value),这与 ifPresent 一致;与 ifPresent 方法的区别在于,ifPresentOrElse 还有第二个参数 emptyAction —— 如果 Optional 不包含值,那么 ifPresentOrElse 便会调用 emptyAction,即 emptyAction.run()。
public static void ifPresentOrElseTest(){ Optional<Integer> optional = Optional.of(1); optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() -> System.out.println("Not Present.")); //Value: 1 optional = Optional.empty(); optional.ifPresentOrElse( x -> System.out.println("Value: " + x),() -> System.out.println("Not Present.")); //Not Present. }
测试结果:
Value: 1
Not Present.
Process finished with exit code 0
or(Supplier<? extends Optional<? extends T>> supplier)
不是很懂这个是干啥的,但大概意思应该是有值就输出改值,否则输出提示信息。
public static void orTest(){ Optional<String> optional1 = Optional.of("Java"); Supplier<Optional<String>> supplierString = () -> Optional.of("Not Present"); optional1 = optional1.or( supplierString); optional1.ifPresent( x -> System.out.println("Value: " + x)); //Value: Java optional1 = Optional.empty(); optional1 = optional1.or( supplierString); optional1.ifPresent( x -> System.out.println("Value: " + x)); //Value: Not Present }
6.文件读写增强
Files类增强
Files类的静态方法writeString()和readString(),把文件内容读取到String以及String回写到文:
public static void filesTest() throws IOException { Path path = Paths.get("D:/test.txt"); Files.writeString( path, "刺客五六七", StandardCharsets.UTF_8 ); String content = Files.readString(path, StandardCharsets.UTF_8); System.out.println(content); }
测试结果:
刺客五六七
Process finished with exit code 0
InputStream增强
InputStream则增加了一个transferTo()方法,直接将数据丢到OutputStream去:
public static void transferToTest(){ try { InputStream inputStream = new FileInputStream("D:/test.txt"); OutputStream outputStream = new FileOutputStream("D:/test2.txt"); inputStream.transferTo(outputStream); } catch (Exception e){ e.printStackTrace(); } }
7.HTTP Client
JDK官方就自带HTTP Client了,位于java.net.http包下,支持发送同步、异步的HTTP
同步
public static void visitWeb() throws IOException, InterruptedException { var request = HttpRequest.newBuilder() .uri( URI.create("https://www.baidu.com/") ) .GET() .build(); // 同步请求方式,拿到结果前会阻塞当前线程 var httpResponse = HttpClient.newHttpClient() .send( request, HttpResponse.BodyHandlers.ofString()); System.out.println( httpResponse.body() ); // 打印获取到的网页内容 }
异步
public static void asynchronous() throws ExecutionException, InterruptedException { var request = HttpRequest.newBuilder() .uri( URI.create("https://www.baidu.com/") ) .GET() .build(); CompletableFuture<String> future = HttpClient.newHttpClient(). sendAsync( request, HttpResponse.BodyHandlers.ofString() ) .thenApply( HttpResponse::body ); System.out.println("我先继续干点别的事情..."); System.out.println( future.get() ); // 打印获取到的网页内容 }
携带JWT Token权限信息去请求
public static void jwtToken() throws IOException, InterruptedException { var requestWithAuth = HttpRequest.newBuilder() .uri( URI.create("https://www.baidu.com/") ) .header("Authorization", "Bearer xxxxxxxxxxxxxx") .GET() .build(); var response = HttpClient.newHttpClient() .send( requestWithAuth, HttpResponse.BodyHandlers.ofString() ); System.out.println( response.body() ); // 打印获取到的接口返回内容 }
8.直接运行java文件(这个没测。。)
以前要运行一个.java文件,首先要javac编译成.class文件,然后在java执行:
//编译
javac Java11.java
//运行
java Java11
复制代码在java11中,只需要通过java一个命令就可以搞定
java Java11.java
结语:总体而言,java11新增的功能都是比较实用的,用起来也挺不错。虽说现在一般的项目里都用不上,但是多学一点东西还是有用的。说不定哪天就用上了。其实java8和java11还有着很多的不同,后面有空再做一期关于jdk版本的总结吧。