Open In App

Comparing Streams to Loops in Java

Last Updated : 20 Oct, 2022
Improve
Improve
Like Article
Like
Save
Share
Report

A stream is an ordered pipeline of aggregate operations(filter(), map(), forEach(), and collect()) that process a (conceptually unbounded) sequence of elements. A stream pipeline consists of a source, followed by zero or more intermediate operations; and a terminal operation. An aggregate operation performs a function. Ideally, a function’s output in a stream depends only on its input arguments. A stream holds no non-transient stage. Every stream works essentially the same which is:

  • Starts with a source of data.
  • Processes the data through a pipeline of intermediate operations.
  • Finishes with a terminal operation.

By default, each aggregate operation in a stream runs its function sequentially, i.e., one after another in the caller’s thread of control. Streams can be created from Collections, Lists, Sets, ints, longs, doubles, arrays, lines of a file. 

Stream operations are either intermediate or terminal. Intermediate operations such as filter, map, or sort return a stream, so we can chain multiple intermediate operations. Terminal operations such as forEach, collect, or reduce are either void or return a non-stream result. Streams bring functional programming in Java and are supported starting in Java 8. The Java 8 stream is an implementation of the PQSA1 Pipes and Filter pattern.

Example:

Java




// Java Program to Compare Streams to Loops
 
// Importing required libraries
import java.io.IOException;
import java.lang.String;
import java.nio.file.*;
import java.util.*;
import java.util.Arrays;
import java.util.List;
import java.util.stream.*;
 
// Main class
// JavaStreams
class GFG {
 
    // Main driver method
    public static void main(String[] args)
        throws IOException
    {
 
        // 1. Integer Stream
        System.out.println("Integer Stream : ");
        IntStream.range(1, 10).forEach(System.out::print);
 
        // New line
        System.out.println();
 
        // 2. Integer Stream with skip
        System.out.println("Integer Stream with skip : ");
        IntStream.range(1, 10).skip(5).forEach(
            x -> System.out.println(x));
 
        // New line
        System.out.println();
 
        // 3. Integer Stream with sum
        System.out.println("Integer Stream with sum : ");
        System.out.println(IntStream.range(1, 5).sum());
 
        // New line
        System.out.println();
 
        // 4. Stream.of, sorted and findFirst
        System.out.println(
            "Stream.of, sorted and findFirst : ");
        Stream.of("Java ", "Scala ", "Ruby ")
            .sorted()
            .findFirst()
            .ifPresent(System.out::println);
 
        // New line
        System.out.println();
 
        // 5. Stream from Array, sort, filter and print
        String[] names = { "AI",        "Matlab",
                           "Scikit",    "TensorFlow",
                           "OpenCV",    "DeepLearning",
                           "NLP",       "NeuralNetworks",
                           "Regression" };
        System.out.println(
            "Stream from Array, sort, filter and print : ");
        Arrays
            .stream(names) // same as Stream.of(names)
            .filter(x -> x.startsWith("S"))
            .sorted()
            .forEach(System.out::println);
 
        // New line
        System.out.println();
 
        // 6. average of squares of an int array
        System.out.println(
            "Average of squares of an int array : ");
        Arrays.stream(new int[] { 2, 4, 6, 8, 10 })
            .map(x -> x * x)
            .average()
            .ifPresent(System.out::println);
 
        // New line
        System.out.println();
 
        // 7. Stream from List, filter and print
 
        // Display message only
        System.out.println(
            "Stream from List, filter and print : ");
 
        List<String> people = Arrays.asList(
            "AI", "Matlab", "Scikit", "TensorFlow",
            "OpenCV", "DeepLearning", "NLP",
            "NeuralNetworks");
        people.stream()
            .map(String::toLowerCase)
            .filter(x -> x.startsWith("a"))
            .forEach(System.out::println);
 
        // New line
        System.out.println();
 
        // 8. Reduction - sum
 
        // Display message only
        System.out.println("Reduction - sum : ");
 
        double total
            = Stream.of(7.3, 1.5, 4.8)
                  .reduce(0.0,
                          (Double a, Double b) -> a + b);
 
        // Print and display
        System.out.println("Total = " + total);
 
        System.out.println();
 
        // 9. Reduction - summary statistics
        System.out.println(
            "Reduction - summary statistics : ");
        IntSummaryStatistics summary
            = IntStream.of(7, 2, 19, 88, 73, 4, 10)
                  .summaryStatistics();
 
        // Print and display
        System.out.println(summary);
 
        System.out.println();
    }
}


 
 

