Java Streams with Simple Examples

Mete Ergin
4 min readAug 7, 2021

--

Streams and collections resemble each other, but they are designed for distinct goals. Collections provide access management of each object effectively. On the contrary, streams do not directly interest in accessing and manipulating each element it has. Streams are designed to handle parallel and sequential aggregation operations by the usage of method chaining methodology.

Let’s dig into sample usages;

At first, create User class. This will represent our base object for samples.

import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.ToString;
@Data
@AllArgsConstructor
@ToString
public class User {
private long id;
private String firstName;
private String lastName;
private int age;
private String nationality;
}

Let’s write Sampleclass in which all samples run.

import java.util.Arrays;
import java.util.List;
public class Sample { private final List<User> userList = Arrays.asList(
new User(1, "Michael", "Robert", 37, "TR"),
new User(2, "Mary", "Patricia", 11, "EN"),
new User(3, "John", "Michael", 7, "FR"),
new User(4, "Jennifer", "Linda", 77, "TR"),
new User(5, "William", "Elizabeth", 23, "US"),
new User(6, "Sue", "Jackson", 11, "IT"),
new User(7, "Michael", "Tommy", 37, "EN")
);

public static void main(String... args) {
Sample sample = new Sample();
}
}
  1. Loop over each element of userList by using the forEach() operator and then write to console.
public static void main(String... args) {
Sample sample = new Sample();
sample.test1();
}
private void test1() {
System.out.println("Test 1");
userList.stream()
.forEach(System.out::println);
}

Output is;

Test 1
User(id=1, firstName=Michael, lastName=Robert, age=37, nationality=TR)
User(id=2, firstName=Mary, lastName=Patricia, age=11, nationality=EN)
User(id=3, firstName=John, lastName=Michael, age=7, nationality=FR)
User(id=4, firstName=Jennifer, lastName=Linda, age=77, nationality=TR)
User(id=5, firstName=William, lastName=Elizabeth, age=23, nationality=US)
User(id=6, firstName=Sue, lastName=Jackson, age=11, nationality=IT)
User(id=7, firstName=Michael, lastName=Tommy, age=37, nationality=EN)

Due to userList is ArrayList, items are written console with the creation order of the List.

2. Loop over each element afterward manipulate the object and write to console.

private void test2() {
System.out.println("Test 2");
userList.stream()
.map(u -> {
return new User(
u.getId(),
"X " + u.getFirstName(),
"Y " + u.getLastName(),
u.getAge() + 10),
u.getNationality());
})
.collect(Collectors.toList())
.forEach(System.out::println);
}

Output is;

Test 2
User(id=1, firstName=X Michael, lastName=Y Robert, age=47, nationality=TR)
User(id=2, firstName=X Mary, lastName=Y Patricia, age=21, nationality=EN)
User(id=3, firstName=X John, lastName=Y Michael, age=17, nationality=FR)
User(id=4, firstName=X Jennifer, lastName=Y Linda, age=87, nationality=TR)
User(id=5, firstName=X William, lastName=Y Elizabeth, age=33, nationality=US)
User(id=6, firstName=X Sue, lastName=Y Jackson, age=21, nationality=IT)
User(id=7, firstName=X Michael, lastName=Y Tommy, age=47, nationality=EN)

3. Sort the list according to age property.

private void test3() {
System.out.println("Test 3");
userList.stream()
.sorted(Comparator.comparing(User::getAge))
.collect(Collectors.toList())
.forEach(System.out::println);
}

Output is;

Test 3
User(id=3, firstName=John, lastName=Michael, age=7, nationality=FR)
User(id=2, firstName=Mary, lastName=Patricia, age=11, nationality=EN)
User(id=6, firstName=Sue, lastName=Jackson, age=11, nationality=IT)
User(id=5, firstName=William, lastName=Elizabeth, age=23, nationality=US)
User(id=1, firstName=Michael, lastName=Robert, age=37, nationality=TR)
User(id=7, firstName=Michael, lastName=Tommy, age=37, nationality=EN)
User(id=4, firstName=Jennifer, lastName=Linda, age=77, nationality=TR)

