本文列举了从Java8到11各个变化的API:
变量
从Java 10开始,开发人员可以选择让编译器使用var来推断类型:
var x=1.0/2.0
var list = new ArrayList<String>();
var stream = list.stream();
// Type inference can be (Java 8)
Function helloFunction = s -> "Hello " + s;
// Inference of generics (Diamond Operator, since Java 7)
List strings = new ArrayList<>();
strings.add(helloFunction.apply("World"));
// Inference of generics (Diamond Operator) with anonymous inner classes (Java 9 -> JEP 213)
Consumer printer = new Consumer<>() {
@Override
public void accept(String string) {
System.out.println(string);
}
};
strings.forEach(printer::accept);
Java11已经提高了lambda中的var能力:
IntFunction<Integer> doubleIt1 = (int x) -> x * 2; // OK Java 10 and 11
IntFunction<Integer> doubleIt2 = (var x) -> x * 2; // OK Java 11
更复杂案例:
/ /Inference of parameters in Lambda expressions
Consumer<String> printer = (var s) -> System.out.println(s); // statt s -> System.out.println(s);
// But no mixture of "var" and declarated types possible
// BiConsumer<String, String> printer = (var s1, String s2) -> System.out.println(s1 + " " + s2);
// Useful for type annotations
BiConsumer<String, String> printer = (@Nonnull var s1, @Nullable var s2) -> System.out.println(s1 + (s2 == null ? "" : " " + s2));
// given
Optional<String> value = Optional.of("properValue");
AtomicInteger successCounter = new AtomicInteger(0);
AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0);
// when
value.ifPresentOrElse(
v -> successCounter.incrementAndGet(),
onEmptyOptionalCounter::incrementAndGet);
String新方法
java 8加入新方法join:
Set<String> set1 = Set.of("a","b", "c");
List<String> list1 = List.of("a","b", "c");
System.out.println( String.join("a", "b", "c") );
System.out.println( String.join(".", set1) );
System.out.println( String.join(".", list1) );
Java9 有了一个返回Stream的新方法
Java11 添加了更多String的新方法:
String.repeat(int)
String.lines()
String.strip()
String.stripLeading()
String.stripTrailing()
String.isBlank()
接口
java8:
- 常量Constant variables
- 抽象方法Abstract methods
- 默认方法Default methods
- 静态方法Static methods
Java9:
- Constant variables
- Abstract methods
- Default methods
- Static methods
- 私有方法Private methods
- 私有静态方法Private Static methods
Java11:
看一个接口的完整代码:
//generic interface with one type parameter T
interface SomeInterface<T> {
int SOME_CONSTANT = 35; // variable declaration
int abstractMethod(int x, int y); // method declaration
T abstractMethodUsingGenericType(T[] array, int i); // method using type parameter
default int defaultMethod(int x, int y) {
// implementation of method
return 0;
}
static void main(String[] args) {
// any static method, including main can be included in interface
}
private void privateMethod(String[] args) {
// any private method can be included in interface
}
private static void staticMethod(String[] args) {
// any private static method can be included in interface
}
// nested class definition
class NestedClass {
// members of a class
}
// nested interface definition
interface NestedInterface {
// member of an interface
}
// nested enum definition
enum NestedEnum {
OBJECT1,
OBJECT2,
;
// methods, variables and constructors
}
// nested annotation definition
@interface NestedAnnotation {
String attrib1();
}
}
Nullable管理
java8引入了新的Optional。
// return an optional empty object
Optional<String> optional = Optional.empty();
// return an optional with value object
String str = "value";
Optional<String> optional = Optional.of(str);
// return an optional with or without value
Optional<String> optional = Optional.ofNullable(getString());
// how to solve String version = computer?.getSoundcard()?.getUSB()?.getVersion() ?: "UNKNOWN";
// with map
String version = computer.flatMap(Computer::getSoundcard)
.flatMap(Soundcard::getUSB)
.map(USB::getVersion)
.orElse("UNKNOWN");
//list
List<String> list = getList();
List<String> listOpt = list != null ? list : new ArrayList<>();
// is equivalent to
List<String> listOpt = getList().orElseGet(() -> new ArrayList<>());
java9中可以返回另外一个Optional ,使用增强方法ifPresentOrElse :
String defaultString = "default";
Optional<String> value = Optional.empty();
Optional<String> defaultValue = Optional.of(defaultString);
// when
Optional<String> result = value.or(() -> defaultValue);
// given
Optional<String> value = Optional.of("properValue");
AtomicInteger successCounter = new AtomicInteger(0);
AtomicInteger onEmptyOptionalCounter = new AtomicInteger(0);
// when
value.ifPresentOrElse(
v -> successCounter.incrementAndGet(),
onEmptyOptionalCounter::incrementAndGet);
也增加了stream方法。
Java10中有新的方法叫:orElseThrow
Java11中代码如下:
Optional.of(string).isEmpty()
Stream
Java8 引入了新的Stream:
// starting from list
List<String> myList =
Arrays.asList("a1", "a2", "b1", "c2", "c1");
myList
.stream()
.filter(s -> s.startsWith("c"))
.map(String::toUpperCase)
.sorted()
.forEach(System.out::println);
// native stream
Stream.of("a1", "a2", "a3")
.findFirst()
.ifPresent(System.out::println);
可以和number和map一起运行:
// working with number
IntStream.range(1, 4)
.forEach(System.out::println);
// working with map
Arrays.Stream(new int[] {1, 2, 3})
.map(n -> 2 * n + 1)
.average()
.ifPresent(System.out::println);
流提供者可以多次重用流Stream,从而避免了集合中臭名昭著的错误:
java.lang.IllegalStateException: stream has already been operated upon or closed
Supplier<Stream<String>> streamSupplier =
() -> Stream.of("d2", "a2", "b1", "b3", "c")
.filter(s -> s.startsWith("a"));
streamSupplier.get().anyMatch(s -> true); // ok
streamSupplier.get().noneMatch(s -> true); // ok
收集器可以转换到几种List:
List<Person> filtered =
persons
.stream()
.filter(p -> p.name.startsWith("P"))
.collect(Collectors.toList());
使用flatmap管理nullability
Outer outer = new Outer();
if (outer != null && outer.nested != null && outer.nested.inner != null) {
System.out.println(outer.nested.inner.foo);
}
// similar to类似上面代码的新写法
Optional.of(new Outer())
.flatMap(o -> Optional.ofNullable(o.nested))
.flatMap(n -> Optional.ofNullable(n.inner))
.flatMap(i -> Optional.ofNullable(i.foo))
.ifPresent(System.out::println);
Java9中引入了iterate 和 takeWhile/dropWhile方法:
Stream.iterate(0, i -> i < 10, i -> i + 1) .forEach(System.out::println);
System.out.println("stream take while");
Stream<String> stream1 = Stream.iterate("", s -> s + "s")
.takeWhile(s -> s.length() < 10);
stream1.forEach(System.out::println);
Java11引入了Not谓词,以前代码:
lines.stream()
.filter(s -> !s.isBlank())
现在可以是:
lines.stream()
.filter(Predicate.not(String::isBlank))
响应式Stream
Java9 引入了java.util.concurrent.Flow的四个接口:
- Flow.Processor
- Flow.Publisher
- Flow.Subscriber
- Flow.Subscription
还有不可变集合:
// empty immutable collections
List<String> emptyImmutableList = List.of();
Set<String> emptyImmutableSet = Set.of();
Map emptyImmutableMap = Map.of();
// immutable collections
List<String> immutableList = List.of("one", "two");
Set<String> immutableSet = Set.of("value1", "value2");
Map<String, String> immutableMap = Map.of("key1", "Value1", "key2", "Value2", "key3", "Value3");
Java9引入了MultiResolutionImage和提高了Process API
Java10提高了通过List.copyOf(), Set.copyOf(), Map.copyOf()创建不可变集合能力,Collectors类有了新方法toUnmodifiableList, toUnmodifiableSet, toUnmodifiableMap.
新语法
Java 9 try-with-resource现在支持内部可自定义:
try (new MyAutoCloseable() { }.finalWrapper.finalCloseable) {
// do some stuff with finalCloseable
} catch (Exception ex) { }
Java 9还支持带有菱形运算符的匿名类:
List list = new ArrayList<>(){ };
Java 9支持支持HTTP / 2和websockets的新HTTP客户端API。
Java 11改善了HTTP客户端API支撑
int numLetters = switch (day) {
case MONDAY, FRIDAY, SUNDAY -> 6;
case TUESDAY -> 7;
case THURSDAY, SATURDAY -> 8;
case WEDNESDAY -> 9;
};
Lambdas
Java8中已经引入了Lambda语法:s -> do(s)
为了支持Lambda,引入了5个接口:Consumer, Function, Supplier, Predicate, Operator
在Iterable & Stream & Optional上增加了几个方法:
- forEach
- filter
- map
- flatMap
- collect
- …
Java 11提高了Lambda的var推断能力
Deprecated
Java 9 short list
- java.activation
- java.corba
- java.se.ee
- java.transaction
- java.xml.bind
- java.xml.ws
- java.xml.ws.annotation
- jdk.policytool
Java 11 short list
Java EE packages removed
- javax.activation (java.activation)
- javax.activity, javax.rmi, javax.rmi.CORBA, org.omg.* (java.corba)
- javax.transaction (java.transaction)
- javax.xml.bind.* (java.xml.bind)
- javax.jws, javax.jws.soap, javax.xml.soap,
- javax.xml.ws.*(java.xml.ws)
- javax.annotation (java.xml.ws.annotation)
日志
Java9提供了日志级别和作用域:
java -Xlog:all=debug:file=application.log -version
写在最后:
看到最后了,那就点个关注呗,只收藏不点关注的都是在耍流氓!
关注并私信我“架构”,免费送一套Java架构资料,先到先得!