diff --git a/.github/workflows/maven.yml b/.github/workflows/maven.yml
index 5767a5a..0718126 100644
--- a/.github/workflows/maven.yml
+++ b/.github/workflows/maven.yml
@@ -13,11 +13,11 @@ jobs:
steps:
- uses: actions/checkout@v4
- - name: Set up JDK 17
+ - name: Set up JDK 21
uses: actions/setup-java@v4
with:
- java-version: '17'
- distribution: 'temurin'
+ java-version: '21'
+ distribution: 'corretto'
cache: maven
- name: Build with Maven
run: mvn -B package --file pom.xml
diff --git a/pom.xml b/pom.xml
index 2623864..87bef11 100644
--- a/pom.xml
+++ b/pom.xml
@@ -10,8 +10,8 @@
java_stream_api
- 1.8
- 1.8
+ 21
+ 21
UTF-8
5.13.0
diff --git a/src/main/java/java_stream_api/App.java b/src/main/java/java_stream_api/App.java
index a8f4617..b387904 100644
--- a/src/main/java/java_stream_api/App.java
+++ b/src/main/java/java_stream_api/App.java
@@ -1,14 +1,18 @@
package java_stream_api;
+import java.util.AbstractMap;
import java.util.ArrayList;
import java.util.Arrays;
+import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
+import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import java.util.Objects;
import java.util.Optional;
import java.util.Random;
+import java.util.Set;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Function;
import java.util.stream.Collectors;
@@ -306,6 +310,389 @@ public static List userNamesSortedByLength(List users) {
.collect(Collectors.toList());
}
+ // 51. Group a list of integers by even or odd.
+ public static Map> groupByEvenOdd(List intsList) {
+ return intsList.stream().collect(Collectors.groupingBy(n -> n % 2 == 0));
+ }
+
+ // 52. Find the second largest number in a list.
+ public static Optional secondLargest(List intsList) {
+ return intsList.stream().distinct().sorted(Comparator.reverseOrder()).skip(1).findFirst();
+ }
+
+ // 53. Get a comma-separated list of the first letters of each string.
+ public static String firstLettersAsString(List strList) {
+ return strList.stream()
+ .filter(s -> !s.isEmpty())
+ .map(s -> s.substring(0, 1))
+ .collect(Collectors.joining(","));
+ }
+
+ // 54. Partition strings into those containing digits and those not.
+ public static Map> partitionByContainsDigit(List strList) {
+ return strList.stream().collect(Collectors.partitioningBy(s -> s.matches(".*\\d.*")));
+ }
+
+ // 55. Remove palindromes from a list of strings.
+ public static List removePalindromes(List strList) {
+ return strList.stream()
+ .filter(s -> !s.equals(new StringBuilder(s).reverse().toString()))
+ .collect(Collectors.toList());
+ }
+
+ // 56. Find the most frequent string in a list.
+ public static Optional mostFrequentString(List strList) {
+ return strList.stream()
+ .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()))
+ .entrySet()
+ .stream()
+ .max(Map.Entry.comparingByValue())
+ .map(Map.Entry::getKey);
+ }
+
+ // 57. Remove empty or blank strings from a list.
+ public static List removeBlankStrings(List strList) {
+ return strList.stream()
+ .filter(s -> s != null && !s.trim().isEmpty())
+ .collect(Collectors.toList());
+ }
+
+ // 58. Double only odd numbers in a list.
+ public static List doubleOdds(List intsList) {
+ return intsList.stream().map(n -> n % 2 != 0 ? n * 2 : n).collect(Collectors.toList());
+ }
+
+ // 59. Replace negative numbers in a list with zero.
+ public static List replaceNegativesWithZero(List intsList) {
+ return intsList.stream().map(n -> n < 0 ? 0 : n).collect(Collectors.toList());
+ }
+
+ // 60. Get a map of string lengths to the count of strings of that length.
+ public static Map lengthToCountMap(List strList) {
+ return strList.stream()
+ .collect(Collectors.groupingBy(String::length, Collectors.counting()));
+ }
+
+ // 61. Filter numbers that are perfect squares.
+ public static List filterPerfectSquares(List intsList) {
+ return intsList.stream()
+ .filter(n -> n >= 0 && Math.sqrt(n) % 1 == 0)
+ .collect(Collectors.toList());
+ }
+
+ // 62. Get the first non-repeating string in a list.
+ public static Optional firstNonRepeatingString(List strList) {
+ Map freq =
+ strList.stream()
+ .collect(
+ Collectors.groupingBy(
+ Function.identity(),
+ LinkedHashMap::new,
+ Collectors.counting()));
+ return freq.entrySet().stream()
+ .filter(e -> e.getValue() == 1)
+ .map(Map.Entry::getKey)
+ .findFirst();
+ }
+
+ // 63. Sum of all odd numbers in a list.
+ public static int sumOfOdds(List intsList) {
+ return intsList.stream().filter(n -> n % 2 != 0).mapToInt(Integer::intValue).sum();
+ }
+
+ // 64. Capitalize the first letter of each string.
+ public static List capitalizeFirstLetter(List strList) {
+ return strList.stream()
+ .map(s -> s.isEmpty() ? s : s.substring(0, 1).toUpperCase() + s.substring(1))
+ .collect(Collectors.toList());
+ }
+
+ // 65. Find all pairs of numbers that sum to a given value.
+ public static List pairsThatSumTo(List intsList, int sum) {
+ return intsList.stream()
+ .flatMap(
+ i ->
+ intsList.stream()
+ .filter(j -> j != i && i + j == sum)
+ .map(j -> new int[] {i, j}))
+ .collect(Collectors.toList());
+ }
+
+ // 66. Map each word in a sentence to its frequency (case-insensitive).
+ public static Map wordFrequency(String sentence) {
+ return Arrays.stream(sentence.toLowerCase().split("\\s+"))
+ .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
+ }
+
+ // 67. Repeat each string in a list twice (e.g., "abc" -> "abcabc").
+ public static List repeatStringsTwice(List strList) {
+ return strList.stream().map(s -> s + s).collect(Collectors.toList());
+ }
+
+ // 68. Find unique words from a list of sentences.
+ public static Set uniqueWords(List sentences) {
+ return sentences.stream()
+ .flatMap(s -> Arrays.stream(s.split("\\s+")))
+ .map(String::toLowerCase)
+ .collect(Collectors.toSet());
+ }
+
+ // 69. Sum all elements except the largest and smallest.
+ public static int sumExcludingExtremes(List intsList) {
+ return intsList.stream()
+ .sorted()
+ .skip(1)
+ .limit(Math.max(0, intsList.size() - 2))
+ .mapToInt(Integer::intValue)
+ .sum();
+ }
+
+ // 70. Return the list truncated at the first occurrence of 0 (not including the 0).
+ public static List untilFirstZero(List intsList) {
+ List result = new ArrayList<>();
+ for (Integer n : intsList) {
+ if (n == 0) break;
+ result.add(n);
+ }
+ return result;
+ }
+
+ // 71. Group words by their first letter.
+ public static Map> groupByFirstChar(List strList) {
+ return strList.stream()
+ .filter(s -> !s.isEmpty())
+ .collect(Collectors.groupingBy(s -> s.charAt(0)));
+ }
+
+ // 72. Get the N longest strings in a list.
+ public static List nLongestStrings(List strList, int n) {
+ return strList.stream()
+ .sorted(Comparator.comparingInt(String::length).reversed())
+ .limit(n)
+ .collect(Collectors.toList());
+ }
+
+ // 73. Join all numbers as a string, separated by dashes.
+ public static String joinNumbersWithDash(List intsList) {
+ return intsList.stream().map(String::valueOf).collect(Collectors.joining("-"));
+ }
+
+ // 74. Swap even and odd indexed elements in a list.
+ public static List swapEvenOddIndexed(List list) {
+ List copy = new ArrayList<>(list);
+ for (int i = 0; i < copy.size() - 1; i += 2) {
+ T temp = copy.get(i);
+ copy.set(i, copy.get(i + 1));
+ copy.set(i + 1, temp);
+ }
+ return copy;
+ }
+
+ // 75. Remove all elements except the last N elements.
+ public static List lastNElements(List list, int n) {
+ return list.stream().skip(Math.max(0, list.size() - n)).collect(Collectors.toList());
+ }
+
+ // 76. Partition a list of numbers into primes and non-primes.
+ public static Map> partitionPrimes(List intsList) {
+ return intsList.stream().collect(Collectors.partitioningBy(App::isPrime));
+ }
+
+ private static boolean isPrime(int n) {
+ if (n < 2) return false;
+ for (int i = 2; i * i <= n; i++) if (n % i == 0) return false;
+ return true;
+ }
+
+ // 77. Map string to its reverse.
+ public static Map stringToReverse(List strList) {
+ return strList.stream()
+ .collect(
+ Collectors.toMap(
+ Function.identity(),
+ s -> new StringBuilder(s).reverse().toString()));
+ }
+
+ // 78. Give a list of every prefix of each string (e.g. "abc" -> "a", "ab", "abc").
+ public static List getAllPrefixes(List strList) {
+ return strList.stream()
+ .flatMap(s -> IntStream.rangeClosed(1, s.length()).mapToObj(i -> s.substring(0, i)))
+ .collect(Collectors.toList());
+ }
+
+ // 79. Multiply all numbers in the list.
+ public static int multiplyAll(List intsList) {
+ return intsList.stream().reduce(1, (a, b) -> a * b);
+ }
+
+ // 80. Remove all vowels from all strings in a list.
+ public static List removeVowels(List strList) {
+ return strList.stream()
+ .map(s -> s.replaceAll("[AEIOUaeiou]", ""))
+ .collect(Collectors.toList());
+ }
+
+ // 81. Create a map of strings to number of vowels in each.
+ public static Map vowelCounts(List strList) {
+ return strList.stream()
+ .collect(
+ Collectors.toMap(
+ Function.identity(),
+ s -> s.chars().filter(c -> "AEIOUaeiou".indexOf(c) >= 0).count()));
+ }
+
+ // 82. Count palindromes in a list.
+ public static long countPalindromes(List strList) {
+ return strList.stream()
+ .filter(s -> s.equals(new StringBuilder(s).reverse().toString()))
+ .count();
+ }
+
+ // 83. Collect the indices of all negative numbers.
+ public static List indicesOfNegatives(List intsList) {
+ return IntStream.range(0, intsList.size())
+ .filter(i -> intsList.get(i) < 0)
+ .boxed()
+ .collect(Collectors.toList());
+ }
+
+ // 84. Group numbers by the sum of their digits.
+ public static Map> groupByDigitSum(List intsList) {
+ return intsList.stream()
+ .collect(
+ Collectors.groupingBy(
+ n ->
+ String.valueOf(Math.abs(n))
+ .chars()
+ .map(Character::getNumericValue)
+ .sum()));
+ }
+
+ // 85. For each word, repeat it as many times as its length (e.g., "hi" -> "hihi").
+ public static List repeatByLength(List strList) {
+ return strList.stream().map(s -> s.repeat(s.length())).collect(Collectors.toList());
+ }
+
+ // 86. Check if a string list is sorted (lexicographically).
+ public static boolean isSorted(List strList) {
+ return IntStream.range(0, strList.size() - 1)
+ .allMatch(i -> strList.get(i).compareTo(strList.get(i + 1)) <= 0);
+ }
+
+ // 87. Combine two lists into pairs (zip).
+ public static List> zip(List listA, List listB) {
+ int size = Math.min(listA.size(), listB.size());
+ return IntStream.range(0, size)
+ .mapToObj(i -> new AbstractMap.SimpleEntry<>(listA.get(i), listB.get(i)))
+ .collect(Collectors.toList());
+ }
+
+ // 88. Find all substrings of a string list.
+ public static List allSubstrings(List strList) {
+ return strList.stream()
+ .flatMap(
+ s ->
+ IntStream.range(0, s.length())
+ .boxed()
+ .flatMap(
+ i ->
+ IntStream.rangeClosed(i + 1, s.length())
+ .mapToObj(j -> s.substring(i, j))))
+ .collect(Collectors.toList());
+ }
+
+ // 89. Set negative numbers to their absolute value.
+ public static List setNegativesToAbsolute(List intsList) {
+ return intsList.stream().map(Math::abs).collect(Collectors.toList());
+ }
+
+ // 90. Find all palindromic numbers in a list.
+ public static List palindromicNumbers(List intsList) {
+ return intsList.stream()
+ .filter(
+ n -> {
+ String s = String.valueOf(Math.abs(n));
+ return s.equals(new StringBuilder(s).reverse().toString());
+ })
+ .collect(Collectors.toList());
+ }
+
+ // 91. Map lowercased strings to their frequency.
+ public static Map lowerCaseFrequency(List strList) {
+ return strList.stream()
+ .map(String::toLowerCase)
+ .collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
+ }
+
+ // 92. Filter numbers that are Fibonacci numbers.
+ public static List filterFibonacci(List intsList) {
+ return intsList.stream().filter(App::isFibonacci).collect(Collectors.toList());
+ }
+
+ private static boolean isFibonacci(int n) {
+ long x = 5L * n * n;
+ return isPerfectSquare(x + 4) || isPerfectSquare(x - 4);
+ }
+
+ private static boolean isPerfectSquare(long x) {
+ long s = (long) Math.sqrt(x);
+ return s * s == x;
+ }
+
+ // 93. Get the difference between every consecutive element in a list.
+ public static List differences(List intsList) {
+ return IntStream.range(1, intsList.size())
+ .mapToObj(i -> intsList.get(i) - intsList.get(i - 1))
+ .collect(Collectors.toList());
+ }
+
+ // 94. Count the number of strings ending with a vowel.
+ public static long countEndsWithVowel(List strList) {
+ return strList.stream()
+ .filter(s -> !s.isEmpty() && "aeiouAEIOU".indexOf(s.charAt(s.length() - 1)) != -1)
+ .count();
+ }
+
+ // 95. Extract only the unique sorted words from sentences.
+ public static List uniqueSortedWords(List sentences) {
+ return sentences.stream()
+ .flatMap(s -> Arrays.stream(s.split("\\s+")))
+ .map(String::toLowerCase)
+ .distinct()
+ .sorted()
+ .collect(Collectors.toList());
+ }
+
+ // 96. Find the product of all even numbers.
+ public static int productOfEvens(List intsList) {
+ return intsList.stream().filter(n -> n % 2 == 0).reduce(1, (a, b) -> a * b);
+ }
+
+ // 97. Replace each string with its length in a list.
+ public static List stringLengths(List strList) {
+ return strList.stream().map(String::length).collect(Collectors.toList());
+ }
+
+ // 98. Flatten a list of integer lists into a single list.
+ public static List flattenIntegerLists(List> listOfLists) {
+ return listOfLists.stream().flatMap(Collection::stream).collect(Collectors.toList());
+ }
+
+ // 99. Remove any integers that are multiples of either 3 or 5.
+ public static List removeMultiplesOf3Or5(List intsList) {
+ return intsList.stream().filter(n -> n % 3 != 0 && n % 5 != 0).collect(Collectors.toList());
+ }
+
+ // 100. Get the longest string for each string length.
+ public static Map longestStringForEachLength(List strList) {
+ return strList.stream()
+ .collect(
+ Collectors.toMap(
+ String::length,
+ Function.identity(),
+ (s1, s2) -> s1.length() >= s2.length() ? s1 : s2));
+ }
+
public static void main(String[] args) {
System.out.println("== Java Stream API Methods Demo ==");
diff --git a/src/test/java/java_stream_api/AppTest.java b/src/test/java/java_stream_api/AppTest.java
index dc7c75f..2fec342 100644
--- a/src/test/java/java_stream_api/AppTest.java
+++ b/src/test/java/java_stream_api/AppTest.java
@@ -454,4 +454,443 @@ void testUserNamesSortedByLength() {
void testMainRunsWithoutException() {
assertDoesNotThrow(() -> App.main(new String[] {}));
}
+
+ @Test
+ @DisplayName("Group integers by even and odd")
+ void testGroupByEvenOdd() {
+ List input = Arrays.asList(1, 2, 3, 4);
+ Map> result = App.groupByEvenOdd(input);
+ assertEquals(Arrays.asList(2, 4), result.get(true), "Even numbers not grouped correctly");
+ assertEquals(Arrays.asList(1, 3), result.get(false), "Odd numbers not grouped correctly");
+ }
+
+ @Test
+ @DisplayName("Find the second largest element")
+ void testSecondLargest() {
+ List input = Arrays.asList(10, 20, 30, 40);
+ assertEquals(Optional.of(30), App.secondLargest(input), "Second largest number incorrect");
+ }
+
+ @Test
+ @DisplayName("Get comma-separated list of first letters")
+ void testFirstLettersAsString() {
+ List input = Arrays.asList("apple", "banana", "carrot");
+ String result = App.firstLettersAsString(input);
+ assertEquals("a,b,c", result, "First letters not joined correctly");
+ }
+
+ @Test
+ @DisplayName("Partition strings by presence of digits")
+ void testPartitionByContainsDigit() {
+ List input = Arrays.asList("abc", "a2b", "xyz3", "nope");
+ Map> result = App.partitionByContainsDigit(input);
+ assertEquals(
+ Arrays.asList("a2b", "xyz3"),
+ result.get(true),
+ "Strings with digits not partitioned correctly");
+ assertEquals(
+ Arrays.asList("abc", "nope"),
+ result.get(false),
+ "Strings without digits not partitioned correctly");
+ }
+
+ @Test
+ @DisplayName("Remove palindromes from a list")
+ void testRemovePalindromes() {
+ List input = Arrays.asList("madam", "apple", "kayak");
+ List result = App.removePalindromes(input);
+ assertTrue(result.contains("apple"), "Non-palindromes were removed incorrectly");
+ assertFalse(result.contains("madam"), "Palindrome was not removed");
+ assertFalse(result.contains("kayak"), "Palindrome was not removed");
+ }
+
+ @Test
+ @DisplayName("Find most frequent string")
+ void testMostFrequentString() {
+ List input = Arrays.asList("apple", "banana", "apple", "carrot", "banana", "apple");
+ Optional result = App.mostFrequentString(input);
+ assertEquals(Optional.of("apple"), result, "Most frequent string not correct");
+ }
+
+ @Test
+ @DisplayName("Remove blank and empty strings")
+ void testRemoveBlankStrings() {
+ List input = Arrays.asList("apple", "", " ", "banana");
+ List result = App.removeBlankStrings(input);
+ assertEquals(
+ Arrays.asList("apple", "banana"), result, "Blank or empty strings not removed");
+ }
+
+ @Test
+ @DisplayName("Double odd numbers")
+ void testDoubleOdds() {
+ List input = Arrays.asList(1, 2, 3);
+ List result = App.doubleOdds(input);
+ assertEquals(Arrays.asList(2, 2, 6), result, "Odds were not doubled correctly");
+ }
+
+ @Test
+ @DisplayName("Replace negatives with zero")
+ void testReplaceNegativesWithZero() {
+ List input = Arrays.asList(-5, 3, 0, -1);
+ List result = App.replaceNegativesWithZero(input);
+ assertEquals(
+ Arrays.asList(0, 3, 0, 0), result, "Negatives not replaced with zero correctly");
+ }
+
+ @Test
+ @DisplayName("Map string-lengths to their count")
+ void testLengthToCountMap() {
+ List input = Arrays.asList("a", "bb", "b", "aaa");
+ Map result = App.lengthToCountMap(input);
+ assertEquals(2L, result.get(1), "Count for length 1 incorrect");
+ assertEquals(1L, result.get(2), "Count for length 2 incorrect");
+ assertEquals(1L, result.get(3), "Count for length 3 incorrect");
+ }
+
+ @Test
+ @DisplayName("Filter perfect squares")
+ void testFilterPerfectSquares() {
+ List input = Arrays.asList(1, 2, 4, 9, 16, 20);
+ List result = App.filterPerfectSquares(input);
+ assertEquals(Arrays.asList(1, 4, 9, 16), result, "Perfect squares not filtered correctly");
+ }
+
+ @Test
+ @DisplayName("Find first non-repeating string")
+ void testFirstNonRepeatingString() {
+ List input = Arrays.asList("a", "b", "a", "c", "b", "d");
+ Optional result = App.firstNonRepeatingString(input);
+ assertEquals(Optional.of("c"), result, "First non-repeating string not correct");
+ }
+
+ @Test
+ @DisplayName("Sum all odd numbers")
+ void testSumOfOdds() {
+ List input = Arrays.asList(1, 2, 3, 4, 5);
+ int sum = App.sumOfOdds(input);
+ assertEquals(9, sum, "Sum of odd numbers incorrect");
+ }
+
+ @Test
+ @DisplayName("Capitalize first letter of each string")
+ void testCapitalizeFirstLetter() {
+ List input = Arrays.asList("apple", "banana", "cat");
+ List result = App.capitalizeFirstLetter(input);
+ assertEquals(
+ Arrays.asList("Apple", "Banana", "Cat"),
+ result,
+ "Strings not capitalized correctly");
+ }
+
+ @Test
+ @DisplayName("Find all pairs that sum to a given value")
+ void testPairsThatSumTo() {
+ List input = Arrays.asList(1, 2, 3, 4);
+ List result = App.pairsThatSumTo(input, 5);
+ assertTrue(
+ result.stream().anyMatch(arr -> arr[0] + arr[1] == 5),
+ "Pairs not found for sum correctly");
+ }
+
+ @Test
+ @DisplayName("Map word frequency in sentence, case-insensitive")
+ void testWordFrequency() {
+ String sentence = "apple banana apple Carrot banana carrot";
+ Map result = App.wordFrequency(sentence);
+ assertEquals(2L, result.get("banana"), "Banana frequency incorrect");
+ assertEquals(2L, result.get("carrot"), "Carrot frequency incorrect");
+ }
+
+ @Test
+ @DisplayName("Repeat each string twice")
+ void testRepeatStringsTwice() {
+ List input = Arrays.asList("abc", "de");
+ List result = App.repeatStringsTwice(input);
+ assertEquals(
+ Arrays.asList("abcabc", "dede"), result, "Strings not repeated twice correctly");
+ }
+
+ @Test
+ @DisplayName("Unique words from sentences")
+ void testUniqueWords() {
+ List sentences = Arrays.asList("the cat", "the dog");
+ Set result = App.uniqueWords(sentences);
+ assertTrue(
+ result.contains("cat") && result.contains("the"),
+ "Unique words not extracted correctly");
+ }
+
+ @Test
+ @DisplayName("Sum excluding largest and smallest numbers")
+ void testSumExcludingExtremes() {
+ List input = Arrays.asList(10, 20, 30, 40);
+ int sum = App.sumExcludingExtremes(input);
+ assertEquals(50, sum, "Sum excluding extremes incorrect");
+ }
+
+ @Test
+ @DisplayName("Elements until first zero")
+ void testUntilFirstZero() {
+ List input = Arrays.asList(1, 2, 0, 5);
+ List result = App.untilFirstZero(input);
+ assertEquals(Arrays.asList(1, 2), result, "Elements until zero not found correctly");
+ }
+
+ @Test
+ @DisplayName("Group words by first character")
+ void testGroupByFirstChar() {
+ List input = Arrays.asList("apple", "arm", "bat");
+ Map> result = App.groupByFirstChar(input);
+ assertEquals(
+ Arrays.asList("apple", "arm"),
+ result.get('a'),
+ "Grouping by first character incorrect");
+ }
+
+ @Test
+ @DisplayName("Get N longest strings")
+ void testNLongestStrings() {
+ List input = Arrays.asList("a", "ab", "abc");
+ List result = App.nLongestStrings(input, 2);
+ assertEquals(
+ Arrays.asList("abc", "ab"), result, "N longest strings not selected correctly");
+ }
+
+ @Test
+ @DisplayName("Join numbers with dash")
+ void testJoinNumbersWithDash() {
+ List input = Arrays.asList(1, 2, 3);
+ String result = App.joinNumbersWithDash(input);
+ assertEquals("1-2-3", result, "Numbers not joined with dash correctly");
+ }
+
+ @Test
+ @DisplayName("Swap even and odd indexed elements")
+ void testSwapEvenOddIndexed() {
+ List input = Arrays.asList("a", "b", "c", "d");
+ List result = App.swapEvenOddIndexed(input);
+ assertEquals(Arrays.asList("b", "a", "d", "c"), result, "Even and odd indices not swapped");
+ }
+
+ @Test
+ @DisplayName("Return last N elements of list")
+ void testLastNElements() {
+ List input = Arrays.asList(1, 2, 3, 4, 5);
+ List result = App.lastNElements(input, 2);
+ assertEquals(Arrays.asList(4, 5), result, "Last N elements not returned correctly");
+ }
+
+ @Test
+ @DisplayName("Partition numbers into primes and non-primes")
+ void testPartitionPrimes() {
+ List input = Arrays.asList(2, 4, 5, 6);
+ Map> result = App.partitionPrimes(input);
+ assertEquals(Arrays.asList(2, 5), result.get(true), "Primes not partitioned correctly");
+ }
+
+ @Test
+ @DisplayName("Map strings to their reverse")
+ void testStringToReverse() {
+ List input = Arrays.asList("abc", "de");
+ Map result = App.stringToReverse(input);
+ assertEquals("cba", result.get("abc"), "String reverse incorrect");
+ assertEquals("ed", result.get("de"), "String reverse incorrect");
+ }
+
+ @Test
+ @DisplayName("Get all prefixes of each string")
+ void testGetAllPrefixes() {
+ List input = Arrays.asList("ab");
+ List result = App.getAllPrefixes(input);
+ assertTrue(result.containsAll(Arrays.asList("a", "ab")), "String prefixes not found");
+ }
+
+ @Test
+ @DisplayName("Multiply all numbers in list")
+ void testMultiplyAll() {
+ List input = Arrays.asList(2, 3, 4);
+ int product = App.multiplyAll(input);
+ assertEquals(24, product, "Product not calculated correctly");
+ }
+
+ @Test
+ @DisplayName("Remove all vowels from strings")
+ void testRemoveVowels() {
+ List input = Arrays.asList("apple", "sky");
+ List result = App.removeVowels(input);
+ assertEquals(Arrays.asList("ppl", "sky"), result, "Vowels not removed correctly");
+ }
+
+ @Test
+ @DisplayName("Count vowels in strings (per item)")
+ void testVowelCounts() {
+ List input = Arrays.asList("apple", "sky");
+ Map result = App.vowelCounts(input);
+ assertEquals(2L, result.get("apple"), "Vowel count of 'apple' incorrect");
+ assertEquals(0L, result.get("sky"), "Vowel count of 'sky' incorrect");
+ }
+
+ @Test
+ @DisplayName("Count the number of palindromes")
+ void testCountPalindromes() {
+ List input = Arrays.asList("madam", "abba", "apple");
+ long count = App.countPalindromes(input);
+ assertEquals(2L, count, "Number of palindromes incorrect");
+ }
+
+ @Test
+ @DisplayName("Collect indices of negative numbers")
+ void testIndicesOfNegatives() {
+ List input = Arrays.asList(-1, 2, -3, 4);
+ List result = App.indicesOfNegatives(input);
+ assertEquals(Arrays.asList(0, 2), result, "Indices of negatives incorrect");
+ }
+
+ @Test
+ @DisplayName("Group numbers by digit sum")
+ void testGroupByDigitSum() {
+ List input = Arrays.asList(12, 21, 3, 30);
+ Map> result = App.groupByDigitSum(input);
+ assertTrue(result.get(3).contains(3), "Digit sum grouping incorrect - 3");
+ assertTrue(
+ result.get(3).contains(12) || result.get(3).contains(21),
+ "Digit sum grouping incorrect - 12/21");
+ }
+
+ @Test
+ @DisplayName("Repeat each word by its length")
+ void testRepeatByLength() {
+ List input = Arrays.asList("hi", "a");
+ List result = App.repeatByLength(input);
+ assertEquals(Arrays.asList("hihi", "a"), result, "Repeat by length incorrect");
+ }
+
+ @Test
+ @DisplayName("Check if string list is sorted")
+ void testIsSorted() {
+ List input = Arrays.asList("a", "b", "c");
+ assertTrue(App.isSorted(input), "List should be sorted");
+ List input2 = Arrays.asList("b", "a", "c");
+ assertFalse(App.isSorted(input2), "List should be unsorted");
+ }
+
+ @Test
+ @DisplayName("Zip two lists into entry pairs")
+ void testZip() {
+ List l1 = Arrays.asList("a", "b");
+ List l2 = Arrays.asList(1, 2);
+ List> result = App.zip(l1, l2);
+ assertEquals("a", result.get(0).getKey(), "First element of zipped pair incorrect");
+ assertEquals(1, result.get(0).getValue(), "Second element of zipped pair incorrect");
+ }
+
+ @Test
+ @DisplayName("Get all substrings from string list")
+ void testAllSubstrings() {
+ List input = Arrays.asList("ab");
+ List result = App.allSubstrings(input);
+ assertTrue(result.containsAll(Arrays.asList("a", "ab", "b")), "All substrings not found");
+ }
+
+ @Test
+ @DisplayName("Set all numbers to absolute value")
+ void testSetNegativesToAbsolute() {
+ List input = Arrays.asList(-1, 2, -3);
+ List result = App.setNegativesToAbsolute(input);
+ assertEquals(Arrays.asList(1, 2, 3), result, "Negative numbers not converted to absolute");
+ }
+
+ @Test
+ @DisplayName("Find all palindromic numbers")
+ void testPalindromicNumbers() {
+ List input = Arrays.asList(121, 12, 22, 132);
+ List result = App.palindromicNumbers(input);
+ assertTrue(result.containsAll(Arrays.asList(121, 22)), "Palindromic numbers not found");
+ }
+
+ @Test
+ @DisplayName("Map lowercased strings to their frequency")
+ void testLowerCaseFrequency() {
+ List input = Arrays.asList("a", "A", "b");
+ Map result = App.lowerCaseFrequency(input);
+ assertEquals(2L, result.get("a"), "Lowercase frequency incorrect");
+ }
+
+ @Test
+ @DisplayName("Filter Fibonacci numbers")
+ void testFilterFibonacci() {
+ List input = Arrays.asList(2, 3, 5, 6);
+ List result = App.filterFibonacci(input);
+ assertTrue(result.containsAll(Arrays.asList(2, 3, 5)), "Fibonacci numbers not filtered");
+ assertFalse(result.contains(6), "Non-Fibonacci number included");
+ }
+
+ @Test
+ @DisplayName("Get all differences between consecutive numbers")
+ void testDifferences() {
+ List input = Arrays.asList(1, 3, 6, 10);
+ List result = App.differences(input);
+ assertEquals(
+ Arrays.asList(2, 3, 4),
+ result,
+ "Differences between consecutive elements incorrect");
+ }
+
+ @Test
+ @DisplayName("Count how many strings end with a vowel")
+ void testCountEndsWithVowel() {
+ List input = Arrays.asList("apple", "banana", "dog");
+ long count = App.countEndsWithVowel(input);
+ assertEquals(2L, count, "Strings ending with vowel counted incorrectly");
+ }
+
+ @Test
+ @DisplayName("Get unique sorted words out of sentences")
+ void testUniqueSortedWords() {
+ List input = Arrays.asList("the dog", "The Cat");
+ List result = App.uniqueSortedWords(input);
+ assertEquals(Arrays.asList("cat", "dog", "the"), result, "Unique sorted words not found");
+ }
+
+ @Test
+ @DisplayName("Get product of all even numbers")
+ void testProductOfEvens() {
+ List input = Arrays.asList(2, 3, 4, 5);
+ int result = App.productOfEvens(input);
+ assertEquals(8, result, "Product of even numbers incorrect");
+ }
+
+ @Test
+ @DisplayName("Replace each string by its length")
+ void testStringLengths() {
+ List input = Arrays.asList("a", "abc");
+ List result = App.stringLengths(input);
+ assertEquals(Arrays.asList(1, 3), result, "String lengths not mapped correctly");
+ }
+
+ @Test
+ @DisplayName("Flatten a list of integer lists")
+ void testFlattenIntegerLists() {
+ List> input = Arrays.asList(Arrays.asList(1, 2), Arrays.asList(3));
+ List result = App.flattenIntegerLists(input);
+ assertEquals(Arrays.asList(1, 2, 3), result, "Integer lists not flattened");
+ }
+
+ @Test
+ @DisplayName("Remove multiples of 3 or 5")
+ void testRemoveMultiplesOf3Or5() {
+ List input = Arrays.asList(3, 5, 7, 9, 10, 11);
+ List result = App.removeMultiplesOf3Or5(input);
+ assertEquals(Arrays.asList(7, 11), result, "Multiples of 3 or 5 not removed");
+ }
+
+ @Test
+ @DisplayName("Longest string for each string length")
+ void testLongestStringForEachLength() {
+ List input = Arrays.asList("a", "bb", "cc", "bbb");
+ Map result = App.longestStringForEachLength(input);
+ assertEquals("a", result.get(1), "Longest string for length 1 incorrect");
+ assertEquals("bbb", result.get(3), "Longest string for length 3 incorrect");
+ }
}