自從Java9開始,JDK裏面爲集合(List/Set/Map)都添加了of和copyOf方法,他們能夠來建立不可變的集合。html
不能對集合進行添加、刪除、替換、排序等操做,不然會報java.lang.UnsupportedOperationException錯誤。 示例代碼:java
List<String> list = List.of("aa", "bb", "cc"); list.add("dd");
報錯信息:數組
Exception in thread "main" java.lang.UnsupportedOperationException at java.base/java.util.ImmutableCollections.uoe(ImmutableCollections.java:71) at java.base/java.util.ImmutableCollections$AbstractImmutableCollection.add(ImmutableCollections.java:75)
**擴展:**Arrays.asList()建立的集合也是一個不可變的集合ide
示例代碼:優化
var list1 = List.of("aa", "bb", "cc"); var copy1 = List.copyOf(list1); System.out.println(list1 == copy1); //運行結果: true var list2 = new ArrayList<String>(); var copy2 = List.copyOf(list2); System.out.println(list2 == copy2); //運行結果: false
注意:var也是Java11新推出的特性局部變量類型推斷,這裏面再也不贅述。ui
第一段代碼和第二段代碼差很少,爲何返回結果不同呢?咱們來看一下他們的源碼:this
static <E> List<E> of(E e1, E e2, E e3) { return new ImmutableCollections.ListN<>(e1, e2, e3); } static final class ListN<E> extends AbstractImmutableList<E> implements Serializable { static final List<?> EMPTY_LIST = new ListN<>(); @Stable private final E[] elements; @SafeVarargs ListN(E... input) { // copy and check manually to avoid TOCTOU @SuppressWarnings("unchecked") E[] tmp = (E[])new Object[input.length]; // implicit nullcheck of input for (int i = 0; i < input.length; i++) { tmp[i] = Objects.requireNonNull(input[i]); } elements = tmp; } @Override public boolean isEmpty() { return size() == 0; } @Override public int size() { return elements.length; } @Override public E get(int index) { return elements[index]; } private void readObject(ObjectInputStream in) throws IOException, ClassNotFoundException { throw new InvalidObjectException("not serial proxy"); } private Object writeReplace() { return new CollSer(CollSer.IMM_LIST, elements); } }
static <E> List<E> copyOf(Collection<? extends E> coll) { return ImmutableCollections.listCopy(coll); } static <E> List<E> listCopy(Collection<? extends E> coll) { if (coll instanceof AbstractImmutableList && coll.getClass() != SubList.class) { return (List<E>)coll; } else { return (List<E>)List.of(coll.toArray()); } }
從源碼能夠看出,copyOf 方法會先判斷來源集合是否是 AbstractImmutableList 類型的,若是是,就直接返回,若是不是,則調用 of 建立一個新的集合。第二段代碼由於用的 new 建立的集合,不屬於不可變 AbstractImmutableList 類的子類,因此 copyOf 方法又建立了一個新的實例,因此爲false。spa
**擴展:**使用Set.of()方法建立Set對象時,不能夠包含重複數據。指針
Stream是Java8的新特性,我以前的博客對其進行了詳細的介紹:Java8新特性 - Stream API。Java9開始對Stream新增了4個新方法。code
在Java8,新建一個值爲null的Stream,會報錯java.lang.NullPointerException錯誤。 示例代碼:
Stream stream = Stream.of(null);
錯誤:
Exception in thread "main" java.lang.NullPointerException at java.util.Arrays.stream(Arrays.java:5004) at java.util.stream.Stream.of(Stream.java:1000)
查看Stream.of()源碼
@SafeVarargs @SuppressWarnings("varargs") // Creating a stream from an array is safe public static<T> Stream<T> of(T... values) { return Arrays.stream(values); } public static <T> Stream<T> stream(T[] array) { return stream(array, 0, array.length); }
能夠看見傳入null會被解析爲時一個數組對象,會進一步訪問它的長度信息,致使了NullPointerException異常。
在Java11中,新增了ofNullable方法,能夠傳入null。由於沒法推斷類型,因此返回的值爲Object,示例代碼以下:
Stream stream = Stream.ofNullable(null); stream.forEach(System.out::println);
從源碼中能夠看出,當傳入的是一個null時,返回的是一個空的對象。
public static<T> Stream<T> ofNullable(T t) { return t == null ? Stream.empty() : StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false); }
首先來看一段示例代碼:
Stream<Integer> stream = Stream.of(3, 6, 9, 12, 15); stream.takeWhile(n -> n % 2 != 0) .forEach(System.out::println);
第一次看這段代碼,可能第一印象就是找出流中的奇數打印出來,可是實際輸出爲:
3
因此takeWhile方法在計算到n % 2 == 0的時候就終止了,takeWhile方法的做用是:從流中一直獲取斷定器爲真的元素,一旦遇到元素爲假,就終止處理!
與上面takeWhile同樣的代碼:
Stream<Integer> stream = Stream.of(3, 6, 9, 12, 15); stream.dropWhile(n -> n % 2 != 0) .forEach(System.out::println);
返回的結果爲:
6 9 12 15
結果正好與takeWhile相反,dropWhile方法的做用爲:只要斷定器爲真,就一直丟棄元素,直到爲假,取爲假後的全部元素!
流的迭代,主要用於建立流,在指定初值的狀況下,通過處理,而後將處理過的值做爲初值,不斷迭代。因此iterate建立的是一個無限流。 示例代碼:
Stream.iterate(1, t -> 2 * t + 1) .limit(10) .forEach(System.out::println);
無限流有一個問題,在數值溢出以後,會一直重複-1的值。Java11進行了優化,以讓你提供一個 Predicate (判斷條件)來指定何時結束迭代,進行有限的迭代,示例代碼以下:
Stream.iterate(1, t -> t< 1000, t -> 2 * t + 1) .forEach(System.out::println);
示例代碼:
String s1 = " \t \r\n"; System.out.println(s1.isBlank()); // true
示例代碼:
String s2 = " \t 123\r\n".strip(); System.out.println(s2); // 123
trim()大部分狀況下效果等同於strip(),可是trim()只能去除碼值小於等於32的空白字符,不能去除中文狀況下的空白字符,strip()能夠去除全部語言中的空白
示例代碼:
String s2 = " \t 123\r\n"; System.out.println(s2.strip().length()); // 3 // 去除首部的空白 System.out.println(s2.stripLeading().length()); // 5 // 去除尾部的空白 System.out.println(s2.stripTrailing().length()); // 10
String s3 = "作一個好人"; System.out.println(s3.repeat(3)); // 作一個好人作一個好人作一個好人
String s2 = " \t 123\r\n123"; System.out.println(s2.lines().count()); //2
s2.lines()獲取的是一個流,將字符串根據換行符切割轉換爲Stream
Optional是Java中引進的容器類,主要用於避免空指針異常,我以前的博客對其進行了詳細的介紹:[Java8新特性 - Optional容器類](https://www.cnblogs.com/fx-blog/p/11747058.html"Java8新特性 - Optional容器類")。Java11中Opthonal 也增長了幾個很是酷的方法。
參照前面Stream加強的介紹,使用Optional.of(T value);傳入的參數是null時,會拋出空指針異常,因此Java11中新增了ofNullable,能夠兼容空指針,可是實際傳入null後要當心,不能用get接收,最好利用orElse方法接收,示例代碼以下。
Optional<String> optional = Optional.ofNullable(null); // 若是內部引用爲空,則返回參數中引用,不然返回內部引用 System.out.println(optional.orElse("作一個好人")); // 作一個好人
也能夠使用orElseThrow()方法接收,直接在**orElseThrow()**時拋出異常。
Optional<String> optional = Optional.ofNullable(null); System.out.println(optional.orElseThrow());
錯誤以下: Exception in thread "main" java.util.NoSuchElementException: No value present at java.base/java.util.Optional.orElseThrow(Optional.java:382)
源碼以下:
public T orElseThrow() { if (value == null) { throw new NoSuchElementException("No value present"); } return value; }
也能夠使用or()方法接收,當一個空 Optional 時給它一個替代的Optional,示例代碼以下:
Optional<String> optional = Optional.ofNullable(null); System.out.println(optional.or(() -> Optional.of("作一個好人!")) .get()); // 作一個好人!
Java11中新增了transferTo方法,把輸入流中的全部數據直接自動地複製到輸出流中,這是在處理原始數據流時很是實用的一種用法,不用寫循環,也不須要緩衝區,示例代碼以下:
public void test() throws Exception { var classLoader = this.getClass().getClassLoader(); var inputStream = classLoader.getResourceAsStream("file"); try (var outputStream = new FileOutputStream("file2")) { inputStream.transferTo(outputStream); } inputStream.close(); }
原文出處:https://www.cnblogs.com/fx-blog/p/11755560.html