Java 8 Flashcards

1
Q

Behavior parameterization

A

Behavior parameterization is a useful pattern to easily adapt to changing requirements and saves on engineering efforts in the future

This is the ability for a method to take multiple different behaviors as parameters and use them internally to accomplish different behaviors.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
2
Q

Behavior parameterization steps

A
  1. Model your selection criteria (predicate):
    public interface ApplePredicate{boolean test (Apple apple); }}
  2. Now declare multiple implementations of ApplePredicate to represent different selection criteria

This is related to the strategy design pattern

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
3
Q

Strategy pattern

A

strategy design pattern lets you define a family of algorithms, encapsulate each algorithm (called a strategy), and select an algorithm at run-time.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
4
Q

Verbose language

A

the programmer must write a lot of code to do minimal job

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
5
Q

Boilerplate code

A

boilerplate refers to sections of code that have to be included in many places with little or no alteration.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
6
Q

Examples of methods that can be parameterized with different behaviors in Java API

A

The Java API contains many methods that can be parameterized with different behaviors, which
include sorting, threads, and GUI handling.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
7
Q

Lambda expression

A
A lambda expression can be understood as a concise representation of an anonymous function
that can be passed around: 
- Anonymous— it doesn’t have an explicit name like a method would normally have: less to write and think about!
- Function—  lambda isn’t associated with a particular class like a method is.But like a method, a lambda has a list of parameters, a body, a return type, and a possible list of exceptions that can be thrown.
- Passed around— A lambda expression can be passed as argument to a method or stored in a variable.
- Concise— You don’t need to write a lot of boilerplate like you do for anonymous classes
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
8
Q

Why lambda expresions

A

code will be clearer and more flexible.
- you no longer have to write clumsy code using anonymous classes to benefit from behavior parameterization!

-Lambda expressions let you provide the implementation of the abstract method of a functional interface directly inline and treat the whole expression as an instance of a functional interface (more technically speaking, an instance of a concrete implementation of the functional interface).

You can achieve the same thing with an anonymous inner class, although it’s clumsier

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Where can you use lambdas

A

You can use a lambda expression in the context of a
functional interface.

filter(inventory, (Apple a) -> “green”.equals(a.getColor()));

In the code shown here, you can pass a lambda as second argument to the method filter because it expects a Predicate, which is a functional interface

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
10
Q

Functional interface. Examples from Java Api

A

= an interface that specifies exactly one abstract method.

Examples: Comparator, Runnable, ActionListener, Callable

@FunctionalInterface - used to indicate that the interface is intended to be a functional interface.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
11
Q

Why we need functional interfaces?

A

Functional interfaces are useful because the signature of the abstract method can describe the
signature of a lambda expression.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
12
Q

Function descriptor

A

The signature of the abstract method of the functional interface essentially describes the
signature of the lambda expression. We call this abstract method a function descriptor

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
13
Q

Lambdas in practice

A

+ behavior parameterization
+ execute around pattern -the setup and cleanup phases are always similar and surround the important code doing the processing. This is called the execute around pattern,

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
14
Q

New functional interfaces in Java 8

A

Most popular:

  • Predicate - need to represent a boolean expression that uses an item
  • Consumer - when perform some operations on a item
  • Function - when maping information from an input object to an output
Predicate         T -> boolean 
Consumer        T -> void 
Function       T -> R
Supplier            () -> T
UnaryOperator T -> T
BinaryOperator (T, T) -> T
Bi(Predicate/Consumer/Function)
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
15
Q

Boxing, Unboxing, Autoboxing

Performance cost

A

in Java there’s a mechanism to convert a primitive type into a corresponding reference type. This mechanism is called boxing.

The opposite approach (that is, converting a reference type into a corresponding primitive type) is called unboxing.

Java also has an autoboxing mechanism to facilitate the task for programmers: boxing and unboxing operations are done automatically.

But this comes with a performance cost. Boxed values are essentially a wrapper around primitive types and are stored on the heap. Therefore, boxed values use more memory and require additional memory lookups to fetch the wrapped primitive value.

How well did you know this?
1
Not at all
2
3
4
5
Perfectly
16
Q

Type inference

Example

A

Type inference refers to the automatic deduction of the data type of an expression in a programming language.

List listOfStrings = new ArrayList<>();
lambda: a -> “green”.equals(a.getColor())

17
Q

Lambda Type checking

A

The type of a lambda is deduced from the context in which the lambda is used.

The type expected for a lambda expression is called the target type.

18
Q

Lambda Type inference

A

The Java compiler deduces what functional
interface to associate with a lambda expression from its surrounding context (the target type),
meaning it can also deduce an appropriate signature for the lambda because the function
descriptor is available through the target type.

a -> “green”.equals(a.getColor())

Note that sometimes it’s more readable to include the types explicitly and sometimes more readable to exclude them.

19
Q

Lamda syntax

A

(parameters) -> expression
or
(parameters) -> { statements; }

