File size: 3,312 Bytes
8ad5547
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
From version 8 onwards, Java has supported so-called "streams".
With streams, it is easy to HANDLE ALL (OR SUITABLY LIMITED) ELEMENTS of an ENTIRE DATA STRUCTURE at once. 
By combining streams with LAMBDA EXPRESSIONS, Java's features can be stretched towards functional programming languages.

In this section, we will look at the operation of streams through a few simple examples. 
The basic idea is that a stream can be created from 'any Collection', such as a list, using the stream method. 

Various operations can then be targeted at the stream. 

Then a so-called terminal operation ends the stream, and typically produces 
- a single VALUE or 
- a new COLLECTION of elements as a result.
https://ville.utu.fi/APP/connector/0/215/source/0c9e196c-6ab5-41d6-9f2c-f4a02c05d1db.png



========================================================


Processing All Elements: forEach

Let's start with an example where we want to apply the SAME OPERATION to ALL ELEMENTS of a collection. 
A typical example would be a situation where we have a list of strings 
and we want to print them one by one. 

An implementation using a stream would look like this:

public static void main(String[] args) {
    ArrayList<String> strings = new ArrayList<>();
    strings.add("first");
    strings.add("second");
    strings.add("third");
    strings.add("fourth");
    
    strings.stream().forEach(string -> System.out.println(string));
}
 

The program prints
first
second
third
fourth
 






========================================================






The forEach method takes the operation to be performed as a parameter. 
A lambda expression is a handy way to define a single operation to be performed.

The LAMBDA EXPRESSION is in the form
parameter -> operation, which uses the parameter

...in the example, it's
string -> System.out.println(string)
 









========================================================


In practice, it means that the print statement is executed for all elements of the stream.
Let's look at another example where the method printVowels is called for all elements of the list:

public static void main(String[] args) {
    ArrayList<String> ducks = new ArrayList<>();
    ducks.add("Huey");
    ducks.add("Dewey");
    ducks.add("Louie");
    ducks.add("Scrooge");
    ducks.add("Gyro Gearloose");
    
    ducks.stream().forEach(duck -> printVowels(duck));
}

public static void printVowels(String string) {
    for (int i=0; i<string.length(); i++) {
        if ("aeiouy".contains("" + string.charAt(i))) {
            System.out.print(string.charAt(i));
        }
    }
    System.out.println();
}
 

The program prints:
ue
eey
ouie
ooe
yoeaooe





========================================================


A third example prints the names

ArrayList<Person> hlot = new ArrayList<>();
persons.add(new Person("Heikki Person", "heikki@example.com"));
persons.add(new Teacher("Oliver Teacher", "oliver@example.com", 123));
persons.add(new Student("Oscar Student", "oscar@example.com", 23));

persons.stream().forEach(person -> 
    System.out.println("name: " + person.getName() + ", email: " + person.getEmail()));
 

Ohjelma tulostaa:
Nimi: Heikki Person, email: heikki@example.com
Nimi: Oliver Teacher, email: oliver@example.com
Nimi: Oscar Student, email: oscar@example.com