@Test
@DisplayName
("Collectors.groupingBy() - should group elements")
void testCollectorsGroupingBy() {
   
List<String> list = Arrays.asList("apple", "bat", "car", "dog", "elephant");
   
Map<Integer, List<String>> result = list.stream()
            .
collect(Collectors.groupingBy(String::length));
   
   
assertEquals(3, result.get(3).size(), "Should have 3 words of length 3");
   
assertEquals(1, result.get(5).size(), "Should have 1 word of length 5");
   
assertEquals(1, result.get(8).size(), "Should have 1 word of length 8");
}

@Test
@DisplayName
("Collectors.partitioningBy() - should partition elements")
void testCollectorsPartitioningBy() {
   
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
   
Map<Boolean, List<Integer>> result = list.stream()
            .
collect(Collectors.partitioningBy(x -> x % 2 == 0));
   
   
assertEquals(5, result.get(true).size(), "Should have 5 even numbers");
   
assertEquals(5, result.get(false).size(), "Should have 5 odd numbers");
}

@Test
@DisplayName
("Collectors.counting() - should count elements")
void testCollectorsCounting() {
   
List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
   
Long count = list.stream()
            .
collect(Collectors.counting());
   
assertEquals(5, count, "Should count all elements");
}

@Test
@DisplayName
("Collectors.joining() - should join strings")
void testCollectorsJoining() {
   
List<String> list = Arrays.asList("Hello", "World", "Java");
   
String result = list.stream()
            .
collect(Collectors.joining(" "));
   
assertEquals("Hello World Java", result, "Should join strings with space delimiter");
}

@Test
@DisplayName
("Collectors.joining() - should join with prefix and suffix")
void testCollectorsJoiningWithPrefixSuffix() {
   
List<String> list = Arrays.asList("a", "b", "c");
   
String result = list.stream()
            .
collect(Collectors.joining(", ", "[", "]"));
   
assertEquals("[a, b, c]", result, "Should join strings with prefix and suffix");
}

@Test
@DisplayName
("Collectors.mapping() - should transform during collection")
void testCollectorsMapping() {
   
List<String> list = Arrays.asList("apple", "banana", "cherry");
   
List<Integer> result = list.stream()
            .
collect(Collectors.mapping(String::length, Collectors.toList()));
   
assertEquals(Arrays.asList(5, 6, 6), result, "Should map strings to their lengths");
}

@Test
@DisplayName
("Collectors - complex grouping example")
void testCollectorsComplexGrouping() {
   
List<String> list = Arrays.asList("apple", "bat", "car", "dog", "elephant", "fish", "cat", "banana");
   
Map<Integer, Long> result = list.stream()
            .
collect(Collectors.groupingBy(String::length, Collectors.counting()));
   
   
assertEquals(Long.valueOf(4), result.get(3), "Should count 4 words of length 3");
   
assertEquals(Long.valueOf(1), result.get(5), "Should count 1 word of length 5");
   
assertEquals(Long.valueOf(1), result.get(6), "Should count 1 word of length 6");
   
assertEquals(Long.valueOf(1), result.get(4), "Should count 1 word of length 4");
   
assertEquals(Long.valueOf(1), result.get(8), "Should count 1 word of length 8");
}

@Test
@DisplayName
("Collectors - nested grouping example")
void testCollectorsNestedGrouping() {
   
List<String> words = Arrays.asList("apple", "berry", "cherry", "chocolate", "alpha");
   
Map<Integer, Map<Character, List<String>>> result = words.stream()
            .
collect(Collectors.groupingBy(
               
String::length,
               
Collectors.groupingBy(s -> s.charAt(0))
            ));
   
   
assertEquals(2, result.get(5).size(), "Length 5 should have 2 groups by first letter");
   
assertTrue(result.get(5).get('a').contains("apple"), "Should contain 'apple' in group 'a'");
   
assertTrue(result.get(5).get('a').contains("alpha"), "Should contain 'alpha' in group 'a'");
   
assertTrue(result.get(5).get('b').contains("berry"), "Should contain 'berry' in group 'b'");
}

@Test
@DisplayName
("Group numbers by frequency using Collections.frequency() - find duplicates")
void testGroupNumbersByFrequency() {
   
// Create a list with 15 random numbers containing duplicates
   
List<Integer> numbers = Arrays.asList(
       
5, 12, 7, 5, 19, 12, 3, 8, 7, 12, 5, 15, 8, 7, 19
   
);
   
   
// Group by frequency using Collections.frequency() with lambda - use temp variable
    // First create frequency map with temp variable to call frequency only once per number
   
Map<Integer, Integer> frequencyMap = numbers.stream()
            .
distinct()  // Get unique numbers
           
.collect(Collectors.toMap(
               
num -> num// Key mapper
               
num ->
                    
Collections.frequency(numbers, num// Temp variable for frequency
                      // Return frequency

           
)).entrySet().stream()
            .
filter(entry -> entry.getValue() > 1// Only keep duplicates
           
.collect(Collectors.toMap(
               
Map.Entry::getKey,
               
Map.Entry::getValue
           
));
   
   
// Verify the results
   
assertEquals(5, frequencyMap.size(), "Should have 5 numbers with duplicates");
   
assertEquals(3, frequencyMap.get(5), "Number 5 appears 3 times");
   
assertEquals(3, frequencyMap.get(12), "Number 12 appears 3 times");
   
assertEquals(3, frequencyMap.get(7), "Number 7 appears 3 times");
   
assertEquals(2, frequencyMap.get(8), "Number 8 appears 2 times");
   
assertEquals(2, frequencyMap.get(19), "Number 19 appears 2 times");
}

 

                           Top 30 Collection Methods to Memorize

Collection

Methods

List

add, get, set, remove, contains, size, sort

Queue

offer, poll, peek

Stack/Deque

push, pop, peek

Set

add, contains, remove

Map

put, get, getOrDefault, containsKey, remove, putIfAbsent, entrySet, keySet, values

PriorityQueue

offer, poll, peek

Arrays

sort, binarySearch, fill, toString

Collections

sort, reverse, shuffle, max, min

Stream

filter, map, sorted, distinct, collect, count, findFirst

Collectors

toList, toSet, groupingBy, joining, toMap