Streams
Source
- Array, Collection, generator function, I/O channel
- Primitive Streams
IntStream
LongStream
DoubleStream
- Boxing and Unboxing
int[] nums = {4, 3, 7, 8, 1};
// boxing
List<Integer> numbers = Stream.of(nums).boxed().toList();
// unboxing
int[] finalNums = numbers.mapToInt(n -> n).toArray();
Collectors
- .groupingBy(keyMapper)
- .groupingBy(keyMapper, Collector)
- .toList()
- .toSet()
- .toMap()
- .joining(delimiter) — String case
- .reducing(T, BinaryOperator)
- .collectingAndThen(Collector)
- .counting()
- .minBy(Comparator)
- .maxBy(Comparator)
- Sum
- summingInt(mapper)
- summingLong(mapper)
- summingDouble(mapper)
- Average
- averagingInt(mapper)
- averagingLong(mapper)
- averagingDouble(mapper)
- Summary
- summarizingInt(mapper)
- summarizingLong(mapper)
- summarizingDouble(mapper)
- methods:
- average, count, sum, min, max
Sum and avg. of all the integers
int[] nums = {4, 3, 7, 8, 1};
System.out.println(Arrays.stream(nums).sum()); // IntStream.count()
List<Integer> numbers = Arrays.stream(nums) // IntStream to List
.boxed()
.toList();
// Using mapToInt()
numbers.stream()
.mapToInt(n -> n).sum();
// Using Collectors.summingInt()
numbers.stream()
.collect(Collectors.summingInt(n -> n));
// Avg
numbers.stream()
.mapToDouble(Integer::doubleValue) // !important
.average()
.orElse(0.0);
String based
// Uppercase all strings
var names = Arrays.asList("Sachin", "manisH", "Suresh");
final List<String> uppercaseNames = names.stream()
.map(String::toUpperCase)
.toList();
// count of strings with length > 5
List<String> list = new ArrayList<>(List.of("he", "hello", "kiamotors", "helloworld", "hd"));
long count = list.stream().filter(e -> e.length() > 5).count();
Data Setup
@Getter
@Setter
@AllArgsConstructor
class Employee {
private int id;
private String name;
private int age;
private String departNames;
private String address;
private double salary;
private String gender;
}
List<Employee> employees = Arrays.asList(
new Employee(1, "Abraham", 29, "IT", "Mumbai", 20000, "Male"),
new Employee(2, "Mary", 27, "Sales", "Chennai", 25000, "Female"),
new Employee(3, "Joe", 28, "IT", "Chennai", 22000, "Male"),
new Employee(4, "John", 29, "Sales", "Gurgaon", 29000, "Male"),
new Employee(5, "Liza", 25, "Sales", "Bangalore", 32000, "Female"),
new Employee(6, "Peter", 27, "Admin", "Mumbai", 31500, "Male"),
new Employee(7, "Harry", 30, "Research", "Kochi", 21000, "Male")
);
Max age of employees
employees.stream()
.mapToInt(Employee::getAge)
.max().orElse(-1);
Count of employee in each department
employees.stream().collect(
Collectors.groupingBy(Employee::getDepartment, Collectors.counting())
);
Second Lowest/Highest Salary
var secondLowestSalaryEmployee = employees.stream()
.sorted(Comparator.comparing(Employee::getSalary))
.skip(1)
.findFirst().orElse(null);
var secondHighestSalaryEmployee = employees.stream()
.sorted(Comparator.comparing(Employee::getSalary).reversed())
.skip(1)
.findFirst().orElse(null);
Department with maximum number of employees
employees.stream()
.collect(Collectors.groupingBy(
Employee::getDepartment,
Collectors.counting()))
.entrySet().stream()
.max(Comparator.comparingLong(Map.Entry::getValue))
.map(Map.Entry::getKey).orElse(null);
Average age of each gender
employees.stream()
.collect(Collectors.groupingBy(
Employee::getGender,
Collectors.averagingInt(Employee::getAge)
));
Find first non-repeating character using streams
String str = "karnataka";
List<String> characters = Arrays.asList(str.split(""));
Map<String, Long> freq = characters.stream().collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));
String result = characters.stream()
.filter(c -> freq.get(c).equals(1L)) // compare with Long else will fail
.findFirst().orElse(null);
System.out.println(freq);
System.out.println(result);
- Optimized using LinkedHashMap
- It remembers the insertion order
String result = characters.stream()
.collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()))
.entrySet().stream()
.filter(entry -> entry.getValue() == 1L)
.map(entry -> entry.getKey())
.findFirst().orElse(null);
System.out.println(result);