回答編集履歴
1
コード解説追加
test
CHANGED
@@ -5,6 +5,14 @@
|
|
5
5
|
|
6
6
|
|
7
7
|
Comparator.comparingIntはComparator<T>を返す**staticメソッド**です。このメソッドを渡すと、このTの部分をElementであるとしてコンパイルしてくれるのです。このため、2はコンパイルが通ります。
|
8
|
+
|
9
|
+
```java
|
10
|
+
|
11
|
+
// Comparator.comparingIntの総称型を自動でElementと推定
|
12
|
+
|
13
|
+
Collections.sort(list, Comparator.comparingInt(e -> e.n1));
|
14
|
+
|
15
|
+
```
|
8
16
|
|
9
17
|
|
10
18
|
|
@@ -14,6 +22,54 @@
|
|
14
22
|
|
15
23
|
つまり、comparingIntやthenComparingIntに渡しているラムダ式のeがObjectとして扱われ、Objectクラスにn1,n2,n3というフィールドがないため、ご質問のエラーが出ます。
|
16
24
|
|
25
|
+
```java
|
26
|
+
|
27
|
+
// この段階では型推論が効かないため、comparingIntの総称型はObject扱い
|
28
|
+
|
29
|
+
// つまり、ラムダ式はToIntFunction<Object>で、eの型がObject扱い
|
30
|
+
|
31
|
+
Collections.sort(list, Comparator.comparingInt(e -> e.n1)
|
32
|
+
|
33
|
+
// これ以降はComparator<Object>に対してthencomparingIntを呼んでいるため、
|
34
|
+
|
35
|
+
// 引数ラムダ式はToIntFunction<Object>
|
36
|
+
|
37
|
+
.thenComparingInt(e -> e.n2)
|
38
|
+
|
39
|
+
.thenComparingInt(e -> e.n3));
|
40
|
+
|
41
|
+
```
|
42
|
+
|
17
43
|
|
18
44
|
|
19
45
|
この問題は、comparingIntにおけるTがElementとわかれば解決します。そのため、総称型を明示的に指定する(4の方法)か、ラムダ式の引数、つまりFunctionの型を明示する(5の方法)ことでコンパイルが通るようになるのです。
|
46
|
+
|
47
|
+
```java
|
48
|
+
|
49
|
+
// comparingIntの総称型を明示的にElementにすることで、引数ラムダ式をToIntFunction<Element>と推定
|
50
|
+
|
51
|
+
Collections.sort(list, Comparator.<Element>comparingInt(e -> e.n1)
|
52
|
+
|
53
|
+
// 以降もComparator<Element>に対するメソッドのため、Elementに対する操作とわかる
|
54
|
+
|
55
|
+
.thenComparingInt(e -> e.n2)
|
56
|
+
|
57
|
+
.thenComparingInt(e -> e.n3));
|
58
|
+
|
59
|
+
```
|
60
|
+
|
61
|
+
```java
|
62
|
+
|
63
|
+
// ラムダ式の引数型をElementと明示することて、このラムダ式がToIntFunction<Element>に確定。
|
64
|
+
|
65
|
+
// これにより、comparingIntの総称型もElementに確定できる。
|
66
|
+
|
67
|
+
Collections.sort(list, Comparator.comparingInt((Element e) -> e.n1)
|
68
|
+
|
69
|
+
// 以下、先述通り
|
70
|
+
|
71
|
+
.thenComparingInt(e -> e.n2)
|
72
|
+
|
73
|
+
.thenComparingInt(e -> e.n3));
|
74
|
+
|
75
|
+
```
|