💡Challenging Java Stream interview

A cup of JAVA coffee with NeeSri
7 min readFeb 3, 2025

--

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:

  1. flatMap(s -> Arrays.stream(s.split(","))) → Splits each string by commas and flattens into a single stream.
  2. map(String::trim) → Trims any extra spaces.
  3. filter(s -> s.matches("\\d+")) → Filters out non-numeric values.
  4. map(Integer::parseInt) → Converts valid strings to integers.
  5. distinct() → Removes duplicate numbers.
  6. sorted(Comparator.reverseOrder()) → Sorts numbers in descending order.
  7. 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):

  1. Extract only valid integers (both positive and negative).
  2. Ignore duplicates.
  3. Sort even numbers in descending order and odd numbers in ascending order.
  4. 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:

  1. Splitting Strings: Uses flatMap to split each string by commas.
  2. Filtering Valid Numbers: Uses regex in isValidInteger() to remove special characters and words.
  3. Parsing & Removing Duplicates: Converts valid strings to integers and removes duplicates.
  4. Partitioning: Uses Collectors.partitioningBy(n -> n % 2 == 0) to separate even and odd numbers.
  5. 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);
}
}

--

--

Responses (1)