Output

Integer Stream : 
123456789
Integer Stream with skip : 
6
7
8
9

Integer Stream with sum : 
10

Stream.of, sorted and findFirst : 
Java 

Stream from Array, sort, filter and print : 
Scikit

Average of squares of an int array : 
44.0

Stream from List, filter and print : 
ai

Reduction - sum : 
Total = 13.600000000000001

Reduction - summary statistics : 
IntSummaryStatistics{count=7, sum=203, min=2, average=29.000000, max=88}

 

Now, discussing loops in order to figure out in order to land onto conclusive differences. Looping is a feature in Java that facilitates the execution of a set of instructions until the controlling Boolean expression evaluates to false. Different types of loops are provided to fit any programming need. Each loop has its own purpose and a suitable use case to serve.

 

Example:

Java




// Java Program to Comparing Streams to Loops
 
// Importing utility packages
import java.util.*;
 
// Class 1
// helper class
class ProgrammingLanguage {
 
    // Member variables of this class
    int rank;
    String name;
    int value;
 
    // Member method of this class
    public ProgrammingLanguage(int rank, String name,
                               int value)
    {
 
        // this keyword is used to refer current object
        // itself
        this.rank = rank;
        this.name = name;
        this.value = value;
    }
}
 
// Class 2
// JavaStreamExample
public class GFG {
 
    // MAin driver method
    public static void main(String[] args)
    {
 
        // Creating an object of List class
        // Declaring object of user defined type (above
        // class)
        List<ProgrammingLanguage> programmingLanguage
            = new ArrayList<ProgrammingLanguage>();
 
        // Adding elements to the object of this class
        // Custom input entries
        programmingLanguage.add(
            new ProgrammingLanguage(1, "Java", 7000));
        programmingLanguage.add(
            new ProgrammingLanguage(2, "Rust", 2000));
        programmingLanguage.add(
            new ProgrammingLanguage(3, "Ruby", 1500));
        programmingLanguage.add(
            new ProgrammingLanguage(4, "Scala", 2500));
        programmingLanguage.add(
            new ProgrammingLanguage(5, "Groovy", 4000));
 
        // Creating object of List class of integer type
        List<Integer> languageValueList
            = new ArrayList<Integer>();
 
        // For each loops for iteration
        for (ProgrammingLanguage language :
             programmingLanguage) {
 
            // Filtering data of List
            if (language.value < 3000) {
 
                // Adding price to above elements
                languageValueList.add(language.value);
            }
        }
 
        // Print and display all elements inside the object
        System.out.println(languageValueList);
    }
}


Output

[2000, 1500, 2500]

By far we have understood both of the concepts and come across to know they don’t go hand in hand, one has advantage over other as per the usage where it is to be used. Hence, wrapping off the article by illustrating their advantages which are as follows:  

Advantages of Streams 

  • Streams are a more declarative style. Or a more expressive style.
  • Streams have a strong affinity with functions. Java 8 introduces lambdas and functional interfaces, which opens a whole toolbox of powerful techniques. Streams provide the most convenient and natural way to apply functions to sequences of objects.
  • Streams encourage less mutability. This is sort of related to the functional programming aspect i.e., the kind of programs we write using streams tend to be the kind of programs where we don’t modify objects.
  • Streams encourage loose coupling. Our stream-handling code doesn’t need to know the source of the stream or its eventual terminating method.
  • Streams can succinctly express quite sophisticated behavior.

 

Advantages of Loops 

  • Performance: A for loop through an array is extremely lightweight both in terms of heap and CPU usage. If raw speed and memory thriftiness is a priority, using a stream is worse.
  • Familiarity: The world is full of experienced procedural programmers, from many language backgrounds, for whom loops are familiar and streams are novel. In some environments, you want to write code that’s familiar to that kind of person.
  • Cognitive overhead: Because of its declarative nature, and increased abstraction from what’s happening underneath, you may need to build a new mental model of how code relates to execution. Actually, you only need to do this when things go wrong, or if you need to deeply analyze performance or subtle bugs. When it “just works”, it just works.
  • Debuggers are improving, but even now, when we are stepping through stream code in a debugger, it can be harder work than the equivalent loop, because a simple loop is very close to the variables and code locations that a traditional debugger works with.

 

Conclusion: 

If you have a small list; for loops perform better, if you have a huge list; a parallel stream will perform better. And since parallel streams have quite a bit of overhead, it is not advised to use these unless you are sure it is worth the overhead.



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads