Spaces:
Running
Running
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());
|