The mapMulti()
method in Java is introduced in JDK 16 and is part of Stream
interface. In this guide, we will learn how to use mapMulti()
method in Java with practical examples and real-world use cases to better understand its usage.
Table of Contents
- Introduction
mapMulti()
Method Syntax- Examples
- Basic Usage
- Using
mapMulti()
with Complex Transformations
- Real-World Use Case
- Conclusion
Introduction
The Stream.mapMulti()
method in Java allows mapping each stream element to multiple values and flattening them into a single stream. Unlike flatMap()
, it uses a BiConsumer
to handle the element processing and add multiple results to the stream.
This method is useful when you need to transform each element into zero, one, or multiple values while keeping control over how elements are produced.
mapMulti()
is often used when the transformation logic for each element involves generating multiple results in a flexible way.
mapMulti() Method Syntax
The syntax for the mapMulti()
method is as follows:
<R> Stream<R> mapMulti(BiConsumer<? super T, ? super Consumer<R>> mapper)
Parameters:
mapper
: ABiConsumer
that consumes an element of the stream and aConsumer
to which multiple elements can be passed.
Returns:
- A new
Stream
consisting of the mapped elements.
Throws:
- This method does not throw any exceptions.
Examples
Basic Usage
To demonstrate the basic usage of mapMulti()
, we will create a Stream
of integers and use mapMulti()
to map each integer to its square and cube.
Example
import java.util.stream.Stream;
public class MapMultiExample {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3);
// Use mapMulti() to map each integer to its square and cube
Stream<Integer> mappedStream = stream.mapMulti((number, consumer) -> {
consumer.accept(number * number); // Square
consumer.accept(number * number * number); // Cube
});
// Print the mapped elements
mappedStream.forEach(System.out::println);
}
}
Output:
1
1
4
8
9
27
Using mapMulti()
with Complex Transformations
This example shows how to use mapMulti()
to split a stream of sentences into a stream of words.
Example
import java.util.stream.Stream;
public class MapMultiComplexExample {
public static void main(String[] args) {
Stream<String> stream = Stream.of("Hello world", "How are you");
// Use mapMulti() to split sentences into words
Stream<String> wordStream = stream.mapMulti((sentence, consumer) -> {
for (String word : sentence.split(" ")) {
consumer.accept(word);
}
});
// Print the mapped elements
wordStream.forEach(System.out::println);
}
}
Output:
Hello
world
How
are
you
Real-World Use Case
Example 1: Expanding Hierarchical Data
In real-world applications, mapMulti()
can be used to expand hierarchical data, such as transforming a stream of directories into a stream of files:
import java.io.File;
import java.util.stream.Stream;
public class MapMultiFileExample {
public static void main(String[] args) {
Stream<File> directories = Stream.of(new File("dir1"), new File("dir2"));
// Use mapMulti() to expand directories into files
Stream<File> fileStream = directories.mapMulti((directory, consumer) -> {
File[] files = directory.listFiles();
if (files != null) {
for (File file : files) {
consumer.accept(file);
}
}
});
// Print the mapped elements (files)
fileStream.forEach(System.out::println);
}
}
Output:
(Note: The actual output will depend on the contents of the directories.)
Example 2: Flattening Nested Collections
mapMulti()
can also be used to flatten nested collections, such as a stream of lists of integers, into a single stream of integers.
import java.util.List;
import java.util.stream.Stream;
public class MapMultiFlattenListExample {
public static void main(String[] args) {
Stream<List<Integer>> listOfNumbers = Stream.of(
List.of(1, 2, 3),
List.of(4, 5),
List.of(6, 7, 8)
);
// Use mapMulti() to flatten the nested lists into a single stream of integers
Stream<Integer> flatStream = listOfNumbers.mapMulti((list, consumer) -> {
for (Integer number : list) {
consumer.accept(number);
}
});
// Print the flattened stream
flatStream.forEach(System.out::println);
}
}
Output:
1
2
3
4
5
6
7
8
Example 3: Transforming and Filtering Data
Another real-world use case of mapMulti()
is when transforming and filtering data at the same time. In this example, we will take a stream of integers, map them to their multiples, and only add the multiples that are even.
import java.util.stream.Stream;
public class MapMultiTransformAndFilterExample {
public static void main(String[] args) {
Stream<Integer> stream = Stream.of(1, 2, 3, 4);
// Use mapMulti() to map each integer to its multiples, filtering even multiples
Stream<Integer> mappedStream = stream.mapMulti((number, consumer) -> {
int square = number * number;
int cube = number * number * number;
// Add only even results to the stream
if (square % 2 == 0) {
consumer.accept(square);
}
if (cube % 2 == 0) {
consumer.accept(cube);
}
});
// Print the filtered and mapped elements
mappedStream.forEach(System.out::println);
}
}
Output:
4
8
64
Conclusion
The Stream.mapMulti()
method is used for performing one-to-many mappings of elements in a stream. This method is particularly useful for scenarios where you need to produce a dynamic number of results for each input element.
By understanding and using this method, you can efficiently manage and process streams of values in your Java applications, allowing for flexible and complex data transformations.