Separate Positive and Negative in Java
Problem
Separating positive and negative numbers means grouping an array's elements into two lists based on sign, while keeping each group in its original relative order.
Given an array of integers, print its non-negative numbers and negative numbers as two separate groups.
Java Program
import java.util.ArrayList;
import java.util.List;
public class SeparatePositiveNegative {
public static void main(String[] args) {
int[] arr = {8, -3, 12, -7, 5, -1, 9};
List<Integer> positives = new ArrayList<>();
List<Integer> negatives = new ArrayList<>();
for (int num : arr) {
if (num >= 0) { // zero counts as non-negative here
positives.add(num);
} else {
negatives.add(num);
}
}
System.out.println("Positives: " + positives);
System.out.println("Negatives: " + negatives);
}
}Output
Core Logic
Checking each number's sign, and appending it to one of two lists, sorts every element into a positive group or a negative group in a single pass.
- 1Two empty lists,
positivesandnegatives, are created to hold each group. - 2A for-each loop visits every element of the array.
- 3
num >= 0checks whether the number is zero or positive; a match appends it topositives, otherwise it's appended tonegatives. - 4By the end of the loop, every original element has landed in exactly one of the two lists, in its original relative order.
[8, -3, 12, -7, 5, -1, 9], 8, 12, 5, and 9 land in positives, while -3, -7, and -1 land in negatives.Key Point: Zero is treated as non-negative here — num >= 0 routes it into positives, which is worth confirming matches what a given problem actually wants before reusing this check.
Why: Each element is visited once and appended to one of two lists, whose combined size always equals the original array's length.
Key Concepts
Approach 2: Java 8
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
public class SeparatePositiveNegativeStream {
public static void main(String[] args) {
int[] arr = {8, -3, 12, -7, 5, -1, 9};
// Splits the stream into two groups keyed by true (non-negative) and false (negative)
Map<Boolean, List<Integer>> partitioned = Arrays.stream(arr)
.boxed()
.collect(Collectors.partitioningBy(n -> n >= 0));
System.out.println("Positives: " + partitioned.get(true));
System.out.println("Negatives: " + partitioned.get(false));
}
}
Output
Core Logic
Collectors.partitioningBy() already knows how to split a stream into two groups based on a true/false test — one collector call replaces the whole if/else loop.
- 1
Arrays.stream(arr).boxed()converts theint[]into aStream<Integer>, since collectors work with objects, not primitives. - 2
Collectors.partitioningBy(n -> n >= 0)splits the stream into aMap<Boolean, List<Integer>>, using the same sign test as the loop version. - 3
partitioned.get(true)retrieves the list of elements that passed the test — the non-negative numbers. - 4
partitioned.get(false)retrieves everything that failed it — the negatives.
[8, -3, 12, -7, 5, -1, 9] produces the same two groups as the manual version, keyed by true for positives and false for negatives.Key Point: This is the same partitioningBy() pattern used to separate evens and odds — only the predicate inside it changes.
Why: partitioningBy() still visits every element once while building the two lists behind a single boolean key.