Java
Java 8
Streams
Programming
Data Processing

How can I get a List from some class properties with Java 8 Stream?

Master System Design with Codemia

Enhance your system design skills with over 120 practice problems, detailed solutions, and hands-on exercises.

In Java 8, the Stream API introduced a powerful and efficient way to process collections of objects. One common application is extracting a list of specific properties from a collection of objects. This article will explore how to use Java 8 Streams to convert a list of objects into a list of a specific class property.

Understanding Java Streams

Java Streams are sequences of elements that support various operations, possibly transforming these into a different type of stream. Streams enable functional-style operations on collections, providing developers with a more declarative way to work with data.

Key Stream Operations

  • Intermediate Operations: Transform a stream into another stream. Common intermediate operations include filter, map, and sorted.
  • Terminal Operations: Produce a result or a side-effect. Common terminal operations include collect, forEach, and reduce.

Example: Extracting a List of Class Properties

Assume you have a class Person with properties name and age. You can extract names from a list of Person objects using Java Streams as follows:

java
1import java.util.Arrays;
2import java.util.List;
3import java.util.stream.Collectors;
4
5class Person {
6    private String name;
7    private int age;
8
9    public Person(String name, int age) {
10        this.name = name;
11        this.age = age;
12    }
13
14    public String getName() {
15        return name;
16    }
17
18    public int getAge() {
19        return age;
20    }
21}
22
23public class StreamExample {
24    public static void main(String[] args) {
25        List<Person> people = Arrays.asList(
26            new Person("Alice", 30),
27            new Person("Bob", 25),
28            new Person("Charlie", 35)
29        );
30
31        List<String> names = people.stream()
32                                   .map(Person::getName)
33                                   .collect(Collectors.toList());
34
35        System.out.println(names); // Output: [Alice, Bob, Charlie]
36    }
37}

Explanation

  1. Creating the Stream: people.stream() initializes a stream from the List<Person>.
  2. Mapping: The map(Person::getName) intermediate operation calls the getName method on each Person object in the stream, transforming it into a stream of names (Stream<String>).
  3. Collecting: The collect(Collectors.toList()) terminal operation collects the elements of the stream into a List.

Technical Details

  • Lambda Expressions: Streams work seamlessly with lambda expressions and method references (Person::getName). This makes operations concise and readable.
  • Type Safety: Generics ensure that the transformations are type-safe. The map method's transformation maintains the specific type information across operations.

Collecting Other Property Types

You can adapt the example for different property types:

Example: Extracting Ages

java
1List<Integer> ages = people.stream()
2                           .map(Person::getAge)
3                           .collect(Collectors.toList());
4
5System.out.println(ages); // Output: [30, 25, 35]

Combining Streams

Streams can be further manipulated by chaining multiple operations:

java
1List<String> adults = people.stream()
2                            .filter(p -> p.getAge() >= 18)
3                            .map(Person::getName)
4                            .collect(Collectors.toList());
5
6System.out.println(adults); // Output: [Alice, Bob, Charlie]

Summary Table

Here is a table summarizing the key operations:

OperationTypeDescription
stream()CreationConverts a collection to a stream.
map()IntermediateTransforms each element via a provided function (e.g., method call). Maintains type consistency across transformations.
filter()IntermediateSelects elements based on a predicate.
collect()TerminalCollects the elements into a collection (e.g., List).

Conclusion

Using Java 8 Streams to extract class properties from a collection offers a concise, efficient, and readable approach to data manipulation. By employing functional operations such as map and collect, developers can handle complex data transformations with minimal code and maximum clarity.

Incorporating Streams into your Java applications not only enhances code expressiveness but also takes advantage of parallelism and laziness in stream processing, evident in more performance-optimized and declarative Java programs.


Course illustration
Course illustration

All Rights Reserved.