File size: 3,312 Bytes
45666b5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9ba0818
45666b5
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
A typical example of an operation applied to a collection is calculating the SUM of all elements. 
If we have a list containing numbers as strings, we can easily calculate the sum of its elements by forming a stream from the list:

ArrayList<String> numbers = new ArrayList<>();

numbers.add("23");
numbers.add("9");
numbers.add("7");
numbers.add("3");

int sum = numbers.stream().mapToInt(number -> Integer.valueOf(number)).sum();
System.out.println("The sum of the numbers: " + sum);
 

The program prints:
42
 

In this stream, we need the operation 'mapToInt', which converts the pieces into int type. 
Here again, we use a lambda expression and give the operation as Integer's valueOf.






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


Somewhat confusingly, the operation is also needed when the list is already of integer type. 
This is because certain terminal operations only work when the elements are of type 'int' ('Integer' is not acceptable):

ArrayList<Integer> numbers = new ArrayList<>();
for (int i=1; i<20; i+=2) {
    numbers.add(i);
}

System.out.println(numbers);

// The confusing-looking "change" number -> number converts
// an Integer stream into an int stream
System.out.println("The sum of the numbers: " + numbers.stream().mapToInt(number -> number).sum());
 

The program prints:
[1, 3, 5, 7, 9, 11, 13, 15, 17, 19]
The sum of the numbers: 100
 


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


Other handy operations include average, min, and max, 
which return the average, minimum, and maximum of a list of numbers:

 

ArrayList<Integer> numbers = new ArrayList<>();
for (int i=1; i<10; i++) {
    numbers.add(i);
}
System.out.println(numbers);

System.out.println("Maximum:");
System.out.println(numbers.stream().mapToInt(number -> number).max().getAsInt());

System.out.println("Minimum:");
System.out.println(numbers.stream().mapToInt(number -> number).min().getAsInt());

System.out.println("Average:");
System.out.println(numbers.stream().mapToInt(number -> number).average().getAsDouble());
 

The program prints:
[1, 2, 3, 4, 5, 6, 7, 8, 9]
Maximum:
9
Minimum:
1
Average:
5.0




 

Now, a terminal operation is needed to convert the result into a number, for example, getAsInt(). 
This is because the output of the preceding max operation is not an integer but a value of type 'OptionalInt'.

An 'extended type' from a normal integer (such as 'OptionalInt') is needed because the list might not contain any values 
- in which case the maximum value of the list cannot be presented as an integer.








If the stream is empty when it comes to the max operation, the getAsInt() operation will throw an exception:

ArrayList<Integer> numbers = new ArrayList<>();

// In an empty stream, there is no maximum...
int max = numbers.stream().mapToInt(number -> number).max().getAsInt();

The programs throws an exception:
Exception in thread "main" java.util.NoSuchElementException: No value present
 






The problem can be circumvented either by
1- CHECKING that the LIST is NOT EMPTY or
2- by performing the 'getAsInt' operation only AFTER it has been confirmed that the VALUE EXISTS:

OptionalInt max = numbers.stream().mapToInt(number -> number).max();

if (!max.isEmpty()) {
    System.out.println("Maximum: " + max.getAsInt());