4. Sort the list according to age, firstName and lastName property.

private void test4() {
System.out.println("Test 4");
userList.stream()
.sorted(Comparator.comparing(User::getAge)
.thenComparing(User::getFirstName)
.thenComparing(User::getLastName))
.collect(Collectors.toList())
.forEach(System.out::println);
}

Output is;

Test 4
User(id=3, firstName=John, lastName=Michael, age=7, nationality=FR)
User(id=2, firstName=Mary, lastName=Patricia, age=11, nationality=EN)
User(id=6, firstName=Sue, lastName=Jackson, age=11, nationality=IT)
User(id=5, firstName=William, lastName=Elizabeth, age=23, nationality=US)
User(id=1, firstName=Michael, lastName=Robert, age=37, nationality=TR)
User(id=7, firstName=Michael, lastName=Tommy, age=37, nationality=EN)
User(id=4, firstName=Jennifer, lastName=Linda, age=77, nationality=TR)

5. Let’s find out age average and maximum length of firstName.

private void test5() {
System.out.println("Test 5");
double averageAge = userList.stream()
.mapToInt(User::getAge)
.summaryStatistics()
.getAverage();
System.out.print("averageAge: " + averageAge); int maxFirstNameLenght = userList.stream()
.mapToInt((value) -> {
return value.getFirstName().length();
})
.summaryStatistics()
.getMax();
System.out.println(" maxFirstNameLenght: " + maxFirstNameLenght);
}

Output is;

Test 5
averageAge: 29.0 maxFirstNameLenght: 8

6. Check if all ages greater than 6.

private void test6() {
System.out.println("Test 6");
boolean isAllAgesGreaterThan6 = userList.stream()
.allMatch(user -> user.getAge() > 6);
System.out.println("isAllAgesGreaterThan6: " + isAllAgesGreaterThan6);
}

Output is;

Test 6
isAllAgesGreaterThan6: true

7. Check if any of firstName property’s first character is S.

private void test7() {
System.out.println("Test 7");
boolean isFirstCharS = userList.stream()
.anyMatch(user -> user.getFirstName().charAt(0) == 'S');
System.out.println("isFirstCharS " + isFirstCharS);
}

Output is;

Test 7
isFirstCharS: true

8. Repackage the returned Collection object to another.

private void test8() {
System.out.println("Test 8");
List<User> list = userList.stream()
.collect(Collectors.toList());
Set<User> set = userList.stream()
.collect(Collectors.toSet());
List<User> linkedList = userList.stream()
.collect(Collectors.toCollection(LinkedList::new));
Map<Long, User> map = userList.stream()
.collect(Collectors.toMap(user -> user.getId(), user -> user));
}

9. Count different nationalities on the list.

private void test9() {
long countDifferentNationalites = userList.stream()
.map(User::getNationality)
.distinct()
.count();
System.out.println("countDifferentNationalites: " + countDifferentNationalites);
}

Output is;

Test 9
countDifferentNationalites: 5

10. Let’s drop out User whose firstName`s first character is M letter and is older than 10.

private void test10() {
System.out.println("Test 10");
userList.stream()
.filter(p -> (p.getFirstName().charAt(0) != 'M'))
.filter(p -> (p.getAge() > 10))
.collect(Collectors.toList())
.forEach(System.out::println);
}

Output is;

Test 10
User(id=4, firstName=Jennifer, lastName=Linda, age=77, nationality=TR)
User(id=5, firstName=William, lastName=Elizabeth, age=23, nationality=US)
User(id=6, firstName=Sue, lastName=Jackson, age=11, nationality=IT)

To sum up, Java Stream is not a data structure that stores elements; instead, it conveys elements from a source such as a data structure through a pipeline of computational operations. An operation on a Java Stream produces a return value but does not modify its original source.

All sample source codes are in the GitHub repository. Thank you for reading the article.

--

--