Creating Streams in Java

Naveen AnamaneniUpdated · 4 min read
easyJava 25javastreams

Before you can filter or transform data with streams, you need a stream to start with. Java offers many ways to create one: from a collection, an array, individual values, a range of numbers, a formula, the characters or lines of a string, or the lines of a file. In this lesson, you will learn each way to create a stream, with an example.

Ways to Create a Stream

SourceMethodType of stream
A collectionlist.stream(), set.stream()Stream<T>
A mapmap.entrySet().stream(), map.keySet().stream()Stream<...>
An arrayArrays.stream(array)Stream<T> or IntStream...
Individual valuesStream.of(a, b, c)Stream<T>
A possibly-null valueStream.ofNullable(x) (Java 9)0 or 1 element
A range of numbersIntStream.range(a, b), rangeClosed(a, b)IntStream
A formulaStream.iterate(seed, next)Infinite unless limited
A formula with a stop conditionStream.iterate(seed, hasNext, next) (Java 9)Finite
A supplierStream.generate(supplier)Infinite unless limited
Characters of a stringstr.chars()IntStream
Lines of a stringstr.lines() (Java 11)Stream<String>
Lines of a fileFiles.lines(path)Stream<String>
No elementsStream.empty()Empty stream
Built step by stepStream.builder()Stream<T>

Example: From Collections, Arrays and Values

Let's see an example of the most common sources.

Sources.java▶ Try it
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.TreeMap;
import java.util.stream.Stream;
 
public class Sources {
    public static void main(String[] args) {
        List<String> list = List.of("Navika", "Srihitha");
        System.out.println(list.stream().count());
 
        String[] array = {"Advitha", "Anamaneni"};
        System.out.println(Arrays.stream(array).toList());
 
        int[] marks = {91, 78, 85};
        System.out.println(Arrays.stream(marks).max().getAsInt());
 
        System.out.println(Stream.of("a", "b", "c").toList());
 
        Map<String, Integer> m =
            new TreeMap<>(Map.of("Navika", 91, "Advitha", 85));
        m.entrySet().stream()
         .forEach(e -> System.out.println(e.getKey() + "=" + e.getValue()));
    }
}
Output
2
[Advitha, Anamaneni]
91
[a, b, c]
Advitha=85
Navika=91

Explanation: list.stream() and Arrays.stream(array) stream existing data. Arrays.stream on an int[] gives an IntStream, which has max(). Stream.of streams the values you list. A map isn't a collection, so you stream one of its views, such as entrySet().

Example: Ranges, iterate and generate

Generated.java▶ Try it
import java.util.stream.IntStream;
import java.util.stream.Stream;
 
public class Generated {
    public static void main(String[] args) {
        System.out.println(IntStream.range(1, 5).boxed().toList());
        System.out.println(IntStream.rangeClosed(1, 5).sum());
 
        System.out.println(Stream.iterate(1, n -> n * 2).limit(6).toList());
        System.out.println(
            Stream.iterate(1, n -> n < 100, n -> n * 3).toList());
 
        System.out.println(Stream.generate(() -> "hi").limit(3).toList());
    }
}
Output
[1, 2, 3, 4]
15
[1, 2, 4, 8, 16, 32]
[1, 3, 9, 27, 81]
[hi, hi, hi]

Explanation: range(1, 5) excludes 5; rangeClosed(1, 5) includes it. Stream.iterate(1, n -> n * 2) is infinite, so limit(6) stops it. The three-argument iterate stops by itself when n < 100 becomes false. generate calls a supplier again and again, so it also needs limit.

Example: Strings and Builders

TextSources.java▶ Try it
import java.util.stream.Stream;
 
public class TextSources {
    public static void main(String[] args) {
        long vowels = "Anamaneni".toLowerCase().chars()
            .filter(c -> "aeiou".indexOf(c) >= 0)
            .count();
        System.out.println("Vowels: " + vowels);
 
        String text = "Navika\nSrihitha\nAdvitha";
        System.out.println(text.lines().map(String::length).toList());
 
        Stream<String> built = Stream.<String>builder()
            .add("one").add("two").build();
        System.out.println(built.toList());
    }
}
Output
Vowels: 5
[6, 8, 7]
[one, two]

Explanation: chars() streams the characters of a string as int codes, which can be tested. lines() splits text into a stream of lines. A builder lets you add elements one at a time before building the stream.

Common Mistakes

Calling stream() on an array. Arrays have no methods; use Arrays.stream(arr).

Passing an int[] to Stream.of. You get a stream with one element, the array; use Arrays.stream or IntStream.of.

Forgetting to close Files.lines. Use it in try-with-resources, because it holds the file open.

Practice

  1. Easy: Print the multiples of 5 from 5 to 50 using IntStream.rangeClosed and filter.
  2. Harder: Use Stream.iterate to generate the first 10 Fibonacci numbers (hint: iterate over two-element int[] arrays).

Quick check: Creating streams

4 questions
1How do you stream an array?
2Does IntStream.range(1, 5) include 5?
3What does Stream.generate need to finish?
4What does "text".chars() return?

Key Takeaways

Was this tutorial helpful?

Lesson 314 of 482