回答編集履歴

3

ソースコードの不備(import)を修正

2020/04/12 09:46

投稿

xebme
xebme

スコア1083

test CHANGED
@@ -4,13 +4,23 @@
4
4
 
5
5
  ```Java
6
6
 
7
+ import java.util.ArrayList;
8
+
9
+ import java.util.Arrays;
10
+
11
+ import java.util.Comparator;
12
+
7
- import java.util.*;
13
+ import java.util.List;
8
14
 
9
15
  import java.util.function.BiFunction;
10
16
 
11
17
  import java.util.function.Consumer;
12
18
 
19
+ import java.util.function.Function;
20
+
13
21
  import java.util.stream.Collectors;
22
+
23
+ import java.util.stream.IntStream;
14
24
 
15
25
 
16
26
 
@@ -45,6 +55,18 @@
45
55
  .findFirst()
46
56
 
47
57
  .orElse(0);
58
+
59
+
60
+
61
+ static Function<Integer,Comparator<long[]>> genComparatorChain = size ->
62
+
63
+ IntStream.range(0,size)
64
+
65
+ .mapToObj(i -> Comparator.<long[],Long>comparing(x -> x[i]))
66
+
67
+ .reduce((a,b) -> 0, Comparator::thenComparing);
68
+
69
+ static Comparator<long[]> comparator14 = genComparatorChain.apply(2);
48
70
 
49
71
 
50
72
 
@@ -88,7 +110,9 @@
88
110
 
89
111
  dump_.accept(sorter.apply(comparator13,a));
90
112
 
91
- dump_.accept(sorter.apply(comparator12,a));
113
+ dump_.accept(sorter.apply(comparator12,a));
114
+
115
+ dump_.accept(sorter.apply(comparator14,a));
92
116
 
93
117
  }
94
118
 

2

配列のサイズに合わせたComparator<long[]>(追記)

2020/04/12 09:46

投稿

xebme
xebme

スコア1083

test CHANGED
@@ -131,3 +131,29 @@
131
131
  Comparator<long[]> comparator13 = Comparator.comparing(getElement.apply(0)).thenComparing(getElement.apply(1));
132
132
 
133
133
  ```
134
+
135
+ ###
136
+
137
+ **配列のサイズに合わせたComparator<long[]>(追記)**
138
+
139
+
140
+
141
+ 結論の3番目を変形して、配列のサイズに応じた`Comparator<long[]>`が作れることがわかりました。
142
+
143
+
144
+
145
+ ```Java
146
+
147
+ Function<Integer,Comparator<long[]>> genComparatorChain = size ->
148
+
149
+ IntStream.range(0,size)
150
+
151
+ .mapToObj(i -> Comparator.<long[],Long>comparing(x -> x[i]))
152
+
153
+ .reduce((a,b) -> 0, Comparator::thenComparing);
154
+
155
+ Comparator<long[]> comparator14 = genComparatorChain.apply(2);
156
+
157
+ ```
158
+
159
+ 結論:Comparatorに限らず、Functionインターフェイスでもreduce()を使って、compose()、andThen()をチェインできることがわかり有益でした。

1

結論(追記)

2020/04/12 09:20

投稿

xebme
xebme

スコア1083

test CHANGED
@@ -25,6 +25,26 @@
25
25
  static Comparator<long[]> comparator3 = Comparator.<long[], Long>comparing(v -> v[0]).thenComparing(v -> v[1]);
26
26
 
27
27
  static Comparator<long[]> comparator4 = Comparator.<long[], Long>comparing(v -> v[0]).thenComparingLong(v -> v[1]);
28
+
29
+
30
+
31
+ static Function<Integer,Function<long[],Long>> getElement = i -> (array) -> array[i];
32
+
33
+ static Comparator<long[]> comparator13 = Comparator.comparing(getElement.apply(0)).thenComparing(getElement.apply(1));
34
+
35
+
36
+
37
+ static Comparator<long[]> comparator12 = (x,y) ->
38
+
39
+ IntStream.range(0, Math.min(x.length,y.length))
40
+
41
+ .map(i -> Long.compare(x[i], y[i]))
42
+
43
+ .dropWhile(i -> i == 0)
44
+
45
+ .findFirst()
46
+
47
+ .orElse(0);
28
48
 
29
49
 
30
50
 
@@ -64,10 +84,50 @@
64
84
 
65
85
  dump_.accept(sorter.apply(comparator3,a));
66
86
 
67
- dump_.accept(sorter.apply(comparator4,a));
87
+ dump_.accept(sorter.apply(comparator4,a));
88
+
89
+ dump_.accept(sorter.apply(comparator13,a));
90
+
91
+ dump_.accept(sorter.apply(comparator12,a));
68
92
 
69
93
  }
70
94
 
71
95
  }
72
96
 
73
97
  ```
98
+
99
+ ###
100
+
101
+ **結論(追記)**
102
+
103
+
104
+
105
+ `thenComparing`のkyExtractorの型が推論されない問題の解決として、以下の3つの方法がありました。
106
+
107
+
108
+
109
+ - Comparator.comparingに指定するラムダ式の、引数に型`long[]`を指定する
110
+
111
+ - staticメソッドComparator.comparingにkeyExtractorの型`<long[], Long>`を指定する
112
+
113
+ - あらかじめkeyExtractor関数`Function<long[],Long>`を定義しておき渡す。
114
+
115
+
116
+
117
+ ```Java
118
+
119
+ // 1
120
+
121
+ Comparator.comparing((long[] v) -> v[0]).thenComparing(v -> v[1]);
122
+
123
+ // 2
124
+
125
+ Comparator.<long[], Long>comparing(v -> v[0]).thenComparing(v -> v[1]);
126
+
127
+ // 3
128
+
129
+ Function<Integer,Function<long[],Long>> getElement = i -> (array) -> array[i];
130
+
131
+ Comparator<long[]> comparator13 = Comparator.comparing(getElement.apply(0)).thenComparing(getElement.apply(1));
132
+
133
+ ```