JAVA11 新特性(var,集合新的api,stream新的api,字符串处理,http操作。。。)

745 阅读5分钟

上班啦

jshell 工具

一个java的控制台工具,效果类似与浏览器的控制台,能够直接编写测试代码片段

C:\Program Files\Java\jdk-11\bin\jshell.exe

Dynamic Class-File Constants类文件新添的一种结构

局部变量类型推断(var ”关键字”)

什么是局部变量类型推断?

var javastack = "javastack";
// => String javastack = "javastack";
System.out.printin(iavastack);

大家看出来了,局部变量类型推断就是左边的类型直接使用 var 定义,而不用具体的类型,编译器能根据右边的表达式自动推断类型,如上面的 String

在声明隐式类型的 lambda 表达式的形参时允许使用 var

使用 var 的好处是在使用 lambda 表达式时给参数加上注解

// 错误的形式:必须要有类型,可以加上var
// error: Consumer<String> consumer = (@Deprecated t) -> System.out.println(t.toUpperCase());
// 正确的形式:
Consumer<String> consumer = (@Deprecated var t) -> System.out.println(t.toUpperCase());

注意点:

  • var a; 这样不可以,因为无法推断
  • 类的属性的数据类型不可以使用 var

集合中新的 API

List.of(E...e)

Set.of(E...e)

// 快速生成不可变的 list,set 集合
List<Integer> list = List.of(1, 2, 3, 4, 5);
// set 中如果有重复的元素,程序运行的时候就会报错,而不是自动去除重复元素
Set<Integer> set = Set.of(1, 2, 3, 4 /*,1*/);

通过 of() 生成的集合,是不可变的,实际使用的是 ImmutableCollections.class 中的内部类

// 摘抄内部类,对list 修改的方法实现
static UnsupportedOperationException uoe() { return new UnsupportedOperationException(); }

@Override public void    add(int index, E element) { throw uoe(); }
@Override public boolean addAll(int index, Collection<? extends E> c) { throw uoe(); }
@Override public E       remove(int index) { throw uoe(); }
@Override public void    replaceAll(UnaryOperator<E> operator) { throw uoe(); }
@Override public E       set(int index, E element) { throw uoe(); }
@Override public void    sort(Comparator<? super E> c) { throw uoe(); }

和 Arrays.asList(E...e) 的区别

Arrays.asList 实际返回对象 class java.util.Arrays$ArrayList,对象声明后,还是可以调用 set(int, E) 更新元素

Stream 中新的 API

Stream.ofNullable(T)

用于处理生成流的元素可能为空的情况

    public static<T> Stream<T> ofNullable(T t) {
        return t == null ? Stream.empty()
                         : StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
    }

Stream.takeWhile(Predicate<? super T>)

传入一个判断表达式,在遍历流对象时使用,返回前面连续的判断条件为 true 的所有元素

类似与 Stream.filter(Predicate<? super T>),遍历元素过滤

Stream.of(1, 3, 2, 4, 5).takeWhile(x -> x % 2 == 1).forEach(System.out::println);
// 判断为奇数
// output: 	1, 3

Stream.dropWhile(Predicate<? super T>)

丢弃前面连续的判断为 true 的所有元素,返回剩下的元素

Stream.of(1, 3, 2, 4, 5).dropWhile(x -> x % 2 == 1).forEach(System.out::println);
// 判断为奇数
// output: 	2, 4, 5

.iterate()

iterate(final T, final UnaryOperator )

缺点,这是一个无限流,容易出现出乎意料的错误,一般需要和 .limit(int) 配置使用,截取前面 n 个元素

iterate(T, Predicate<? super T>, UnaryOperator)

添加了一个条件判断表达式,生成的元素经过判断表达式处理后如果返回为 false 就停止流迭代

新增的字符处理方法

去除空格

String string = " \t \r\n ";
System.out.println(string.isBlank());//判断字符串中的字符是否都是空白
System.out.println("************************");
string = "\t\r\nabc\t";
String string2 = string.strip();//去重字符串首尾的空白.包括英文和其他所有语言中的空白字符
System.out.println(string2);
System.out.println(string2.length());
String string3 = string.trim();//去重字符串首尾的空白字符,只能去除码值小于等于32的空白字符
System.out.println(string3);
System.out.println(string3.length());
System.out.println("************************");
String string4 = string.stripLeading();//去重字符串首部的空白
System.out.println(string4);
System.out.println(string4.length());
String string5 = string.stripTrailing();//去重字符串尾部的空白
System.out.println(string5);
System.out.println(string5.length());

其他

String str = "123";
str.repeat(3); // 将当前字符串重复 n 次
// -----------------------
String text = "123\nabc\nqwe";
Stream<String> stream = text.lines(); // 将字符串根据换行符,生成一个字符串形式的流

Optional 提供新的方法

// 判断为空
// since 11
isEmpty()
// 如果值不为空,就使用消费方法;否则,调用线程的 run()
// since 9
ifPresentOrElse(Consumer<? super T>, Runnable)
// 如果值为空,就调用 supplier 去获取一个 Optional<T>
// since 9
or(Supplier<? extends Optional<? extends T>>)

IO 提供简化、快速的文件拷贝

String path = "C:\\eclipse\\2020-06\\workspace\\demo\\src\\main\\java\\com\\example\\demo\\PublishSubscriber.java";
try (var in = new FileInputStream(path);
		var out = new FileOutputStream("D:/test.java")) {
	in.transferTo(out);
	System.out.println("copy file finish...");
} catch (Exception e) {
	e.printStackTrace();
}

Http 客户端 API

String url = "http://localhost:8080/user";
HttpClient client = HttpClient.newHttpClient();
BodyPublisher bodyPublisher = BodyPublishers.ofString("try to post some string");
Builder builder = HttpRequest.newBuilder(URI.create(url));
// builder.GET() // builder.DELETE() // ....
HttpRequest request = builder.POST(bodyPublisher).build();
BodyHandler<String> bodyHandler = BodyHandlers.ofString();
// client.sendAsync(request, responseBodyHandler),异步的http 请求
HttpResponse<String> response = client.send(request, bodyHandler);
String body = response.body();
System.out.println(body);

更简化的编译方式

# 定义一个java类,然后在cmd 中直接使用,文件需要带 .java 后缀
java test.java
# 注意点
# 所有引用的文件都需要写在一个 .java 文件中,默认使用第一个类的 main() 作为入口调用函数

新增垃圾收集器

Epsilon

开发一个处理内存分配但不实现任何实际内存回收机制的GC, 一旦可用堆内存用完,JVM就会退出。

-XX:+UnlockExperimentalVMOptions
-XX:+UseEpsilonGC

用途

  • 性能测试(它可以帮助过滤掉 GC引起的性能假象)
  • 内存压力测试(例如,知道测试用例 应该分配不超过1GB的内存, 我们可以使用-Xmx1g –XX:+UseEpsilonGC, 如果程序有问题, 则程序会崩溃)
  • 非常短的JOB任务(对象这种任务, 接受GC清理堆那都是浪费空间)
  • VM接口测试
  • Last-drop 延迟&吞吐改进

ZGC

-XX:+UnlockExperimentalVMOptions
-XX:+UseZGC
  • GC暂停时间不会超过10ms
  • 既能处理几百兆的小堆, 也能处理几个T的大堆(OMG)
  • 和G1相比, 应用吞吐能力不会下降超过15%
  • 为未来的GC功能和利用colord指针以及Load barriers优化奠定基础
  • 初始只支持64位系统

飞行记录仪

开源使用