Java工具類簡介
- 定義: 工具類是對String吼拥,Collection,IO等基礎(chǔ)、常用功能的封裝诲锹、擴展
- 目的: 為開發(fā)者提供便利繁仁,減少重復(fù)代碼
- 優(yōu)勢: 更快、更好归园、更容易
CompletableFuture
- 包: java.util.concurrent
- 作用: 構(gòu)建異步應(yīng)用黄虱,實現(xiàn)異步調(diào)用
- 優(yōu)勢: 簡化異步編程的復(fù)雜性,提供了函數(shù)式編程的能力
CompletableFuture的使用
- 構(gòu)造CompletableFuture對象
runAsync方法庸诱,不支持返回值
supplyAsync方法捻浦,支持返回值
-
返回計算結(jié)果
get方法,拋出具體的異常
join拋出具體的異常
例子如下:
CompletableFuture<Void> future1 = CompletableFuture.runAsync(() -> { for (int i = 0; i < 5000; i ++) { System.out.println("future1: " + i); } }); CompletableFuture<Void> future2 = CompletableFuture.runAsync(() -> { for (int i = 0; i < 5000; i ++) { System.out.println("future2: " + i); } }); CompletableFuture<Void> future3 = CompletableFuture.runAsync(() -> { for (int i = 0; i < 5000; i ++) { System.out.println("future3: " + i); } }); try { future1.get(); future2.get(); future3.get(); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
輸出如下:
-
上一階段的處理完成后的下一階段處理
-
thenApply方法桥爽,接收上一階段的處理結(jié)果朱灿,處理后返回
CompletableFuture<String> future = CompletableFuture.supplyAsync(() -> "hello") .thenApply(str -> str + " world!"); try { System.out.println(future.get()); } catch (InterruptedException | ExecutionException e) { e.printStackTrace(); }
輸出:
-
hello world聚谁!
-
thenAccept方法母剥,接收上一階段的處理結(jié)果,處理后無返回
CompletableFuture.supplyAsync(() -> "hello").thenAccept(System.out::println);
輸出:
hello
-
thenRun方法形导,不接收上一階段處理結(jié)果,只進行后續(xù)操作
CompletableFuture.supplyAsync(() -> "hello").thenRun(() -> System.out.println("then run"));
輸出:
then run
-
計算完成后的結(jié)果處理或拋出異常的處理
-
whenComplete方法
CompletableFuture.supplyAsync(() -> "hello") .whenComplete((s, throwable) -> System.out.println(s));
輸出: hello
-
Stream
包:java.util.stream
作用:集合數(shù)據(jù)處理
stream() ? 為集合創(chuàng)建串行流习霹。
parallelStream() ? 為集合創(chuàng)建并行流朵耕。
-
優(yōu)勢: 寫出高效率、干凈淋叶、簡潔的代碼
遍歷一個數(shù)組統(tǒng)計1的數(shù)目的兩種方式對比如下:
// 構(gòu)造數(shù)組 List<Integer> numbers = Stream.of(1,2,3,5,1,2,1,1,5).collect(Collectors.toList()); // 遍歷 int count = 0; for (Integer num : numbers) { if (num == 1) { count ++; } } System.out.println(count); // stream long count1 = numbers.stream().filter(num -> num == 1).count(); System.out.println(count1);
Stream的特點
- stream不會存儲元素,遍歷完一次就等于消費完了阎曹;
- stream只會操作數(shù)據(jù),不會改變數(shù)據(jù);
- stream采用的是內(nèi)部迭代,訪問者模式(Visitor)實現(xiàn)煞檩;
- stream中間操作都會返回流對象本身,多個操作串聯(lián)成一個管道,流式風(fēng)格,都是懶加載的,只有用到結(jié)果的時候才會去執(zhí)行
Stream的操作
Stream和集合的相互轉(zhuǎn)化
stream -> 集合 (.collect)
-
集合 -> stream (.stream或.parallelStream)
// 生成stream Stream<Integer> stream = Stream.of(1,2,3,5,1,2,1,1,5); // stream -> 集合 List<Integer> numbers = stream.collect(Collectors.toList()); // 集合 -> stream Stream<Integer> streamFromList = numbers.stream(); Stream<Integer> parallelStreamFromList = numbers.parallelStream();
中間的操作(對流的操作)
filter(Predicate p)处嫌,在流中篩選一些符合要求的元素
distinct(),在流中利用hashCode和equals方法去除相同的元素
-
limit(long maxSize)斟湃,在流中數(shù)據(jù)達到最大值時截斷流
List<Integer> numbers = Stream.of(1,2,3,5,1,2,1,1,5).collect(Collectors.toList()); numbers = numbers.stream().filter(num -> num <= 4) .distinct().limit(3).collect(Collectors.toList()); System.out.println(numbers);
輸出:
[1, 2, 3]
skip(long n)熏迹,丟棄掉流中的前n個元素
-
map(Function function),接受一個函數(shù)入?yún)?用在每個元素上,并將其結(jié)果映射成一個新的元素
-
flatMap(Function function)凝赛,接受一個函數(shù)入?yún)?該函數(shù)會用在每個元素上,并將流中每個元素?fù)Q到另一個流中.然后將所有的流連在一起.
sorted()方法注暗,按照自然規(guī)則排序
-
sorted(Comparator comparator)方法,按照給定的規(guī)則排序
List<Integer> numbers = Stream.of(1,2,3,5,1,2,1,1,5).collect(Collectors.toList()); // skip List<Integer> numbersSkipped = numbers.stream().skip(3).collect(Collectors.toList()); // 打印出的結(jié)果為: [5, 1, 2, 1, 1, 5] System.out.println(numbersSkipped); // map List<Integer> numbersMapped = numbers.stream().map(i -> i + 1).collect(Collectors.toList()); // 打印出的結(jié)果為: [2, 3, 4, 6, 2, 3, 2, 2, 6] System.out.println(numbersMapped); // flatMap List<String> strings = Stream.of("A-A-A", "B-B-B").collect(Collectors.toList()); List<String> stringsFlatMapped = strings.stream() .flatMap(i -> Arrays.stream(i.split("-"))).collect(Collectors.toList()); // 打印出的結(jié)果為: [A, A, A, B, B, B] System.out.println(stringsFlatMapped); // sorted List<Integer> numbersSorted = numbers.stream().sorted().collect(Collectors.toList()); // 打印出的結(jié)果為: [1, 1, 1, 1, 2, 2, 3, 5, 5] System.out.println(numbersSorted); // sorted(Comparator comparator) numbersSorted = numbers.stream() .sorted(Comparator.comparing(Integer::intValue).reversed()).collect(Collectors.toList()); // 打印出的結(jié)果為: [5, 5, 3, 2, 2, 1, 1, 1, 1] System.out.println(numbersSorted);
終止操作(操作后獲得結(jié)果)
count()墓猎,返回該流存在的元素個數(shù)
findFirst()捆昏,返回該流中第一個元素,返回值為Optional類型
findAny()毙沾,返回流中任意一個元素骗卜,返回值為Optional類型
allMatch(Predicate predicate),返回流中所有的元素是否滿足Predicate條件
anyMatch(Predicate predicate),是否有
noneMatch(Predicate predicate)寇仓,是否都不滿足
max(Comparator comparator)举户,返回流中Comparator比較后的最大值
min(Comparator comparator),返回流中Comparator比較后的最小值
forEach(Consumer consumer)焚刺,對流中所有的元素進行迭代操作(內(nèi)部迭代),并行執(zhí)行
-
forEachOrdered(Consumer consumer),對流中所有的元素進行迭代操作(內(nèi)部迭代),順序執(zhí)行
List<Integer> numbers = Stream.of(1,2,3,5,1,2,1,1,5).collect(Collectors.toList()); // 打印出的結(jié)果為: 9 System.out.println(numbers.stream().count()); Optional<Integer> firstTwo = numbers.stream().filter(i -> i == 2).findFirst(); // 打印出的結(jié)果為: 2 firstTwo.ifPresent(System.out::println); Optional<Integer> anyOne = numbers.stream().filter(i -> i == 1).findAny(); // 打印出的結(jié)果為: 1 anyOne.ifPresent(System.out::println); // 打印出的結(jié)果為: false System.out.println(numbers.stream().allMatch(i -> i > 4)); // 打印出的結(jié)果為: true System.out.println(numbers.stream().anyMatch(i -> i > 4)); // 打印出的結(jié)果為: false System.out.println(numbers.stream().noneMatch(i -> i > 4)); Optional<Integer> max = numbers.stream().max(Comparator.naturalOrder()); // 打印出的結(jié)果為: 5 max.ifPresent(System.out::println); Optional<Integer> min = numbers.stream().min(Comparator.naturalOrder()); // 打印出的結(jié)果為: 1 min.ifPresent(System.out::println); // 打印出的結(jié)果為: 123512115 numbers.forEach(System.out::print); // 打印出的結(jié)果為: 234623226 numbers.stream().forEachOrdered(i -> System.out.print(i + 1));
歸約將集合中的所有元素經(jīng)過指定運算(加減乘除等),折疊成一個元素輸出)
reduce(T identity, BinaryOperator accumulator)敛摘,返回一個T類型的值.第一個值為初始值.
-
reduce(BinaryOperator accumulator),返回一個Optional類型的值.
List<Integer> numbers = Stream.of(1,2,3,5,1,2,1,1,5).collect(Collectors.toList()); Integer multi = numbers.stream().reduce(2, (i1, i2) -> i1 * i2); // 打印出的結(jié)果為: 600 System.out.println(multi); Optional<Integer> multi1 = numbers.stream().reduce((i1, i2) -> i1 * i2); // 打印出的結(jié)果為: 300 multi1.ifPresent(System.out::println);
Optional
包:java.util.Optional
作用:是個可以為null的容器對象乳愉。它可以保存類型T的值兄淫,或者僅僅保存null
-
優(yōu)勢:很好的解決空指針異常
類聲明
以下是一個java.util.Optional<T>類的聲明:
public final class Optional<T> extends Object
Optional操作
empty(),構(gòu)造一個空Optional實例
get(),如果在Optional中包含這個值蔓姚,返回值捕虽,否則拋出NoSuchElementException異常
ofPresent(Consumer consumer),如果值存在則使用該值調(diào)用consumer , 否則不做任何事情
ofNullable(T value)坡脐,如果為非空泄私,返回Optional描述的指定值
-
orElse(T other),如果存在該值,返回值备闲,否則返回other
public class OptionalTest { public static void main(String[] args) { OptionalTest optionalTest = new OptionalTest(); Integer value1 = null; Integer value2 = 10; // Optional.ofNullable - 允許傳遞為 null 參數(shù) Optional<Integer> a = Optional.ofNullable(value1); // Optional.of - 如果傳遞的參數(shù)是 null晌端,拋出異常 NullPointerException Optional<Integer> b = Optional.of(value2); System.out.println(optionalTest.sum(a,b)); } public Integer sum(Optional<Integer> a, Optional<Integer> b) { // Optional.isPresent - 判斷值是否存在 System.out.println("第一個參數(shù)值存在: " + a.isPresent()); System.out.println("第二個參數(shù)值存在: " + b.isPresent()); // Optional.orElse - 如果值存在,返回它恬砂,否則返回默認(rèn)值 Integer value1 = a.orElse(0); //Optional.get - 獲取值咧纠,值需要存在 Integer value2 = b.get(); return value1 + value2; } }