Skip to content

Instantly share code, notes, and snippets.

@DavidBiesack
Last active July 27, 2023 13:03
Show Gist options
  • Save DavidBiesack/e4bc3151d0c9cdaf2f6a to your computer and use it in GitHub Desktop.
Save DavidBiesack/e4bc3151d0c9cdaf2f6a to your computer and use it in GitHub Desktop.
Errata for Pluralsight "What's new in Java 8" course

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.

Module 1 - Lambdas

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>

Method References

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.

Module 2

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);

Module 4

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).

@enzobonggio
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment