Created: 2023-09-06 10:01
Status: #concept
Subject: Programming
Tags: Java java.util Java Package Bash Stream Redirection

java.util.Stream

It is a sequence of elements returned after doing .stream() which is similar to doing .toArray(), implemented by all Java Classes that implements Collection.

  • this lets us use Pipe & Filter methods and Lambda Functions to chain methods together to return Stream<E> values.

Collections vs Streams

Collections are primarily concerned with the efficient management of, and access to, their elements. By contrast, streams do not provide a means to directly access or manipulate their elements, and are instead concerned with declaratively describing their source and the computational operations which will be performed in aggregate on that source.

Stream Methods

Stream methods are divided into two groups,

(1) Intermediate Operations which process each element as an aggregate, .filter(), .map(), .distinct(), .sorted(naturalComparisonFn?)
(2) Terminal Operations which return a single value based on all the elements, .collect(), .forEach(), .count(), .average(), .reduce(start, (total, current) -> newTotal)

List<Integer> list = new ArrayList<>();
list.add(3);
list.add(7);
list.add(4);
list.add(2);
list.add(6);

ArrayList<Integer> values = list.stream()
    .filter(value -> value > 5)
    .map(value -> value * 2)
    .collectnew);

Common Methods

Stream aggregate operation methods are typically Pure Functions.

Purpose and method Assumptions
Stream formation: stream() The method is called on collection that implements the Collection Java Interface, such as an ArrayList Object. Something is done on the created stream.
Stream formation: Stream.of(T ...values) Creates a stream we can use methods on, especially useful for typecasting Java Array prmitive types.
Converting a stream into an integer stream: mapToInt(value -> another) The stream transforms into one containing integers. A stream containing strings can be converted using, for instance, the Integer.valueOf() method. Something is done with the stream containing integers.
Filtering values: filter(value -> filter condition) The elements that do not satisfy the filter condition are removed from the string. On the right side of the arrow is a statement that returns a boolean. If the boolean is true, the element is accepted into the stream. If the boolean evaluates to false, the value is not accepted into the stream. Something is done with the filtered values.
Counting the number of elements in a stream: count() Returns the number of elements in a stream as a long-type value.
Collection formation: .collect() for example: .collect(Collectors.toList()) mutable reduction operation accumulates input elements into a mutable result container, such as a Collection or StringBuilder, as it processes the elements in the stream.

Example: Parsing a File with Formatted Lines

Kaarlo Juho Ståhlberg; 1865
Lauri Kristian Relander; 1883
Pehr Evind Svinhufvud; 1861
Kyösti Kallio; 1873
Risto Heikki Ryti; 1889
Carl Gustaf Emil Mannerheim; 1867
Juho Kusti Paasikivi; 1870
Urho Kaleva Kekkonen; 1900
Mauno Henrik Koivisto; 1923
Martti Oiva Kalevi Ahtisaari; 1937
Tarja Kaarina Halonen; 1943
Sauli Väinämö Niinistö; 1948
List<Person> presidents = new ArrayList<>();
try {
    // reading the "presidents.txt" file line by line
    Files.lines(Paths.get("presidents.txt"))
        // splitting the row into parts on the ";" character
        .map(row -> row.split(";"))
        // deleting the split rows that have less than two parts (we want the rows to always contain both the name and the birth year)
        .filter(parts -> parts.length >= 2)
        // creating persons from the parts
        .map(parts -> new Person(parts[0], Integer.valueOf(parts[1])))
        // and finally add the persons to the list
        .forEach(person -> presidents.add(person));
} catch (Exception e) {
    System.out.println("Error: " + e.getMessage());
}

// now the presidents are on the list as person objects

References