When type is infered (round parantheses can be ommited):
paramenter -> expression

20
Q

Lambda Using local variables

A

Lambdas are allowed to capture (that is, to reference in their bodies) instance variables and static variables without restrictions.
But local variables have to be explicitly declared final or are effectively final

WHY THIS RESTRICTION?
Case 1:
public static void repeatMessage(String text, int count) {
    Runnable r = () -> {
        for (int i = 0; i < count; i++) {
            System.out.println(text);
        }
    };
    new Thread(r).start();
}
PROBLEM: Lambda expression may run long after the call to repeatMessage has returned and the parameter variables are gone
Case2:
vois someMethod(){
     int a;
     Runnable r = () -> {a = random();}
     new Thread(r).start();
     new Thread(r).start();
}
If two threads update var a at the same time, its value is undefined.
21
Q

Method references

A
  • shorthand for lambdas calling only a specific method.
    if a lambda represents “call this method directly,” it’s best to refer to the method by name rather than by a description of how to call it.

Method references let you reuse an existing method implementation and pass it around directly.

For example,
Apple::getWeight is a method reference to
(Apple a) -> a.getWeight().

Remember that no brackets are needed because you’re not actually calling the method

22
Q

Constructor references

A

You can create a reference to an existing constructor using its name and the keyword new as
follows: ClassName::new.

It's important that lambda matches apropiate signature, for example:
ZERO argument constructor: Suplier s = Apple::new  // () -> new Apple()
ONE argument constructor: Function f = Apple::new // (Integer weight) -> new Apple(weight)
TWO arg constructor: BiFunction bf = Apple:new // (Integer weight, String color) -> new Apple(weight, color);
23
Q

Streams

A

Stream is a sequence of elements from a source that supports data processing operations.

  • Sequence of elements — Like a collection, a stream provides an interface to a sequenced set of
    values of a specific element type.
  • Source —Streams consume from a data-providing source such as collections, arrays, or I/O resources.
  • Data processing operations— Streams support database-like operations and common operations
    from functional programming languages to manipulate data, such as filter, map, reduce, find,
    match, sort, and so on. Stream operations can be executed either sequentially or in parallel.
24
Q

Advantages Streams

A

Streams API in Java 8 lets you write code that’s
Declarative— More concise and readable
Composable— Greater flexibility
Parallelizable— Better performance,
Can be mentioned 2 most important characteristcs:
Pipelining
Internal Interation - due to this, the Streams API can decide to run your code in parallel. Using external iteration, this isn’t possible because you’re committed to a single-threaded step-by-step sequential iteration.

  • Streams lets you manipulate collections of data in a declarative way
  • Streams can be processed in parallel transparently, without you having to write any multithreaded code! (To exploit a multicore architecture)
25
Q

Collections VS Streams

A

Collections are about data; streams are about computations.

BOTH are sequence of elements
COLLECTIONS are computed at construction, STREAMS are computed at iteration
COLLECTIONS - external iteration(ex: using
for-each), STREAMS - internal iteration
COLLECTIONS - finite size, STREAMS - infinte size
STREAMS traversed only one. After that a stream is said
to be consumed.

*Collections first complete/create the collection, then is open to some operation (collection of all prime numbers -> a program loop that forever computes a new prime, dding it to the collection)
Stream’s elements are computed on demand.

26
Q

Streams- 2 most important characteristcs

A

Pipelining— Many stream operations return a stream themselves, allowing operations to be chained
and form a larger pipeline. This enables certain optimizations that we explain in the next chapter, such
as laziness and short-circuiting. A pipeline of operations can be viewed as a database-like query on
the data source.
Internal iteration— In contrast to collections, which are iterated explicitly using an iterator,
stream operations do the iteration behind the scenes for you.

27
Q

Stream operations

A
  • intermediate operations- that can be connected together to form a pipeline ( filter, map, limit)
  • terminal operations - that executes the pipeline, close stream, and return a result (collect - list, count-int, foreach -void)
28
Q

Optimization due to lazy nature of streams

  • short-circuiting
  • loop fusion
A

main.stream().filter(…).map(…).limit(3).collect(toList());

It will be executed in following way:
filtering pork
mapping pork
filtering beef
mapping beef
filtering chicken
mapping chicken
[pork, beef, chicken]
  1. Despite the fact that many dishes have > 300 calories, only the first three are selected! This is because of the limit operation and a technique called short-circuiting
  2. Despite the fact that filter and map are two separate operations, they were merged into
    the same pass (we call this technique loop fusion)
29
Q

working with streams in general involves three items

A

A data source (such as a collection) to perform a query on
A chain of intermediate operations that form a stream pipeline
A terminal operation that executes the stream pipeline and produces a result

30
Q

Streams is similar to the …………… pattern

A

BUILDER
In the builder pattern, there’s a chain of calls to set up a configuration (for streams this is a chain of intermediate
operations), followed by a call to a build method (for streams this is a terminal operation).