Java 8
Stream API
為什麼需要
Stream API
Steam API 的作用
- Functional Prgroamming 的大力發展
- Steam API 讓迴圈的循環能更寫得更優雅
- Stream 的寫法會引導開發者降低程式的耦合度
- Stream 讓平行擴展變的相當容易
Steam API 的缺點
- 開發者需要調整開發的想法
- 相較一個簡單的 for ,效能是會比較差的。
- 除錯相對會比較困難一點
先來一段
Code
這段 Code 的作用?
public class StreamDemo {
public static void main(String[] args) throws IOException {
String fileName = "C:\\temp\temp.txt";
List<String> strings = Files.readAllLines(Paths.get(fileName));
List<String> result = new ArrayList<>();
for (String line : strings) {
if(line.startsWith("2019.09")) {
result.add(line);
}
}
for (String s : result) {
System.out.println(s);
}
}
}比較
// 單純的 For 迴圈
List<String> result = new ArrayList<>();
for (String line : strings) {
if(line.startsWith("2019.09")) {
result.add(line);
}
}
// Java 8 Stream API 的寫法
List<String> streamResult = Files.lines(path)
.filter(line -> line.startsWith("2019.09"))
.collect(Collectors.toList());
Java Stream API 使用流程
- 取得 Stream
- 執行 0 到多個 中繼操作
- 執行 結束操作
Java Stream 圖解

