This gist contains some errors I have found and my suggestions for improving the Pluralsight training, "What's New in Java 8" by Jose Paumard.
Should exlain why these are called 'lambdas' - i.e. lambda calculus and the foundations of functional programming
Should describe why -> is used, provide a name for it (arrow).
Describe a function
args -> body
as a mapping of args to a computed result. a Function is a mapping of inputs to output
A 'functional interface' is not a type.
I can't use it as a variable / parameter / field type in Java code, and I cannot express it with instanceof (Also, @FunctionalInterface is a just an annotation, it is also not a type.) "Type" has specific meaning in Java and in programming languages, saying the "type of a lambda expression is a functional interface" is the wrong use of the term "type".
Note:
(T u) -> expression
and (T t, U u) -> expression
are not two different syntax forms. They are the same form.
Module I, slide The Functional Interface Toolbox
function categories
public boolean Predicate<T t, U u>
should be
public boolean BiPredicate<T t, U u>
The slide shows
Consumer<String> c = s -> System.out.println(s);
The earlier slides showing the syntax for lambdas did not discuss omitting the parens on the arguments, only the form
(String s) -> System.out.println(s)
This is new here but not described as new notation.
short for:
Consumer<String> c = (s) -> System.out.println(s);
which is short for: Consumer c = (String s) -> System.out.println(s);
I think the focus of this module is wrong. It overemphasizes the notation convenience of using lambdas (as an extension of or abbreviation of anonymous classes) which really misses the point of the use of functions as objects whcih are then passed as arguments to other functions/methods... that is, the foundation of functional programming.
Map/Filter/Reduce/ Algorithm
typo "Let's take a list a Person"
Drawback of map / filter / reduce is that it may be more efficient to to filter / map / reduce in this case.... this is certainly the case with the examples shown. Consider transient garbage and creating a new large list vs crating a new a small list; creating many new Integer objects vs. creating few Integer objects. Often the function chaining is filter / map / filter / reduce
But filter / map / reduce requires more custom code (i.e. filter on person -> person.getAge() > 20 compared to filter on age -> age > 20
Given the intro to map / filter / reduce, you should introduce the map operation first, then filter.
The presenter consistently uses the terms "intermediary operation" and "final operation", but the correct terms are "intermediate operation" and "terminal operation".
States that streams contain no data, but that's not always true; for example String.chars() is an IntStream that stores the input from which the stream is derived; the same is true for Arrays.stream(array). Some stream operations can and must store state - stateful operations such as sort must consume and effectively store the entire stream before returing their contents as a new stream.
MyType val = opt.orElseThrow(NoSuchValueException::new)
the ::new is a function (lambda) - that is, new is not called unless needed - lazy. New form of a function method reference to new SomeType()
typo:
persons.stream()
.map(person -> person.getLastName())
.allMatch(length < 20);
should be
persons.stream()
.map(person -> person.getLastName())
.allMatch(s -> s.length() < 20);
In segment 2, Strings and String Joiner, the slide at :40 shows
Stream stream = s.chars();
but this should be
IntStream stream = s.chars();
Also, the next line of code
stream.map(String::toUpperCase).forEach(System.out::print);
is also wrong because String::toUpperCase cannot be passed to an IntStream because the elements are int not String.
Instead, this produces the expected output:
stream.map(Character::toUpperCase).forEach(c -> System.out.print((char) c));
Since this is processing an IntStream, the values must be cast to (char) before printing (else System.out::print would print the integer code points, yielding the output
72697676794432877982766833
instead of
HELLO WORLD!
While most of the errors in this presentation are minor, the section introducing StringJoiner contains some serious misperceptions and misprepresetations of Java.
There is no problem whatsover with concatenation of strings such as
String s = s1 + " " + s2
This has long used StringBuffer, then StringBuilder starting with Java 5, and does not create/delete intermediate strings.
What is bad / inefficient is the use of things like
s = s + "string";
inside a loop. But this section implies even simple concatenation should be rewritten with StringBuilder or StringJoiner, and that is simply not the case.
One should never, never replace
String s = s1 + " " + s2
with
String s = StringBuffer(s1).append(" ").append(s2).toString();
(or the new StringJoiner equivalent) for a simple string concatenation as shown!!!
One should use a StringBuilder when contcatenatation occurs in a loop, for example, in a loop
for (String s2 : myStringArray)
s = s + " " + s2;
Likewise, one should never use StringJoiner to concatenate a fixed set of strings; again, just use the + operator. Use StringJoiner when you have an array or Stream of strings, or you are adding incrementally (in a loop).
In "reading text files", should note that Paths is in java.nio.file.Paths (the package is not obvious).
never use StringJoiner to concatenate a fixed set of strings;
but if you have "person1, person2, person3" but then they want "person1 - person2 - person3" you have to change the code in 3 places. I usually use ",".join(list) idk if writing those + ", " is a good practice