Functional Programming Flashcards
What types of variables can lambda expressions use?
static variables
instance variables
effectively final variables in methods (effectively final meaning they are only ever assigned one value and never altered)
Functional Interface
Supplier
1) # of Parameters?
2) Return Type?
3) Single Abstract Method It Contains?
1) 0
2) T
3) get
Functional Interface
Consumer
1) # of Parameters?
2) Return Type?
3) Single Abstract Method It Contains?
1) 1 (T)
2) void
3) accept
Functional Interface
BiConsumer
1) # of Parameters?
2) Return Type?
3) Single Abstract Method It Contains?
1) 2 (T, U)
2) void
3) accept
Functional Interface
Predicate
1) # of Parameters?
2) Return Type?
3) Single Abstract Method It Contains?
1) 1 (T)
2) boolean
3) test
Functional Interface
BiPredicate
1) # of Parameters?
2) Return Type?
3) Single Abstract Method It Contains?
1) 2 (T, U)
2) boolean
3) test
Functional Interface
Function
1) # of Parameters?
2) Return Type?
3) Single Abstract Method It Contains?
1) 1 (T)
2) R
3) apply
Functional Interface
BiFunction
1) # of Parameters?
2) Return Type?
3) Single Abstract Method It Contains?
1) 2 (T, U)
2) R
3) apply
Functional Interface
UnaryOperator
1) # of Parameters?
2) Return Type?
3) Single Abstract Method It Contains?
1) 1 (T)
2) T`
3) apply
Functional Interface
BinaryOperator
1) # of Parameters?
2) Return Type?
3) Single Abstract Method It Contains?
1) 2 (T, T)
2) T`
3) apply
When do you use the Supplier functional interface?
When you want to generate or supply values without taking any input.
Think of it as creating something to supply
When do you use the Consumer or BiConsumer functional interface?
When you want to do something with a parameter (or two if BiConsumer) but not return anything.
Think of it as consuming the parameters
When do you use the Predicate or BiPredicate functional interface?
When filtering or matching.
It checks for a certain condition and returns true or false.
When do you use the Function or BiFunction functional interface?
When turning parameters into a value of a potentially different type and returning it.
Use the parameters to calculate/determine a result
When do you use the UnaryOperator or BinaryOperator functional interface?
When you want to transform a value (or two) into another value of the same type.
UnaryOperator extends Function
BinaryOperator extends BiFunction
Optional
A container object which may or may not contain a non-null value
How to represent an empty Optional object?
Optional.empty()
How to represent an Optional object with a value of 30?
Optional.of(30)
Optional.ofNullable(val)
Returns an Optional.empty() if val is null, or Optional.of(val) if val is non-null
Optional instance method
get()
When the Optional is empty, throws an exception
When the Optional contains a value, returns the value
Optional instance method
ifPresent(Consumer c)
When the Optional is empty, does nothing
When the Optional contains a value, calls Consumer c with the value
Optional instance method
isPresent()
When the Optional is empty, returns false
When the Optional contains a value, returns true
Optional instance method
orElse(T other)
When the Optional is empty, returns other
When the Optional contains a value, returns the value
Optional instance method
orElseGet(Supplier s)
When the Optional is empty, returns result of calling Supplier s
When the Optional contains a value, returns the value
Optional instance method
orElseThrow(Supplier s)
When the Optional is empty, throws the exception created by calling Supplier s
When the Optional contains a value, returns the value
Stream
A sequence of data
Stream Pipeline
The operations that run on a stream to produce a result
It has a source which starts the stream, intermediate operations that produce a chain of streams, and the final operation that produces the result, known as the terminal operation.
Stream package
java.util.stream
How to create an empty Stream
Stream empty = Stream.empty();
How to create a Stream with elements
Stream.of(T… t)
Can be one value, comma separated values, or an array
How to create a Stream from a List
list.stream()
or
list.parallelStream(); // Allows the stream to process elements in parallel
What does the following code do?
Stream.generate(Math::random)
Generates infinite random numbers
What does the following code do?
Stream.iterate(1, n -> n + 2)
Generates infinite odd numbers
It starts with 1, then continues infinitely using the previous result as n in the lambda
What is a reduction?
A special type of terminal operation where all of the contents of the stream are combined into a single primitive or Object.
Terminal Operation
count()
Determines the number of elements in a finite stream.
Returns a long
Terminal Operations
min() and max()
Allow you to pass a custom comparator and find the smallest or largest value in a finite stream according to that sort order.
Optional min( super T> comparator) Optional max( super T> comparator)
Terminal Operations
findAny() and findFirst()
findAny() will return any element in the stream so long as it is not empty
findFirst() will return the first element in the stream so long as it is not empty
Works with infinite streams!
Optional findAny() Optional findFirst()
Terminal Operations
anyMatch(), allMatch(), noneMatch()
anyMatch will find out whether at least one of the elements in the stream matches a given predicate.
allMatch will check every element in the stream and find out if it matches the predicate.
noneMatch will find if no elements in the stream match the specified predicate.
boolean anyMatch(Predicate super T> predicate) boolean allMatch(Predicate super T> predicate) boolean noneMatch(Predicate super T> predicate)
Terminal Operation
forEach()
forEach will perform an action for each element in the stream. It is a simplified inline way to write a for loop.
void forEach(Consumer super T> action)
Terminal Operation
reduce()
reduce uses a BinaryOperator to combine the elements of the stream into a single object.
Stream stream = Stream.of(3, 5, 6); System.out.println(stream.reduce(1, (a, b) -> a*b)); //90
T reduce(T identity, BinaryOperator accumulator) Optional reduce(BinaryOperator accumulator) <u> U reduce(U identity, BiFunction<u> accumulator, BinaryOperator<u> combiner)</u></u></u>
Terminal Operation
collect()
collect will convert the stream into some other container
Stream stream = Stream.of(“w”, “o”, “l”, “f”); StringBuilder word = stream.collect(StringBuilder::new,
StringBuilder::append, StringBuilder:append)
In this example, StringBuilder::new creates the object we will be adding elements of the stream to, the first StringBuilder::append tells it how to handle adding one element, and the second StringBuilder::append tells it how to handle combining two containers together (however it chooses to do that in the process)
R collect(Supplier supplier, BiConsumer accumulator, BiConsumer combiner) R collect(Collector super T, A,R> collector)
You can also use a predefined Collector such as this:
Stream stream = Stream.of(“w”, “o”, “l”, “f”); Set set = stream.collect(Collectors.toSet());
Intermediate Operation
filter()
Returns a Stream with elements that match a given expression
Stream filter(Predicate super T> predicate)
Stream s = Stream.of(“monkey”, “gorilla”, “bonobo”);
s.filter(x -> x.startsWith(“m”)).forEach(System.out::print); // monkey
Intermediate Operation
distinct()
Returns a stream with duplicate values removed
Stream distinct()
Stream s = Stream.of(“duck”, “duck”, “duck”, “goose”); s.distinct().forEach(System.out::print); // duckgoose
Intermediate Operations
limit() and skip()
limit(n) specifies the max size of the stream is n
skip(n) will skip to the nth element in the stream
Stream limit(int maxSize) Stream skip(int n)
Stream s = Stream.iterate(1, n -> n + 1); s.skip(5).limit(2).forEach(System.out::print); // 67
Intermediate Operation
map()
map will transform the elements elements in a stream using the provided Function
Stream map(Function super T, ? extends R> mapper)
Stream s = Stream.of(“monkey”, “gorilla”, “bonobo”); s.map(String::length).forEach(System.out::print); // 676
Intermediate Operation
flatMap()
Takes each element in the stream and makes any elements it contains top-level elements in a single stream.
This is helpful when you want to remove empty elements from a stream or you want to combine a stream of lists.
List zero = Arrays.asList();
List one = Arrays.asList(“Bonobo”);
List two = Arrays.asList(“Mama Gorilla”, “Baby Gorilla”); Stream> animals = Stream.of(zero, one, two);
animals.flatMap(l -> l.stream()).forEach(System.out::println);
Intermediate Operation
sorted()
Returns a stream with the elements sorted
Stream sorted() Stream sorted(Comparator super T> comparator)
Intermediate Operation
peek()
Allows you to perform an operation on the current element of the stream
Stream peek(Consumer super T> action)
Stream s = Stream.of(“monkey”, “gorilla”, “bonobo”);
s.peek(System.out::println);
What is the result of this code?
Stream.generate(() -> "Elsa") .filter(n -> n.length() == 4) .sorted() .limit(2) .forEach(System.out::println);
It hangs until you kill it.
Sorted will wait to sort until filter is done passing it stuff, so it never reaches the limit(2)
What is the result of this code?
Stream.generate(() -> "Elsa") .filter(n -> n.length() == 4) .limit(2) .sorted() .forEach(System.out::println);
Elsa Elsa
When filter passes 2 elements through to sorted(), limit(2) tells the code to move on and do the sort.
What is the result of this code?
Stream infinite = Stream.iterate(1, x -> x + 1); infinite.filter(x -> x % 2 == 1)
.peek(System.out::print)
.limit(5)
.forEach(System.out::print);
1133557799
The elements of the stream get passed through all the way down the pipeline before the next one
IntStream
A stream that contains primitives.
Can be used for int, short, byte or char
LongStream
A stream that contains primitives.
Can be used for long
DoubleStream
A stream that contains primitives.
Can be used for double or float
How to get the average of the numbers in this stream?
IntStream intStream = IntStream.of(1, 2, 3);
intStream.average()
Returns an OptionalDouble
How to create an IntStream with the numbers in the range 1-5?
IntStream range = IntStream.range(1,6)
IntStream range = IntStream.rangeClosed(1,5)
How to get the sum of the elements in this stream?
IntStream intStream = IntStream.of(1, 2, 3);
intStream.sum()
Returns an int
How to find the largest and smallest element in this stream?
IntStream intStream = IntStream.of(1, 2, 3);
intStream.max()
intStream.min()
Returns an OptionalInt
How to retrieve the value of the following OptionalInt?
OptionalInt optional;
optional.getAsInt()
If no element present, throws NoSuchElementException
How to get info on an IntStream that includes the minimum, maximum, average, size, and the number of values in the stream.
IntSummaryStatistics stats = intStream.summaryStatistics();
getAverage() getCount() getMax() getMin() getSum()
BooleanSupplier
Functional interface for boolean
boolean getAsBoolean()
What is the output of the following code?
Stream ohMy = Stream.of(“lions”, “tigers”, “bears”); String result = ohMy.collect(Collectors.joining(“, “)); System.out.println(result);
lions, tigers, bears
What is the output of the following code?
Stream ohMy = Stream.of(“lion”, “tigers”, “bears”);
Double result = ohMy.collect(Collectors.averagingInt(String::length)); System.out.println(result);
5.0
a Double