取得 Stream 的方法
建立 Collection 的 Stream
Collection<String> collection = Arrays.asList("a", "b", "c");
Stream<String> streamOfCollection = collection.stream();建立 Array 的 Stream
String[] arr = new String[]{"a", "b", "c"};
Stream<String> streamOfArrayFull = Arrays.stream(arr);
Stream<String> streamOfArrayPart = Arrays.stream(arr, 1, 3);建立 Files 的 Stream
Path path = Paths.get("C:\\file.txt");
Stream<String> streamOfStrings = Files.lines(path);Steam 的中介動作
filter()
Stream<String> longStringsStream = stream.filter((value) -> {
return value.length() >= 3;
});map()
List<String> list = new ArrayList<String>();
Stream<String> stream = list.stream();
Stream<String> streamMapped =
stream.map((value) -> value.toUpperCase());flatMap()
List<String> stringList = new ArrayList<String>();
stringList.add("One flew over the cuckoo's nest");
stringList.add("To kill a muckingbird");
stringList.add("Gone with the wind");
Stream<String> stream = stringList.stream();
stream.flatMap((value) -> {
String[] split = value.split(" ");
return (Stream<String>) Arrays.asList(split).stream();
}).forEach((value) -> System.out.println(value));distinct()
List<String> stringList = new ArrayList<String>();
stringList.add("one");
stringList.add("two");
stringList.add("three");
stringList.add("one");
Stream<String> stream = stringList.stream();
List<String> distinctStrings = stream
.distinct()
.collect(Collectors.toList());
System.out.println(distinctStrings);limit()
List<String> stringList = new ArrayList<String>();
stringList.add("one");
stringList.add("two");
stringList.add("three");
stringList.add("one");
Stream<String> stream = stringList.stream();
stream
.limit(2)
.forEach( element -> { System.out.println(element); }); peek()
List<String> stringList = new ArrayList<String>();
stringList.add("abc");
stringList.add("def");
Stream<String> stream = stringList.stream();
Stream<String> streamPeeked = stream.peek((value) -> {
System.out.println("value");
});Steam 的結尾動作
collect()
List<String> stringList = new ArrayList<String>();
stringList.add("One flew over the cuckoo's nest");
stringList.add("To kill a muckingbird");
stringList.add("Gone with the wind");
Stream<String> stream = stringList.stream();
List<String> stringsAsUppercaseList = stream
.map(value -> value.toUpperCase())
.collect(Collectors.toList());
System.out.println(stringsAsUppercaseList);foreach()
List<String> stringList = new ArrayList<String>();
stringList.add("one");
stringList.add("two");
stringList.add("three");
stringList.add("one");
Stream<String> stream = stringList.stream();
stream.forEach( element -> { System.out.println(element); });anyMatch()
List<String> stringList = new ArrayList<String>();
stringList.add("One flew over the cuckoo's nest");
stringList.add("To kill a muckingbird");
stringList.add("Gone with the wind");
Stream<String> stream = stringList.stream();
boolean anyMatch =
stream.anyMatch((value) -> {
return value.startsWith("One");
});
System.out.println(anyMatch);anyMatch()
List<String> stringList = new ArrayList<String>();
stringList.add("One flew over the cuckoo's nest");
stringList.add("To kill a muckingbird");
stringList.add("Gone with the wind");
Stream<String> stream = stringList.stream();
boolean allMatch =
stream.allMatch((value) -> {
return value.startsWith("One");
});
System.out.println(allMatch);noneMatch()
List<String> stringList = new ArrayList<String>();
stringList.add("abc");
stringList.add("def");
Stream<String> stream = stringList.stream();
boolean noneMatch = stream.noneMatch((element) -> {
return "xyz".equals(element);
});
System.out.println("noneMatch = " + noneMatch);count()
List<String> stringList = new ArrayList<String>();
stringList.add("One flew over the cuckoo's nest");
stringList.add("To kill a muckingbird");
stringList.add("Gone with the wind");
Stream<String> stream = stringList.stream();
long count = stream.flatMap((value) -> {
String[] split = value.split(" ");
return (Stream<String>) Arrays.asList(split).stream();
})
.count();
System.out.println("count = " + count);findAny()
List<String> stringList = new ArrayList<String>();
stringList.add("one");
stringList.add("two");
stringList.add("three");
stringList.add("one");
Stream<String> stream = stringList.stream();
Optional<String> anyElement = stream.findAny();
System.out.println(anyElement.get());findFirst()
List<String> stringList = new ArrayList<String>();
stringList.add("one");
stringList.add("two");
stringList.add("three");
stringList.add("one");
Stream<String> stream = stringList.stream();
Optional<String> result = stream.findFirst();
System.out.println(result.get());min()
List<String> stringList = new ArrayList<String>();
stringList.add("abc");
stringList.add("def");
Stream<String> stream = stringList.stream();
Optional<String> min = stream.min((val1, val2) -> {
return val1.compareTo(val2);
});
String minString = min.get();
System.out.println(minString);max()
List<String> stringList = new ArrayList<String>();
stringList.add("abc");
stringList.add("def");
Stream<String> stream = stringList.stream();
Optional<String> max = stream.max((val1, val2) -> {
return val1.compareTo(val2);
});
String maxString = max.get();
System.out.println(maxString);
reduce()
List<String> stringList = new ArrayList<String>();
stringList.add("One flew over the cuckoo's nest");
stringList.add("To kill a muckingbird");
stringList.add("Gone with the wind");
Stream<String> stream = stringList.stream();
Optional<String> reduced = stream.reduce(
(value, combinedValue) -> {
return combinedValue + " + " + value;
});
System.out.println(reduced.get());toArray()
List<String> stringList = new ArrayList<String>();
stringList.add("One flew over the cuckoo's nest");
stringList.add("To kill a muckingbird");
stringList.add("Gone with the wind");
Stream<String> stream = stringList.stream();
Object[] objects = stream.toArray();Example
private Double getActualEffectiveEsdaya(String esdaysGrid,
Timestamp resignDate) throws Exception{
List<EsdaysYear> esdaysYear = esdaysEBO.getEsdaysYearByEffectiveDate(esdaysGrid, resignDate);
// Before Java 8
Double actualDays = 0.0;
for(int i = 0 ; i < esdaysYear.size() ; i++ ){
actualDays += esdaysYear.get(i).getDays();
actualDays += esdaysYear.get(i).getPendingDays();
}
// After Java 8
double actutal = esdaysYear.stream()
.mapToDouble(esdaysYearItem -> esdaysYearItem.getDays() + esdaysYearItem.getPendingDays())
.sum();
return actualDays;
}Java 8 Stream
By Balicanta Yao
Java 8 Stream
- 116