從 java 8到 java 11變化一覽

banq發表於2018-12-03

本文列舉了從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:

  1. 常量Constant variables
  2. 抽象方法Abstract methods
  3. 預設方法Default methods
  4. 靜態方法Static methods

Java9:
  1. Constant variables
  2. Abstract methods
  3. Default methods
  4. Static methods
  5. 私有方法Private methods
  6. 私有靜態方法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<String> 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 (https://docs.oracle.com/javase/9/docs/api/deprecated-list.html)

  1. java.activation
  2. java.corba
  3. java.se.ee
  4. java.transaction
  5. java.xml.bind
  6. java.xml.ws
  7. java.xml.ws.annotation
  8. 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

Annotations

Java 8

  • @FunctionalInterface : to specify an interface "for lambda" purpose

Java 9
has improved the following annotations

  • @SafeVarargs : it improves now private methods
  • @Deprecated : it provide the scope of deprecation (JSCOR-GUID-BB859EA8-E6F7-4239-9A52-4F1BDE27BB09>https://docs.oracle.com/javase/9/core/enhanced-deprecation1.htmJSCOR-GUID-BB859EA8-E6F7-4239-9A52-4F1BDE27BB09)

相關文章