View Javadoc
1   /*
2    * Licensed to the Apache Software Foundation (ASF) under one or more
3    * contributor license agreements.  See the NOTICE file distributed with
4    * this work for additional information regarding copyright ownership.
5    * The ASF licenses this file to You under the Apache License, Version 2.0
6    * (the "License"); you may not use this file except in compliance with
7    * the License.  You may obtain a copy of the License at
8    *
9    *      http://www.apache.org/licenses/LICENSE-2.0
10   *
11   * Unless required by applicable law or agreed to in writing, software
12   * distributed under the License is distributed on an "AS IS" BASIS,
13   * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   * See the License for the specific language governing permissions and
15   * limitations under the License.
16   */
17  package org.apache.commons.collections4;
18  
19  import static org.junit.jupiter.api.Assertions.assertAll;
20  import static org.junit.jupiter.api.Assertions.assertEquals;
21  import static org.junit.jupiter.api.Assertions.assertFalse;
22  import static org.junit.jupiter.api.Assertions.assertNotEquals;
23  import static org.junit.jupiter.api.Assertions.assertNotNull;
24  import static org.junit.jupiter.api.Assertions.assertSame;
25  import static org.junit.jupiter.api.Assertions.assertThrows;
26  import static org.junit.jupiter.api.Assertions.assertTrue;
27  
28  import java.util.ArrayList;
29  import java.util.Arrays;
30  import java.util.Collection;
31  import java.util.Collections;
32  import java.util.HashSet;
33  import java.util.List;
34  
35  import org.apache.commons.collections4.functors.EqualPredicate;
36  import org.apache.commons.collections4.list.PredicatedList;
37  import org.apache.commons.lang3.StringUtils;
38  import org.junit.jupiter.api.BeforeEach;
39  import org.junit.jupiter.api.Test;
40  
41  /**
42   * Tests for ListUtils.
43   */
44  public class ListUtilsTest {
45  
46      private static final String a = "a";
47      private static final String b = "b";
48      private static final String c = "c";
49      private static final String d = "d";
50      private static final String e = "e";
51      private static final String x = "x";
52  
53      private static final Predicate<Number> EQUALS_TWO = input -> input.intValue() == 2;
54      private String[] fullArray;
55  
56      private List<String> fullList;
57  
58      @BeforeEach
59      public void setUp() {
60          fullArray = new String[]{a, b, c, d, e};
61          fullList = new ArrayList<>(Arrays.asList(fullArray));
62      }
63  
64      @Test
65      public void testDefaultIfNull() {
66          assertTrue(ListUtils.defaultIfNull(null, Collections.emptyList()).isEmpty());
67  
68          final List<Long> list = new ArrayList<>();
69          assertSame(list, ListUtils.defaultIfNull(list, Collections.<Long>emptyList()));
70      }
71  
72      @Test
73      public void testEmptyIfNull() {
74          assertTrue(ListUtils.emptyIfNull(null).isEmpty());
75  
76          final List<Long> list = new ArrayList<>();
77          assertSame(list, ListUtils.emptyIfNull(list));
78      }
79  
80      @Test
81      public void testEquals() {
82          final Collection<String> data = Arrays.asList("a", "b", "c");
83  
84          final List<String> a = new ArrayList<>( data );
85          final List<String> b = new ArrayList<>( data );
86  
87          assertEquals(a, b);
88          assertTrue(ListUtils.isEqualList(a, b));
89          a.clear();
90          assertFalse(ListUtils.isEqualList(a, b));
91          assertFalse(ListUtils.isEqualList(a, null));
92          assertFalse(ListUtils.isEqualList(null, b));
93          assertTrue(ListUtils.isEqualList(null, null));
94      }
95  
96      @Test
97      public void testGetFirst() {
98          assertEquals(a, ListUtils.getFirst(fullList));
99          assertThrows(NullPointerException.class, () -> ListUtils.getFirst(null));
100         assertThrows(IndexOutOfBoundsException.class, () -> ListUtils.getFirst(new ArrayList<>()));
101     }
102 
103     @Test
104     public void testGetLast() {
105         assertEquals(e, ListUtils.getLast(fullList));
106         assertThrows(NullPointerException.class, () -> ListUtils.getFirst(null));
107         assertThrows(IndexOutOfBoundsException.class, () -> ListUtils.getFirst(new ArrayList<>()));
108     }
109 
110     @Test
111     public void testHashCode() {
112         final Collection<String> data = Arrays.asList("a", "b", "c");
113 
114         final List<String> a = new ArrayList<>(data);
115         final List<String> b = new ArrayList<>(data);
116 
117         assertEquals(a.hashCode(), b.hashCode());
118         assertEquals(a.hashCode(), ListUtils.hashCodeForList(a));
119         assertEquals(b.hashCode(), ListUtils.hashCodeForList(b));
120         assertEquals(ListUtils.hashCodeForList(a), ListUtils.hashCodeForList(b));
121         a.clear();
122         assertNotEquals(ListUtils.hashCodeForList(a), ListUtils.hashCodeForList(b));
123         assertEquals(0, ListUtils.hashCodeForList(null));
124     }
125 
126     /**
127      * Tests the {@code indexOf} method in {@code ListUtils} class.
128      */
129     @Test
130     public void testIndexOf() {
131         Predicate<String> testPredicate = EqualPredicate.equalPredicate("d");
132         int index = ListUtils.indexOf(fullList, testPredicate);
133         assertEquals(d, fullList.get(index));
134 
135         testPredicate = EqualPredicate.equalPredicate("de");
136         index = ListUtils.indexOf(fullList, testPredicate);
137         assertEquals(index, -1);
138 
139         assertEquals(ListUtils.indexOf(null, testPredicate), -1);
140         assertEquals(ListUtils.indexOf(fullList, null), -1);
141     }
142 
143     /**
144      * Tests intersecting a non-empty list with an empty list.
145      */
146     @Test
147     public void testIntersectEmptyWithEmptyList() {
148         final List<?> empty = Collections.EMPTY_LIST;
149         assertTrue(ListUtils.intersection(empty, empty).isEmpty(), "result not empty");
150     }
151 
152     /**
153      * Tests intersecting two lists in different orders.
154      */
155     @Test
156     public void testIntersectionOrderInsensitivity() {
157         final List<String> one = new ArrayList<>();
158         final List<String> two = new ArrayList<>();
159         one.add("a");
160         one.add("b");
161         two.add("a");
162         two.add("a");
163         two.add("b");
164         two.add("b");
165         assertEquals(ListUtils.intersection(one, two), ListUtils.intersection(two, one));
166     }
167 
168     /**
169      * Tests intersecting a non-empty list with a subset of itself.
170      */
171     @Test
172     public void testIntersectListWithNoOverlapAndDifferentTypes() {
173         @SuppressWarnings("boxing")
174         final List<Integer> other = Arrays.asList(1, 23);
175         assertTrue(ListUtils.intersection(fullList, other).isEmpty());
176     }
177 
178     /**
179      * Tests intersecting a non-empty list with itself.
180      */
181     @Test
182     public void testIntersectListWithSelf() {
183         assertEquals(fullList, ListUtils.intersection(fullList, fullList));
184     }
185 
186     /**
187      * Tests intersecting a non-empty list with a subset of itself.
188      */
189     @Test
190     public void testIntersectNonEmptySubset() {
191         // create a copy
192         final List<String> other = new ArrayList<>(fullList);
193 
194         // remove a few items
195         assertNotNull(other.remove(0));
196         assertNotNull(other.remove(1));
197 
198         // make sure the intersection is equal to the copy
199         assertEquals(other, ListUtils.intersection(fullList, other));
200     }
201 
202     /**
203      * Tests intersecting a non-empty list with an empty list.
204      */
205     @Test
206     public void testIntersectNonEmptyWithEmptyList() {
207         final List<String> empty = Collections.<String>emptyList();
208         assertTrue(ListUtils.intersection(empty, fullList).isEmpty(), "result not empty");
209     }
210 
211     @Test
212     public void testLazyFactoryList() {
213         final List<Integer> list = ListUtils.lazyList(new ArrayList<>(), new Factory<Integer>() {
214 
215             private int index;
216 
217             @Override
218             public Integer create() {
219                 index++;
220                 return Integer.valueOf(index);
221             }
222         });
223 
224         assertNotNull(list.get(5));
225         assertEquals(6, list.size());
226 
227         assertNotNull(list.get(5));
228         assertEquals(6, list.size());
229     }
230 
231     @Test
232     public void testLazyTransformerList() {
233         final List<Integer> offsets = Arrays.asList(3, 5, 1, 5, 3, 6);
234         final List<Integer> list = ListUtils.lazyList(new ArrayList<>(), new Transformer<Integer, Integer>() {
235 
236             private int index;
237 
238             @Override
239             public Integer transform(final Integer input) {
240                 return offsets.get(input) + index++;
241             }
242 
243         });
244 
245         assertNotNull(list.get(5));
246         assertEquals(6, list.size());
247 
248         assertNotNull(list.get(5));
249         assertEquals(6, list.size());
250     }
251 
252     @Test
253     @SuppressWarnings("boxing") // OK in test code
254     public void testLongestCommonSubsequence() {
255         assertAll(
256                 () -> assertThrows(NullPointerException.class, () -> ListUtils.longestCommonSubsequence((List<?>) null, null),
257                         "failed to check for null argument"),
258                 () -> assertThrows(NullPointerException.class, () -> ListUtils.longestCommonSubsequence(Arrays.asList('A'), null),
259                         "failed to check for null argument"),
260                 () -> assertThrows(NullPointerException.class, () -> ListUtils.longestCommonSubsequence(null, Arrays.asList('A')),
261                         "failed to check for null argument")
262         );
263 
264         @SuppressWarnings("unchecked")
265         List<Character> lcs = ListUtils.longestCommonSubsequence(Collections.EMPTY_LIST, Collections.EMPTY_LIST);
266         assertEquals(0, lcs.size());
267 
268         final List<Character> list1 = Arrays.asList('B', 'A', 'N', 'A', 'N', 'A');
269         final List<Character> list2 = Arrays.asList('A', 'N', 'A', 'N', 'A', 'S');
270         lcs = ListUtils.longestCommonSubsequence(list1, list2);
271 
272         List<Character> expected = Arrays.asList('A', 'N', 'A', 'N', 'A');
273         assertEquals(expected, lcs);
274 
275         final List<Character> list3 = Arrays.asList('A', 'T', 'A', 'N', 'A');
276         lcs = ListUtils.longestCommonSubsequence(list1, list3);
277 
278         expected = Arrays.asList('A', 'A', 'N', 'A');
279         assertEquals(expected, lcs);
280 
281         final List<Character> listZorro = Arrays.asList('Z', 'O', 'R', 'R', 'O');
282         lcs = ListUtils.longestCommonSubsequence(list1, listZorro);
283 
284         assertTrue(lcs.isEmpty());
285     }
286 
287     @Test
288     public void testLongestCommonSubsequenceWithString() {
289         assertAll(
290                 () -> assertThrows(NullPointerException.class, () -> ListUtils.longestCommonSubsequence((String) null, null),
291                         "failed to check for null argument"),
292                 () -> assertThrows(NullPointerException.class, () -> ListUtils.longestCommonSubsequence("A", null),
293                         "failed to check for null argument"),
294                 () -> assertThrows(NullPointerException.class, () -> ListUtils.longestCommonSubsequence(null, "A"),
295                         "failed to check for null argument")
296         );
297 
298         String lcs = ListUtils.longestCommonSubsequence(StringUtils.EMPTY, StringUtils.EMPTY);
299         assertEquals(0, lcs.length());
300 
301         final String banana = "BANANA";
302         final String ananas = "ANANAS";
303         lcs = ListUtils.longestCommonSubsequence(banana, ananas);
304 
305         assertEquals("ANANA", lcs);
306 
307         final String atana = "ATANA";
308         lcs = ListUtils.longestCommonSubsequence(banana, atana);
309 
310         assertEquals("AANA", lcs);
311 
312         final String zorro = "ZORRO";
313         lcs = ListUtils.longestCommonSubsequence(banana, zorro);
314 
315         assertEquals(0, lcs.length());
316     }
317 
318     @Test
319     @SuppressWarnings("boxing") // OK in test code
320     public void testPartition() {
321         final List<Integer> strings = new ArrayList<>();
322         for (int i = 0; i <= 6; i++) {
323             strings.add(i);
324         }
325 
326         final List<List<Integer>> partition = ListUtils.partition(strings, 3);
327 
328         assertNotNull(partition);
329         assertEquals(3, partition.size());
330         assertEquals(1, partition.get(2).size());
331         assertAll(
332                 () -> assertThrows(NullPointerException.class, () -> ListUtils.partition(null, 3),
333                         "failed to check for null argument"),
334                 () -> assertThrows(IllegalArgumentException.class, () -> ListUtils.partition(strings, 0),
335                         "failed to check for size argument"),
336                 () -> assertThrows(IllegalArgumentException.class, () -> ListUtils.partition(strings, -10),
337                         "failed to check for size argument")
338         );
339 
340         final List<List<Integer>> partitionMax = ListUtils.partition(strings, Integer.MAX_VALUE);
341         assertEquals(1, partitionMax.size());
342         assertEquals(strings.size(), partitionMax.get(0).size());
343         assertEquals(strings, partitionMax.get(0));
344     }
345 
346     @Test
347     public void testPredicatedList() {
348         final Predicate<Object> predicate = String.class::isInstance;
349         final List<Object> list = ListUtils.predicatedList(new ArrayList<>(), predicate);
350         assertTrue(list instanceof PredicatedList, "returned object should be a PredicatedList");
351         assertAll(
352                 () -> assertThrows(NullPointerException.class, () -> ListUtils.predicatedList(new ArrayList<>(), null),
353                         "Expecting IllegalArgumentException for null predicate."),
354                 () -> assertThrows(NullPointerException.class, () -> ListUtils.predicatedList(null, predicate),
355                         "Expecting IllegalArgumentException for null list.")
356         );
357     }
358 
359     @Test
360     public void testRemoveAll() {
361         final List<String> sub = new ArrayList<>();
362         sub.add(a);
363         sub.add(b);
364         sub.add(x);
365 
366         final List<String> remainder = ListUtils.removeAll(fullList, sub);
367         assertEquals(3, remainder.size());
368         fullList.removeAll(sub);
369         assertEquals(remainder, fullList);
370 
371         assertThrows(NullPointerException.class, () -> ListUtils.removeAll(null, null),
372                 "expecting NullPointerException");
373 
374         assertThrows(NullPointerException.class, () -> ListUtils.removeAll(null, new ArrayList<>()),
375                 "expecting NullPointerException");
376 
377         assertThrows(NullPointerException.class, () -> ListUtils.removeAll(new ArrayList<>(), null),
378                 "expecting NullPointerException");
379     }
380 
381     @Test
382     public void testRetainAll() {
383         final List<String> sub = new ArrayList<>();
384         sub.add(a);
385         sub.add(b);
386         sub.add(x);
387 
388         final List<String> retained = ListUtils.retainAll(fullList, sub);
389         assertEquals(2, retained.size());
390         sub.remove(x);
391         assertEquals(retained, sub);
392         fullList.retainAll(sub);
393         assertEquals(retained, fullList);
394 
395         assertThrows(NullPointerException.class, () -> ListUtils.retainAll(null, null),
396                 "expecting NullPointerException");
397     }
398 
399     @Test
400     @SuppressWarnings("boxing") // OK in test code
401     public void testSelect() {
402         final List<Integer> list = new ArrayList<>();
403         list.add(1);
404         list.add(2);
405         list.add(3);
406         list.add(4);
407         // Ensure that the collection is the input type or a super type
408         final List<Integer> output1 = ListUtils.select(list, EQUALS_TWO);
409         final List<Number> output2 = ListUtils.<Number>select(list, EQUALS_TWO);
410         final HashSet<Number> output3 = CollectionUtils.select(list, EQUALS_TWO, new HashSet<>());
411         assertTrue(CollectionUtils.isEqualCollection(output1, output3));
412         assertEquals(4, list.size());
413         assertEquals(1, output1.size());
414         assertEquals(2, output2.iterator().next());
415     }
416 
417     @Test
418     @SuppressWarnings("boxing") // OK in test code
419     public void testSelectRejected() {
420         final List<Long> list = new ArrayList<>();
421         list.add(1L);
422         list.add(2L);
423         list.add(3L);
424         list.add(4L);
425         final List<Long> output1 = ListUtils.selectRejected(list, EQUALS_TWO);
426         final List<? extends Number> output2 = ListUtils.selectRejected(list, EQUALS_TWO);
427         final HashSet<Number> output3 = CollectionUtils.selectRejected(list, EQUALS_TWO, new HashSet<>());
428         assertTrue(CollectionUtils.isEqualCollection(output1, output2));
429         assertTrue(CollectionUtils.isEqualCollection(output1, output3));
430         assertEquals(4, list.size());
431         assertEquals(3, output1.size());
432         assertTrue(output1.contains(1L));
433         assertTrue(output1.contains(3L));
434         assertTrue(output1.contains(4L));
435     }
436 
437     @Test
438     public void testSubtract() {
439         final List<String> list = new ArrayList<>();
440         list.add(a);
441         list.add(b);
442         list.add(a);
443         list.add(x);
444 
445         final List<String> sub = new ArrayList<>();
446         sub.add(a);
447 
448         final List<String> result = ListUtils.subtract(list, sub);
449         assertEquals(3, result.size());
450 
451         final List<String> expected = new ArrayList<>();
452         expected.add(b);
453         expected.add(a);
454         expected.add(x);
455 
456         assertEquals(expected, result);
457 
458         assertThrows(NullPointerException.class, () -> ListUtils.subtract(list, null),
459                 "expecting NullPointerException");
460     }
461 
462     @Test
463     public void testSubtractNullElement() {
464         final List<String> list = new ArrayList<>();
465         list.add(a);
466         list.add(null);
467         list.add(null);
468         list.add(x);
469 
470         final List<String> sub = new ArrayList<>();
471         sub.add(null);
472 
473         final List<String> result = ListUtils.subtract(list, sub);
474         assertEquals(3, result.size());
475 
476         final List<String> expected = new ArrayList<>();
477         expected.add(a);
478         expected.add(null);
479         expected.add(x);
480 
481         assertEquals(expected, result);
482     }
483 
484 }