💡Challenging Java Stream interview
Lets play with challenging questions:
🔴 Problem Statement:
Given a List<String>
containing comma-separated numbers, convert it into a List<Integer>
, ensuring:
- Only unique numbers are considered.
- The numbers are sorted in descending order.
- Any invalid (non-numeric) entries are ignored.
Example Input:
List<String> input = Arrays.asList("1,2,3", "3,4,5", "6,abc,7", "8,9,10", "10,2,4");
Expected Output:
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
🟢Solution:
List<String> input = Arrays.asList("1,2,3", "3,4,5", "6,abc,7", "8,9,10", "10,2,4");
List<Integer> listInt= input.stream()
.flatMap(s-> Arrays.stream(s.split(",")))
.map(String->String.trim())
.filter(s -> s.matches("\\d+"))
.map(Integer::parseInt)
.distinct()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
System.out.println(listInt);
//----OUTPUT----->
[10, 9, 8, 7, 6, 5, 4, 3, 2, 1]
Explanation:
flatMap(s -> Arrays.stream(s.split(",")))
→ Splits each string by commas and flattens into a single stream.map(String::trim)
→ Trims any extra spaces.filter(s -> s.matches("\\d+"))
→ Filters out non-numeric values.map(Integer::parseInt)
→ Converts valid strings to integers.distinct()
→ Removes duplicate numbers.sorted(Comparator.reverseOrder())
→ Sorts numbers in descending order.collect(Collectors.toList())
→ Collects the final list.
🔴 Problem Statement:
Given a List<String>
where each string contains comma-separated numbers (possibly containing negative numbers, duplicates, and invalid values like special characters or words):
- Extract only valid integers (both positive and negative).
- Ignore duplicates.
- Sort even numbers in descending order and odd numbers in ascending order.
- Maintain this format:
[EVEN_DESCENDING, ODD_ASCENDING]
.
Example Input:
List<String> input =
Arrays.asList("10,-5,2,3", "3,4,5,-2", "-6,abc,7", "8,9,10", "10,-2,4,@,5");
Expected Output:
[10, 8, 4, 2, -2, -6, -5, 3, 5, 7, 9]
🟢Solution 1-> using partitioningBy (only this is it is coming in two different bracket)
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Practice {
public static void main(String[] args) {
List<String> input = Arrays.asList(
"3, 5, -2, 10, -7, apple, 3, 4",
"banana, -2, 10, 6, -1, 7, 5, 5",
"8, -3, 12, 4, 7, -6, 6, xyz"
);
// Process the list
Map<Boolean, List<Integer>> partitionedNumbers = input.stream()
// Split each string by comma and process each token
.flatMap(str -> Arrays.stream(str.split(",")))
// Trim spaces and filter valid integers
.map(String::trim)
.filter(Practice::isValidInteger)
.map(Integer::parseInt)
// Remove duplicates
.distinct()
// Partition into even and odd numbers
.collect(Collectors.partitioningBy(n -> n % 2 == 0));
// Sort even numbers in descending order
List<Integer> evens = partitionedNumbers.get(true).stream()
.sorted(Comparator.reverseOrder())
.collect(Collectors.toList());
// Sort odd numbers in ascending order
List<Integer> odds = partitionedNumbers.get(false).stream()
.sorted()
.collect(Collectors.toList());
// Print the formatted result
System.out.println(evens + ","+ odds);
}
// Check if a string is a valid integer (positive or negative)
private static boolean isValidInteger(String str) {
return str.matches("-?\\d+");
}
}
//------------OUTPUT-------//
[12, 10, 8, 6, 4, -2, -6],[-7, -3, -1, 3, 5, 7]
Explanation:
- Splitting Strings: Uses
flatMap
to split each string by commas. - Filtering Valid Numbers: Uses regex in
isValidInteger()
to remove special characters and words. - Parsing & Removing Duplicates: Converts valid strings to integers and removes duplicates.
- Partitioning: Uses
Collectors.partitioningBy(n -> n % 2 == 0)
to separate even and odd numbers. - Sorting:
- Even numbers sorted in descending order (
Comparator.reverseOrder()
). - Odd numbers sorted in ascending order (
Comparator.naturalOrder()
).
6. Printing the Output: Displays results in [EVEN_DESCENDING, ODD_ASCENDING]
format.
🟢Solution 2->
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Practice {
public static void main(String[] args) {
List<String> input = Arrays.asList(
"3, 5, -2, 10, -7, apple, 3, 4",
"banana, -2, 10, 6, -1, 7, 5, 5",
"8, -3, 12, 4, 7, -6, 6, xyz"
);
// Process input
List<Integer> numbers = input.stream()
.flatMap(str -> Arrays.stream(str.split(","))) // Split each string by ","
.map(String::trim) // Trim whitespace
.filter(Practice::isValidInteger) // Keep only valid numbers
.map(Integer::parseInt) // Convert to Integer
.distinct() // Remove duplicates
.collect(Collectors.toList());
// Separate even and odd numbers
List<Integer> evens = numbers.stream()
.filter(n -> n % 2 == 0)
.sorted(Comparator.reverseOrder()) // Even numbers in descending order
.collect(Collectors.toList());
List<Integer> odds = numbers.stream()
.filter(n -> n % 2 != 0)
.sorted() // Odd numbers in ascending order
.collect(Collectors.toList());
// Print the result
System.out.println(evens + ", " + odds);
}
// Check if a string is a valid integer (positive or negative)
private static boolean isValidInteger(String str) {
return str.matches("-?\\d+");
}
}
//-------OUTPUT----//
[12, 10, 8, 6, 4, -2, -6], [-7, -3, -1, 3, 5, 7]
🟢Solution 3->Collectors.teeing()
import java.util.Arrays;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class Practice {
public static void main(String[] args) {
List<String> words = List.of("apple", "apricot", "banana", "avocado", "artichoke", "almond", "grape");
List<String> result = words.stream()
.collect(Collectors.filtering(
word -> word.startsWith("a") && word.length() > 5, // Filtering condition
Collectors.toList() // Collect into List
));
System.out.println(result);
List<String> input = Arrays.asList(
"3, 5, -2, 10, -7, apple, 3, 4",
"banana, -2, 10, 6, -1, 7, 5, 5",
"8, -3, 12, 4, 7, -6, 6, xyz"
);
// another way using Collectors.teeing()
String result = input.stream()
// Split each string into individual numbers
.flatMap(str -> Arrays.stream(str.split(",")))
// Trim spaces and filter valid integers
.map(String::trim)
.filter(Practice::isValidInteger)
.map(Integer::parseInt)
// Remove duplicates
.distinct()
// Partition into even and odd numbers
.collect(Collectors.teeing(
Collectors.filtering(n -> n % 2 == 0, Collectors.toList()),
Collectors.filtering(n -> n % 2 != 0, Collectors.toList()),
(evens, odds) -> {
evens.sort(Comparator.reverseOrder()); // Sort evens in descending
odds.sort(Comparator.naturalOrder()); // Sort odds in ascending
return evens + ", " + odds;
}
));
System.out.println(result);
}
// Check if a string is a valid integer (positive or negative)
private static boolean isValidInteger(String str) {
return str.matches("-?\\d+");
}
}
//---OUTPUT---//
[10, 8, 4, 2, -2, -6, -5, 3, 5, 7, 9]
🔴 Problem Statement:
How would you find the longest and shortest strings from a list using Collectors.teeing()
?
🟢Solution 1->Using Java 12 Collectors.teeing
import java.util.List;
import java.util.stream.Collectors;
public class LongestShortestString {
public static void main(String[] args) {
List<String> words = List.of("apple", "banana", "cherry", "date", "elderberry");
var result = words.stream()
.collect(Collectors.teeing(
Collectors.maxBy((a, b) -> Integer.compare(a.length(), b.length())), // Longest
Collectors.minBy((a, b) -> Integer.compare(a.length(), b.length())), // Shortest
(longest, shortest) ->
"Longest: " + longest.orElse("None") + ", Shortest: " + shortest.orElse("None")
));
System.out.println(result);
}
}
//-----OUTPUT----//
Longest: elderberry, Shortest: date
🟢Solution 2->Java 8 Solution (Without teeing()
)
import java.util.List;
import java.util.Comparator;
public class LongestShortestJava8 {
public static void main(String[] args) {
List<String> words = List.of("apple", "banana", "cherry", "date", "elderberry");
String longest = words.stream()
.max(Comparator.comparingInt(String::length))
.orElse("None");
String shortest = words.stream()
.min(Comparator.comparingInt(String::length))
.orElse("None");
System.out.println("Longest: " + longest + ",
Shortest: " + shortest);
}
}
🔴 Problem Statement:
Count Even and Odd Numbers and Return Their Difference?
🟢Solution 1->Using Java 12 Collectors.teeing
import java.util.List;
import java.util.stream.Collectors;
public class EvenOddDifference {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
int difference = numbers.stream()
.collect(Collectors.teeing(
Collectors.filtering(n -> n % 2 == 0, Collectors.counting()), // Even count
Collectors.filtering(n -> n % 2 != 0, Collectors.counting()), // Odd count
(evenCount, oddCount) -> (int) (evenCount - oddCount) // Difference
));
System.out.println("Difference between even and odd counts: " + difference);
}
}
//-----------output-----//
Difference between even and odd counts: 0
🟢Solution 2->Java 8 Solution (Without teeing()
)
import java.util.List;
public class EvenOddDifferenceJava8 {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
long evenCount = numbers.stream()
.filter(n -> n % 2 == 0).count();
long oddCount = numbers.stream()
.filter(n -> n % 2 != 0).count();
int difference = (int) (evenCount - oddCount);
System.out.println("Difference between even and odd counts: "
+ difference);
}
}
🔴 Problem Statement:
Merge Two Lists — One with Numbers >5 and One with Numbers ≤5 (Java 8 Alternative)
🟢Solution 1->Using Java 12 Collectors.teeing
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class CombineTwoLists {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 6, 3, 7, 4, 8, 2, 9, 5);
List<Integer> combined = numbers.stream()
.collect(Collectors.teeing(
Collectors.filtering(n -> n > 5, Collectors.toList()), // Greater than 5
Collectors.filtering(n -> n <= 5, Collectors.toList()), // 5 or less
(greater, lesser) ->
Stream.concat(greater.stream(), lesser.stream()) // Merge lists
.collect(Collectors.toList())
));
System.out.println(combined);
}
}
//-----output-----//
[6, 7, 8, 9, 1, 3, 4, 2, 5]
🟢Solution 2->Java 8 Solution (Without teeing()
)
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
public class MergeTwoListsJava8 {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, 6, 3, 7, 4, 8, 2, 9, 5);
List<Integer> greater = numbers.stream()
.filter(n -> n > 5).collect(Collectors.toList());
List<Integer> lesser = numbers.stream()
.filter(n -> n <= 5).collect(Collectors.toList());
List<Integer> combined =
Stream.concat(greater.stream(), lesser.stream())
.collect(Collectors.toList());
System.out.println(combined);
}
}
//-----output-----//
[6, 7, 8, 9, 1, 3, 4, 2, 5]
✅ Manually filters and concatenates streams instead of teeing()
.
🔴 Problem Statement:
Find the Average of Positive Numbers and Sum of Negative Numbers
🟢Solution 1->Using Java 12 Collectors.teeing
import java.util.List;
import java.util.stream.Collectors;
public class AverageAndSum {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, -2, 3, -4, 5, -6);
var result = numbers.stream()
.collect(Collectors.teeing(
Collectors.filtering(n -> n > 0, Collectors.averagingInt(Integer::intValue)), // Average of positives
Collectors.filtering(n -> n < 0, Collectors.summingInt(Integer::intValue)), // Sum of negatives
(avgPositives, sumNegatives) ->
"Average of Positives: " + avgPositives + ", Sum of Negatives: " + sumNegatives
));
System.out.println(result);
}
}
//-----OUTPUT----//
Average of Positives: 3.0, Sum of Negatives: -12
🟢Solution 2->Java 8 Solution (Without teeing()
)
import java.util.List;
import java.util.OptionalDouble;
public class AverageSumJava8 {
public static void main(String[] args) {
List<Integer> numbers = List.of(1, -2, 3, -4, 5, -6);
OptionalDouble avgPositives = numbers.stream()
.filter(n -> n > 0)
.mapToInt(Integer::intValue)
.average();
int sumNegatives = numbers.stream()
.filter(n -> n < 0)
.mapToInt(Integer::intValue)
.sum();
System.out.println("Average of Positives: " + (avgPositives.isPresent() ? avgPositives.getAsDouble() : "None")
+ ", Sum of Negatives: " + sumNegatives);
}
}
🔴 Problem Statement:
Count Words With and Without Vowels
🟢Solution 1->Using Java 12 Collectors.teeing
import java.util.List;
import java.util.stream.Collectors;
public class VowelCount {
public static void main(String[] args) {
List<String> words = List.of("apple", "sky", "banana", "try", "grape");
var vowelCounts = words.stream()
.collect(Collectors.teeing(
Collectors.filtering(word -> word.matches(".*[aeiou].*"), Collectors.counting()), // With vowels
Collectors.filtering(word -> !word.matches(".*[aeiou].*"), Collectors.counting()), // Without vowels
(withVowels, withoutVowels) ->
"With vowels: " + withVowels + ", Without vowels: " + withoutVowels
));
System.out.println(vowelCounts);
}
}
🟢Solution 2->Java 8 Solution (Without teeing()
)
import java.util.List;
public class VowelCountJava8 {
public static void main(String[] args) {
List<String> words = List.of("apple", "sky", "banana", "try", "grape");
long withVowels = words.stream()
.filter(word -> word.matches(".*[aeiou].*"))
.count();
long withoutVowels = words.stream()
.filter(word -> !word.matches(".*[aeiou].*"))
.count();
System.out.println("With vowels: " + withVowels + ", Without vowels: " + withoutVowels);
}
}