---
tags: java_se
---
# Java 8 OCPJP Notes
## Ch7 Exception
### 在 catch block reassign exception parameter
*Uni-Catch* clause
A catch clause whose exception parameter is denoted as a single class type is called a uni-catch clause.
在 catch blcok reassign exception parameter variable 後, 相當於又產生了一個新的 Exception. 必須 handle or declare it.
```java=
public class Q3 {
public static void main(String[] args) {
System.out.println("Start ");
try {
int i = 1/0;
System.out.println("Try ");
} catch (Exception e){
System.out.println("Catch ");
// new exception in the catch block
e = new Exception("My Exception");
// need to handle or declare it
throw e;
} finally {
System.out.println("Finally ");
}
System.out.println("After");
}
}
```
### multi-catch 的陷井
multi-catch 中的 exception parameter 被自動宣告為 finally, 不可在 catch block 中 reassign.
*Multi-Catch clause*
A catch clause whose exception parameter is denoted as a union of types is called a multi-catch clause.
- An exception parameter of a multi-catch clause is implicitly declared final if it is not explicitly declared final.
- It is a compile-time error if a union of types contains two alternatives Di and Dj (i ≠ j) where Di is a subtype of Dj (§4.10.2).
Ref: https://docs.oracle.com/javase/specs/jls/se8/html/jls-14.html#jls-CatchType
## Ch12 JDBC
[Using RowSet Object | Java 8 Tutorial](https://docs.oracle.com/javase/tutorial/jdbc/basics/rowset.html)
## Ch15 Stream API
### 在 stream 中進行 group by 的動作
以 city 進行排序, 得到每個 city 下的不重覆的員工的 Last name
```java=
Map<City, Set<String>> namesByCity =
people
.stream()
.collect(
Collectors.groupingBy(
Person::getCity,
Collectors.mapping(
Person::getLastName,
toSet()
)
)
);
```
[Collectors.mapping()](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#mapping-java.util.function.Function-java.util.stream.Collector-)
```java=
public static <T,U,A,R> Collector<T,?,R> mapping(
Function<? super T,? extends U> mapper,
Collector<? super U,A,R> downstream)
```
- `R` 是回傳後的資料型態, `U` 是 `R` 內的物件型態, 或者 `R<U>`
groupingBy 回傳的物件類別為 `Collector<T,?,Map<K,D>>`,
[Collectors.groupingBy()](https://docs.oracle.com/javase/8/docs/api/java/util/stream/Collectors.html#groupingBy-java.util.function.Function-java.util.stream.Collector-)
```java=
public static <T,K,A,D> Collector<T,?,Map<K,D>> groupingBy(
Function<? super T,? extends K> classifier,
Collector<? super T,A,D> downstream)
```
`downstream` 讓我們控制 `Map<K,D>` 中的 `D` 是那種物件型態.
也就是控制 map 中的 value 值是那種物件型態。
例如:
```java=
// 使用 set 來裝每群的內容
// K: City, R: Set, T: People, U: String
Map<City, Set<String>> namesByCity =
people
.stream()
.collect( // Collect to Map<K, R<U>>
Collectors.groupingBy(
Person::getCity, // K
Collectors.mapping(
Person::getLastName, // T --> U
toSet() // Collect to R<U>
)
)
);
// 使用 List 來裝每群的內容
Map<City, List<String>> namesByCity =
people
.stream()
.collect(
Collectors.groupingBy(
Person::getCity,
Collectors.mapping(
Person::getLastName,
toList()
)
)
);
```
### lambda expression x -> y -> x*y ?
Q25 的題目
```java=
public class Q25 {
public static void main(String[] args) {
IntStream stream = IntStream.of(10, 20, 30);
// Line 1
IntFunction<IntUnaryOperator> IF = (x) -> {
return (y -> {
return y * x;
});
};
// Line 2
IntStream newStream = stream.map(IF.apply(15));
newStream.forEach(System.out::println);
}
}
```
輸出結果爲何?
IF 為一個函數, 輸入值型態為 int, 輸出值型態為 `IntUnaryOperator`.
Line 2 中, `IF.apply(15)` 呼叫 `IntFunction` 的 `apply(x)`, 使得 x 的值為 15。之後,Unary Operator 成為:
```
(y) -> y * 15
```
`stream.map()` 會呼叫此 Unary Operator 的 `applyAsInt(y)`, 其中 y 為 stream 中的原素。
所以, 此程式會將 stream 中的每一個元素值乘上 15。輸出結果為: 150, 300, 450.
### 2 種找出 List 最大值的方法
重要觀念:
1. stream.max() 回傳的資料型態為 `Optional<T>` 或者 `Optional{primitive_type}`, 例如 `OptionalInt`。
2. 若 stream 中的值不是 primitive type, 就不能直接呼叫無參數 max() 方法。呼叫 `max()` 時必須提供 Comparators 說明如何比較兩個物件。
3. 使用 `Comparators.comparing(Function<? super T,? extends U> keyExtractor)` 方法產生 Comparators。我們可以提供取出物件鍵值方法, 之後包裝成一個 Comparator, 再回傳。
```java=
public class Q26 {
// Find the maximum value in the list
public static void main(String[] args) {
List<Integer> ints = Arrays.asList(11, 22, 8);
// Method 1:
// Comparator.comparing(Function_of_key_extractor)
// 提供取出物件鍵值的方法, 並包裝成 Comparator
Optional<Integer> max = ints.stream().max(Comparator.comparing(a -> a));
System.out.println(max.get());
// Method 2: 轉成 IntStream 後, 再呼叫 max()
OptionalInt maxInt = ints.stream().mapToInt(a -> a.intValue()).max();
System.out.println(maxInt.getAsInt());
}
}
```