Просмотр исходного кода

list-ops: update to match Kotlin track

Based on v1.0.0 of the canonical data:

https://github.com/exercism/problem-specifications/tree/28a32203b96ebaecac6a6968831bd66718d8ba30/exercises/list-ops

Plus modifications that are being discussed in

https://github.com/exercism/problem-specifications/issues/826
Stuart Kent 9 лет назад
Родитель
Сommit
6599e32896

+ 7
- 7
config.json Просмотреть файл

481
       ]
481
       ]
482
     },
482
     },
483
     {
483
     {
484
-      "slug": "change",
484
+      "slug": "list-ops",
485
       "difficulty": 8,
485
       "difficulty": 8,
486
       "topics": [
486
       "topics": [
487
-
487
+      
488
       ]
488
       ]
489
     },
489
     },
490
     {
490
     {
491
-      "slug": "palindrome-products",
491
+      "slug": "change",
492
       "difficulty": 8,
492
       "difficulty": 8,
493
       "topics": [
493
       "topics": [
494
 
494
 
495
       ]
495
       ]
496
     },
496
     },
497
     {
497
     {
498
-      "slug": "pythagorean-triplet",
499
-      "difficulty": 9,
498
+      "slug": "palindrome-products",
499
+      "difficulty": 8,
500
       "topics": [
500
       "topics": [
501
 
501
 
502
       ]
502
       ]
503
     },
503
     },
504
     {
504
     {
505
-      "slug": "list-ops",
505
+      "slug": "pythagorean-triplet",
506
       "difficulty": 9,
506
       "difficulty": 9,
507
       "topics": [
507
       "topics": [
508
-      
508
+
509
       ]
509
       ]
510
     },
510
     },
