Streams of Java 8
1 Abstract
Streams of Java8. Prereq: Java 8 Lambda Expressions, functional interfaces and method references.
2 Overview
- The streams discussed here are unrelated to
InputStream
andOutputStream
from Java IO. - A stream is a sequence of "items". Can be infinite.
- Never expect to have the "entire" stream to be available "at once". Typically, we use items from the head, then wish to access the next item. This is computed lazily (i.e., on demand).
- Java8
stream
s are monads. "In functional programming, a monad is a structure that represents computations defined as sequences of steps" – WikiPedia. - Any collection can be made into a stream. A
List <Integer> ilst = Arrays.asList (1, 2, 3, 5, 7, 11)
can be made into a stream of those 6 integers.
2.1 Example: An Int Stream
IntStream ns = ss.stream().mapToInt(s -> s.length()).filter(i -> i%2 != 0);
ss
was aList<String>
. Thestream()
converted it to a stream.mapToInt
mapped each string to its length. The filter function removed all odd numbers from the result. There were two uses of the lambda expressions. (Past tense was used just to explain.)- The object named
ns
will-contain/ contains the resulting stream. - But, the entire stream value is not constructed "up front". It is computed on a need-to-have basis, known as lazy evaluation. The above is "just" a declaration of an object that you "want."
2.2 Ordered Streams
- A stream whose source is an array, a List, or a generator function, is ordered.
- A stream whose source is a Set is unordered.
3 Map + Reduce
- We already used the idea of a map: Apply a function to each value of a collection and gather the resulting collection of the same structure.
- Reduce is the name given to an operation that takes a collection and computes "one-thing" out of it.
- Example: Sum up all the numbers of a Set.
3.1 Example
Example below is from https://docs.oracle.com/javase/tutorial/collections/streams/reduction.html
double average = roster .stream() .filter(p -> p.getGender() == Person.Sex.MALE) .mapToInt(Person::getAge) .average() .getAsDouble();
p -> p.getGender()
= =Person.Sex.MALE
a lambda expression as as a true/false yielding predicate.mapToInt
is a function that applies the function given as its argument to every item in the stream. A new stream is constructed with these results.Person::getAge
a lambda expression omitting the bound var of the lambdaaverage
is a reduction.
4 Example: Log Analysis
- ../Java/src/AuthLogStreamEx.java Look for "Invalid" attempts to login from the /var/log/auth.log file; 50+ lines long. A complete Java program. Colorized | Plain
% javac AuthLogStreamEx.java
% java AuthLogStreamEx auth.log.txt invalidUsers.txt
- Input data file for the above: auth.log.txt Copy of a
/var/log/auth.log
. - Output data file for the above: invalidUsers.txt
5 References
- http://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html Reference.
- Brian Goetz, Lambdas and Streams in Java 8 Libraries, DrDobbs article, 2014. Recommended Reading
- Lectured using these PDF slides by www.cs.cmu.edu/~charlie. "Lambdas and Streams in Java8", 2014. Required Reading.