511
     {
511
     {

+ 3
- 0
exercises/list-ops/HINTS.md Просмотреть файл

1
+## Hints
2
+
3
+The `foldLeft` and `foldRight` methods are "fold" functions, which is a concept well-known in the functional programming world, but less so in the object-oriented one. See the Wikipedia page on folding for [general background](https://en.wikipedia.org/wiki/Fold_(higher-order_function)) and [signature/implementation hints](https://en.wikipedia.org/wiki/Fold_(higher-order_function)#Linear_folds).

+ 43
- 25
exercises/list-ops/src/example/java/ListOps.java Просмотреть файл

3
 import java.util.Collection;
3
 import java.util.Collection;
4
 import java.util.Collections;
4
 import java.util.Collections;
5
 import java.util.List;
5
 import java.util.List;
6
-import java.util.function.BiFunction;
7
-import java.util.function.BinaryOperator;
8
-import java.util.function.Predicate;
9
-import java.util.function.UnaryOperator;
6
+import java.util.function.*;
10
 import java.util.stream.Collectors;
7
 import java.util.stream.Collectors;
11
 import java.util.stream.Stream;
8
 import java.util.stream.Stream;
12
 
9
 
13
-public class ListOps {
10
+class ListOps {
14
 
11
 
15
-    private ListOps() {
12
+    static <T> List<T> append(final List<T> list1, final List<T> list2) {
13
+        final List<T> result = new ArrayList<>();
14
+        result.addAll(list1);
15
+        result.addAll(list2);
16
+        return result;
17
+    }
18
+
19
+    static <T> List<T> concat(final List<List<T>> listOfLists) {
20
+        final List<T> result = new ArrayList<>();
21
+        listOfLists.forEach(result::addAll);
22
+        return result;
23
+    }
24
+
25
+    static <T> List<T> filter(final List<T> list, Predicate<T> predicate) {
26
+        return list.stream().filter(predicate).collect(Collectors.toList());
16
     }
27
     }
17
 
28
 
18
-    public static <T> int length(final List<T> list) {
29
+    static <T> int size(final List<T> list) {
19
         return list.size();
30
         return list.size();
20
     }
31
     }
21
 
32
 
22
-    public static <T> List<T> reverse(final List<T> list) {
23
-        List<T> result = new ArrayList(list);
33
+    static <T, U> List<U> map(final List<T> list, Function<T, U> transform) {
34
+        return list.stream().map(transform).collect(Collectors.toList());
35
+    }
36
+
37
+    static <T> List<T> reverse(final List<T> list) {
38
+        final List<T> result = new ArrayList<>(list);
24
         Collections.reverse(result);
39
         Collections.reverse(result);
25
         return result;
40
         return result;
26
     }
41
     }
27
 
42
 
28
-    public static <T> List<T> map(final List<T> list,
29
-            UnaryOperator<T> mapper) {
30
-        return list.stream().map(mapper).collect(Collectors.toList());
31
-    }
43
+    static <T, U> U foldLeft(final List<T> list, final U initial, final BiFunction<U, T, U> f) {
44
+        if (list.isEmpty()) return initial;
32
 
45
 
33
-    public static <T> List<T> filter(final List<T> list,
34
-            Predicate<T> predicate) {
35
-        return list.stream().filter(predicate).collect(Collectors.toList());
46
+        return foldLeft(
47
+                new ArrayList<>(list.subList(1, list.size())),
48
+                f.apply(
49
+                        initial,
50
+                        list.get(0)),
51
+                f);
36
     }
52
     }
37
 
53
 
38
-    public static <U, T> U reduce(final List<T> list,
39
-            U identity,
40
-            BiFunction<U, T, U> accumulator,
41
-            BinaryOperator<U> combiner) {
42
-        return list.stream().reduce(identity, accumulator, combiner);
54
+    static <T, U> U foldRight(final List<T> list, final U initial, final BiFunction<T, U, U> f) {
55
+        if (list.isEmpty()) return initial;
56
+
57
+        return f.apply(
58
+                list.get(0),
59
+                foldRight(
60
+                        new ArrayList<>(list.subList(1, list.size())),
61
+                        initial,
62
+                        f));
43
     }
63
     }
44
 
64
 
45
-    public static <T> List<T> concat(final List<T>... lists) {
46
-        return Stream.of(lists)
47
-                .flatMap(Collection::stream)
48
-                .collect(Collectors.toList());
65
+    private ListOps() {
66
+        // No instances.
49
     }
67
     }
50
 
68
 
51
 }
69
 }

+ 0
- 0
exercises/list-ops/src/main/java/.keep Просмотреть файл


+ 44
- 0
exercises/list-ops/src/main/java/ListOps.java Просмотреть файл

1
+import java.util.List;
2
+import java.util.function.BiFunction;
3
+import java.util.function.Function;
4
+import java.util.function.Predicate;
5
+
6
+class ListOps {
7
+
8
+    static <T> List<T> append(List<T> list1, List<T> list2) {
9
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
10
+    }
11
+
12
+    static <T> List<T> concat(List<List<T>> listOfLists) {
13
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
14
+    }
15
+
16
+    static <T> List<T> filter(List<T> list, Predicate<T> predicate) {
17
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
18
+    }
19
+
20
+    static <T> int size(List<T> list) {
21
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
22
+    }
23
+
24
+    static <T, U> List<U> map(List<T> list, Function<T, U> transform) {
25
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
26
+    }
27
+
28
+    static <T> List<T> reverse(List<T> list) {
29
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
30
+    }
31
+
32
+    static <T, U> U foldLeft(List<T> list, U initial, BiFunction<U, T, U> f) {
33
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
34
+    }
35
+
36
+    static <T, U> U foldRight(List<T> list, U initial, BiFunction<T, U, U> f) {
37
+        throw new UnsupportedOperationException("Delete this statement and write your own implementation.");
38
+    }
39
+
40
+    private ListOps() {
41
+        // No instances.
42
+    }
43
+
44
+}

+ 119
- 249
exercises/list-ops/src/test/java/ListOpsTest.java Просмотреть файл

1
+import org.junit.Ignore;
2
+import org.junit.Test;
1
 
3
 
2
-import java.util.ArrayList;
3
 import java.util.Arrays;
4
 import java.util.Arrays;
4
 import java.util.Collections;
5
 import java.util.Collections;
5
 import java.util.List;
6
 import java.util.List;
6
-import java.util.function.BiFunction;
7
-import java.util.function.BinaryOperator;
8
-import java.util.function.Predicate;
9
-import java.util.stream.Collectors;
10
-import java.util.stream.IntStream;
11
-import static junit.framework.TestCase.assertEquals;
12
-import static junit.framework.TestCase.assertFalse;
13
-import static junit.framework.TestCase.assertNotNull;
14
-import static junit.framework.TestCase.assertTrue;
15
-import org.junit.Ignore;
16
-import org.junit.Test;
17
 
7
 
18
-public class ListOpsTest {
8
+import static org.junit.Assert.assertEquals;
19
 
9
 
20
-    private static final List<Integer> EMPTY_LIST
21
-            = Collections.emptyList();
10
+/*
11
+ * version: 1.0.0
12
+ */
13
+public class ListOpsTest {
22
 
14
 
23
     @Test
15
     @Test
24
-    public void lengthOfAnEmptyListShouldBeZero() {
25
-        final int expected = 0;
26
-        final int actual = ListOps.length(EMPTY_LIST);
27
-
28
-        assertEquals(expected, actual);
16
+    public void testAppendingEmptyLists() {
17
+        assertEquals(
18
+                Collections.emptyList(),
19
+                ListOps.append(Collections.emptyList(), Collections.emptyList()));
29
     }
20
     }
30
 
21
 
31
-    @Test
32
     @Ignore("Remove to run test")
22
     @Ignore("Remove to run test")
33
-    public void shouldReturnTheCorrectLengthOfAnNonEmptyList() {
34
-        final List<Integer> list = Collections.unmodifiableList(
35
-                Arrays.asList(0, 1, 2, 3, 4)
36
-        );
37
-        final int actual = ListOps.length(list);
38
-        final int expected = list.size();
39
-
40
-        assertEquals(expected, actual);
41
-    }
42
-
43
     @Test
23
     @Test
44
-    @Ignore("Remove to run test")
45
-    public void shouldReverseAnEmptyList() {
46
-        final List<Integer> actual = ListOps.reverse(EMPTY_LIST);
47
-
48
-        assertNotNull(actual);
49
-        assertTrue(actual.isEmpty());
24
+    public void testAppendingNonEmptyListOnEmptyList() {
25
+        assertEquals(
26
+                Arrays.asList('1', '2', '3', '4'),
27
+                ListOps.append(Collections.emptyList(), Arrays.asList('1', '2', '3', '4')));
50
     }
28
     }
51
 
29
 
52
-    @Test
53
     @Ignore("Remove to run test")
30
     @Ignore("Remove to run test")
54
-    public void shouldReverseANonEmptyList() {
55
-        final List<Integer> list = Collections.unmodifiableList(
56
-                Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8)
57
-        );
58
-        final List<Integer> actual
59
-                = ListOps.reverse(list);
60
-        final List<Integer> expected
61
-                = Arrays.asList(8, 7, 6, 5, 4, 3, 2, 1, 0);
62
-
63
-        assertNotNull(actual);
64
-        assertFalse(actual.isEmpty());
65
-        assertEquals(expected, actual);
31
+    @Test
32
+    public void testAppendingNonEmptyListOnNonEmptyList() {
33
+        assertEquals(
34
+                Arrays.asList("1", "2", "2", "3", "4", "5"),
35
+                ListOps.append(Arrays.asList("1", "2"), Arrays.asList("2", "3", "4", "5")));
66
     }
36
     }
67
 
37
 
68
-    @Test
69
     @Ignore("Remove to run test")
38
     @Ignore("Remove to run test")
70
-    public void shouldMapAnEmptyListAndReturnAnEmptyList() {
71
-        final List<Integer> actual = ListOps.map(EMPTY_LIST, x -> x + 1);
72
-
73
-        assertNotNull(actual);
74
-        assertTrue(actual.isEmpty());
39
+    @Test
40
+    public void testConcatOnEmptyListOfLists() {
41
+        assertEquals(
42
+                Collections.emptyList(),
43
+                ListOps.concat(Collections.emptyList()));
75
     }
44
     }
76
 
45
 
77
-    @Test
78
     @Ignore("Remove to run test")
46
     @Ignore("Remove to run test")
79
-    public void shouldMapNonEmptyList() {
80
-        final List<Integer> list
81
-                = Collections.unmodifiableList(Arrays.asList(1, 3, 5, 7));
82
-        final List<Integer> actual = ListOps.map(list, x -> x + 1);
47
+    @Test
48
+    public void testConcatOnNonEmptyListOfLists() {
49
+        List<List<Character>> listOfLists = Arrays.asList(
50
+                Arrays.asList('1', '2'),
51
+                Collections.singletonList('3'),
52
+                Collections.emptyList(),
53
+                Arrays.asList('4', '5', '6'));
83
 
54
 
84
-        assertNotNull(actual);
85
-        assertFalse(actual.isEmpty());
86
-        assertEquals(Arrays.asList(2, 4, 6, 8), actual);
55
+        assertEquals(
56
+                Arrays.asList('1', '2', '3', '4', '5', '6'),
57
+                ListOps.concat(listOfLists));
87
     }
58
     }
88
 
59
 
89
-    @Test
90
     @Ignore("Remove to run test")
60
     @Ignore("Remove to run test")
91
-    public void shouldFilterAnEmptyListanddReturnAnEmptyList() {
92
-        final List<Integer> actual = ListOps.filter(EMPTY_LIST, x -> x > 0);
93
-
94
-        assertNotNull(actual);
95
-        assertTrue(actual.isEmpty());
61
+    @Test
62
+    public void testFilteringEmptyList() {
63
+        assertEquals(
64
+                Collections.emptyList(),
65
+                ListOps.filter(Collections.<Integer>emptyList(), integer -> integer % 2 == 1));
96
     }
66
     }
97
 
67
 
98
-    @Test
99
     @Ignore("Remove to run test")
68
     @Ignore("Remove to run test")
100
-    public void shouldFilterNonEmptyList() {
101
-        Predicate<Integer> predicate = x -> x % 2 > 0;
102
-        final List<Integer> list = Collections.unmodifiableList(
103
-                IntStream.range(0, 100).boxed().collect(Collectors.toList())
104
-        );
105
-        final List<Integer> actual = ListOps.filter(list, predicate);
106
-        final List<Integer> expected = list.stream()
107
-                .filter(predicate)
108
-                .collect(Collectors.toList());
109
-
110
-        assertNotNull(actual);
111
-        assertFalse(actual.isEmpty());
112
-        assertEquals(expected, actual);
69
+    @Test
70
+    public void testFilteringNonEmptyList() {
71
+        assertEquals(
72
+                Arrays.asList(1, 3, 5),
73
+                ListOps.filter(Arrays.asList(1, 2, 3, 5), integer -> integer % 2 == 1));
113
     }
74
     }
114
 
75
 
115
-    @Test
116
     @Ignore("Remove to run test")
76
     @Ignore("Remove to run test")
117
-    public void shouldConcatenateZeroLists() {
118
-        List<Integer> actual = ListOps.concat();
119
-
120
-        assertNotNull(actual);
121
-        assertTrue(actual.isEmpty());
77
+    @Test
78
+    public void testSizeOfEmptyList() {
79
+        assertEquals(0, ListOps.size(Collections.emptyList()));
122
     }
80
     }
123
 
81
 
124
-    @Test
125
     @Ignore("Remove to run test")
82
     @Ignore("Remove to run test")
126
-    public void shouldConcatenateOneNonEmptyList() {
127
-        final List<Integer> list
128
-                = Collections.unmodifiableList(
129
-                        Arrays.asList(0, 1, 2, 3, 4)
130
-                );
131
-        final List<Integer> actual = ListOps.concat(list);
132
-        final List<Integer> expected = Arrays.asList(0, 1, 2, 3, 4);
133
-
134
-        assertNotNull(actual);
135
-        assertFalse(actual.isEmpty());
136
-        assertEquals(expected, actual);
83
+    @Test
84
+    public void testSizeOfNonEmptyList() {
85
+        assertEquals(4, ListOps.size(Arrays.asList("one", "two", "three", "four")));
137
     }
86
     }
138
 
87
 
139
-    @Test
140
     @Ignore("Remove to run test")
88
     @Ignore("Remove to run test")
141
-    public void shouldConcatenateOneEmptyList() {
142
-        final List<Integer> actual = ListOps.concat(EMPTY_LIST);
143
-
144
-        assertNotNull(actual);
145
-        assertTrue(actual.isEmpty());
89
+    @Test
90
+    public void testTransformingEmptyList() {
91
+        assertEquals(
92
+                Collections.emptyList(),
93
+                ListOps.map(Collections.<Integer>emptyList(), integer -> integer + 1 ));
146
     }
94
     }
147
 
95
 
148
-    @Test
149
     @Ignore("Remove to run test")
96
     @Ignore("Remove to run test")
150
-    public void shouldConcatenateTwoEmptyLists() {
151
-        final List<Integer> actual = ListOps.concat(EMPTY_LIST, EMPTY_LIST);
152
-
153
-        assertNotNull(actual);
154
-        assertTrue(actual.isEmpty());
97
+    @Test
98
+    public void testTransformingNonEmptyList() {
99
+        assertEquals(
100
+                Arrays.asList(2, 4, 6, 8),
101
+                ListOps.map(Arrays.asList(1, 3, 5, 7), integer -> integer + 1 ));
155
     }
102
     }
156
 
103
 
157
-    @Test
158
     @Ignore("Remove to run test")
104
     @Ignore("Remove to run test")
159
-    public void shouldConcatenateOneEmptyAndOneNonEmptyLists() {
160
-        final List<Integer> list
161
-                = Collections.unmodifiableList(
162
-                        Arrays.asList(0, 1, 2, 3, 4)
163
-                );
164
-        final List<Integer> actual = ListOps.concat(list, EMPTY_LIST);
165
-        final List<Integer> expected
166
-                = Arrays.asList(0, 1, 2, 3, 4);
167
-
168
-        assertNotNull(actual);
169
-        assertFalse(actual.isEmpty());
170
-        assertEquals(expected, actual);
105
+    @Test
106
+    public void testFoldLeftOnEmptyList() {
107
+        assertEquals(
108
+                new Double(2.0), // Boxing required for method overload disambiguation.
109
+                ListOps.foldLeft(
110
+                        Collections.<Double>emptyList(),
111
+                        2.0,
112
+                        (x, y) -> x * y));
171
     }
113
     }
172
 
114
 
173
-    @Test
174
     @Ignore("Remove to run test")
115
     @Ignore("Remove to run test")
175
-    public void shouldConcatenateOneNonEmptyAndOneEmptyLists() {
176
-        final List<Integer> list
177
-                = Collections.unmodifiableList(
178
-                        Arrays.asList(0, 1, 2, 3, 4)
179
-                );
180
-        final List<Integer> actual = ListOps.concat(EMPTY_LIST, list);
181
-        final List<Integer> expected
182
-                = Arrays.asList(0, 1, 2, 3, 4);
183
-
184
-        assertNotNull(actual);
185
-        assertFalse(actual.isEmpty());
186
-        assertEquals(expected, actual);
116
+    @Test
117
+    public void testFoldLeftWithDirectionIndependentOperationOnNonEmptyList() {
118
+        assertEquals(
119
+                new Integer(15), // Boxing required for method overload disambiguation.
120
+                ListOps.foldLeft(
121
+                        Arrays.asList(1, 2, 3, 4),
122
+                        5,
123
+                        (x, y) -> x + y));
187
     }
124
     }
188
 
125
 
189
-    @Test
190
     @Ignore("Remove to run test")
126
     @Ignore("Remove to run test")
191
-    public void shouldConcatenateTwoListsWithSameElements() {
192
-        final List<Integer> list1 = Collections.unmodifiableList(
193
-                Arrays.asList(0, 1, 2, 3, 4)
194
-        );
195
-        final List<Integer> list2 = Collections.unmodifiableList(
196
-                Arrays.asList(1, 2, 3, 4, 5, 6)
197
-        );
198
-        final List<Integer> expected
199
-                = Arrays.asList(0, 1, 2, 3, 4, 1, 2, 3, 4, 5, 6);
200
-        final List<Integer> actual = ListOps.concat(list1, list2);
201
-
202
-        assertNotNull(actual);
203
-        assertFalse(actual.isEmpty());
204
-        assertEquals(expected, actual);
127
+    @Test
128
+    public void testFoldLeftWithDirectionDependentOperationOnNonEmptyList() {
129
+        assertEquals(
130
+                new Integer(0), // Boxing required for method overload disambiguation.
131
+                ListOps.foldLeft(
132
+                        Arrays.asList(2, 5),
133
+                        5,
134
+                        (x, y) -> x / y));
205
     }
135
     }
206
 
136
 
207
-    @Test
208
     @Ignore("Remove to run test")
137
     @Ignore("Remove to run test")
209
-    public void shouldConcatenateSeveralLists() {
210
-        final List<Integer> list1 = Collections.unmodifiableList(
211
-                Arrays.asList(0, 1, 2, 3)
212
-        );
213
-        final List<Integer> list2 = Collections.unmodifiableList(
214
-                Arrays.asList(4, 5, 6, 7)
215
-        );
216
-        final List<Integer> list3 = Collections.unmodifiableList(
217
-                Arrays.asList(8, 9, 10, 11)
218
-        );
219
-        final List<Integer> list4 = Collections.unmodifiableList(
220
-                Arrays.asList(12, 13, 14, 15)
221
-        );
222
-        final List<Integer> expected
223
-                = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13,
224
-                        14, 15);
225
-
226
-        final List<Integer> actual
227
-                = ListOps.concat(list1, list2, EMPTY_LIST, list3, list4);
228
-
229
-        assertNotNull(actual);
230
-        assertFalse(actual.isEmpty());
231
-        assertEquals(expected, actual);
138
+    @Test
139
+    public void testFoldRightOnEmptyList() {
140
+        assertEquals(
141
+                new Double(2.0), // Boxing required for method overload disambiguation.
142
+                ListOps.foldRight(
143
+                        Collections.<Double>emptyList(),
144
+                        2.0,
145
+                        (x, y) -> x * y));
232
     }
146
     }
233
 
147
 
234
-    @Test
235
     @Ignore("Remove to run test")
148
     @Ignore("Remove to run test")
236
-    public void shouldReturnIdentityWhenAnEmptyListIsReduced() {
237
-        final int expected = 0;
238
-        final int actual
239
-                = ListOps.reduce(EMPTY_LIST, 0, (x, y) -> x + y, Integer::sum);
240
-
241
-        assertEquals(expected, actual);
149
+    @Test
150
+    public void testFoldRightWithDirectionIndependentOperationOnNonEmptyList() {
151
+        assertEquals(
152
+                new Integer(15), // Boxing required for method overload disambiguation.
153
+                ListOps.foldRight(
154
+                        Arrays.asList(1, 2, 3, 4),
155
+                        5,
156
+                        (x, y) -> x + y));
242
     }
157
     }
243
 
158
 
244
-    @Test
245
     @Ignore("Remove to run test")
159
     @Ignore("Remove to run test")
246
-    public void shouldCalculateTheSumOfANonEmptyIntegerList() {
247
-        final List<Integer> list = Collections.unmodifiableList(
248
-                Arrays.asList(0, 1, 2, 3, 4)
249
-        );
250
-        final int actual = ListOps.reduce(list, 0,
251
-                (x, y) -> x + y,
252
-                Integer::sum);
253
-
254
-        assertEquals(10, actual);
160
+    @Test
161
+    public void testFoldRightWithDirectionDependentOperationOnNonEmptyList() {
162
+        assertEquals(
163
+                new Integer(2), // Boxing required for method overload disambiguation.
164
+                ListOps.foldRight(
165
+                        Arrays.asList(2, 5),
166
+                        5,
167
+                        (x, y) -> x / y));
255
     }
168
     }
256
 
169
 
257
-    /*
258
-    https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html
259
-    https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#reduce-U-java.util.function.BiFunction-java.util.function.BinaryOperator-
260
-     */
261
-    private BiFunction<List<Integer>, Integer, List<Integer>> accumulator
262
-            = (List<Integer> partial, Integer elem) -> {
263
-                List<Integer> result = new ArrayList<>(partial);
264
-                result.add(elem);
265
-                return result;
266
-            };
267
-
268
-    private BinaryOperator<List<Integer>> combiner
269
-            = (list1, list2) -> {
270
-                List<Integer> result = new ArrayList<>(list1);
271
-                result.addAll(list2);
272
-                return result;
273
-            };
274
-
275
-    @Test
276
     @Ignore("Remove to run test")
170
     @Ignore("Remove to run test")
277
-    public void shouldReduceAnEmptyListAndANonEmptyListAndReturnConcatenation() {
278
-        final List<Integer> list = Collections.unmodifiableList(
279
-                Arrays.asList(0, 1, 2, 3, 4, 5)
280
-        );
281
-        final List<Integer> actual
282
-                = ListOps.reduce(list,
283
-                        new ArrayList<Integer>(),
284
-                        accumulator,
285
-                        combiner);
286
-        final List<Integer> expected
287
-                = Arrays.asList(0, 1, 2, 3, 4, 5);
288
-
289
-        assertNotNull(actual);
290
-        assertFalse(actual.isEmpty());
291
-        assertEquals(expected, actual);
171
+    @Test
172
+    public void testReversingEmptyList() {
173
+        assertEquals(
174
+                Collections.emptyList(),
175
+                ListOps.reverse(Collections.emptyList()));
292
     }
176
     }
293
 
177
 
294
-    @Test
295
     @Ignore("Remove to run test")
178
     @Ignore("Remove to run test")
296
-    public void shouldReduceTwoNonEmptyListsAndReturnConcatenation() {
297
-        final List<Integer> listOne = Collections.unmodifiableList(
298
-                Arrays.asList(0, 1, 2, 3, 4)
299
-        );
300
-        final List<Integer> listTwo = Collections.unmodifiableList(
301
-                Arrays.asList(5, 6, 7, 8, 9)
302
-        );
303
-        final List<Integer> actual
304
-                = ListOps.reduce(listTwo,
305
-                        listOne,
306
-                        accumulator,
307
-                        combiner);
308
-        final List<Integer> expected
309
-                = Arrays.asList(0, 1, 2, 3, 4, 5, 6, 7, 8, 9);
310
-
311
-        assertNotNull(actual);
312
-        assertFalse(actual.isEmpty());
313
-        assertEquals(expected, actual);
179
+    @Test
180
+    public void testReversingNonEmptyList() {
181
+        assertEquals(
182
+                Arrays.asList('7', '5', '3', '1'),
183
+                ListOps.reverse(Arrays.asList('1', '3', '5', '7')));
314
     }
184
     }
315
 
185
 
316
 }
186
 }