Java 8 Streams Flashcards

1
Q

Till Java 7 it provided abstraction such as inheritance and generics, what did these things abstract?

A

Abstraction over data

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

Lambda expressions provide abstraction over what?

A

Abstraction over behavior

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

Does lambda and streams make Java functional language?

A

No, functions are still not first class citizens in Java.

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

What was main goal behind Java 8 lambda and streams?

A

The main goal was to make it easy, less error-prone to write parallel and concurrent code and utilize multiple cores available. At the same time improve readability of such code.

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

By default till Java 7, for each loop was serial or parallel?

A

It was fixed as serial implementation. We couldn’t use multiple cores for iteration even if available. We had to write parallel code ourselves which is very hard to get right.

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

Example where serial model is bottleneck

A

Suppose someone asked you to mail some letters with following instructions: If you have any more mails, take next one in alphabetical order of addressee’s surname and put it in mailbox. Obviously problem is overspecified. Ordering doesn’t matter in this task, neither does the mode serial or parallel.

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

coll.forEach(Consumer), then Consumer is example of which GoF design pattern?

A

Command design pattern. Caller just knows what operation he needs to perform and iteration is done by foreach()

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

Why were lambda expressions added?

A
  • To make it less clumsy to add implementation of FunctionalInterfaces. Before that only way to do that was either create a dedicated class or create anonymous inner class.
  • It reduced the verbosity, as rest of the things like method name of functional interfaces, interface name could be inferred by compiler.
How well did you know this?
1
Not at all
2
3
4
5
Perfectly
9
Q

Stream allows us to view program in what way?

A

Data oriented way of looking at the program.

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

What are stream and operators analogous to?

A

Unix pipes and filters

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

What do streams represent?

A

Streams represent data in motion and don’t provide any way to store the data.

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

Name Streams for primitives?

A

IntStream, LongStream, DoubleStream etc.

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

Is stream eager or lazy?

A

Streams are lazy, all the intermidiate operators are lazy and the terminal operators like max, min, forEach() etc start pulling data from the source lazily.

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

What can be sources of streams?

A

Collections, Arrays or Generating functions like IntStream.generate(..)

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

What is recursive decomposition?

A

The process of splitting tasks into smaller ones to be executed in parallel, till they are “small enough” to be executed in serial. The technique for splitting depends on source of data.

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

What fundamental principle does Fork Join pool in Java depend on?

A

Recursive decomposition.

17
Q

What is the way to telling java to use parallel execution to process the stream?

A

Source.parallelStream() is the way to tell java that parallel stream can be used which will utilize Fork/Join framework.

18
Q

Use of sorted operator and comparing, by example

A
intList.stream()
.map(i -> new Point(i % 3, i / 3))
.sorted(comparing(point -> p.distance(0, 0)))
.forEach(print);
19
Q

Which ordering does Comparator.comparing() return?

A

Natural ordering

20
Q

Comparator.comparing() method signature?

A

public static > Comparator comparing(Function keyExtracter)

21
Q

Is it allowed to provide explicit type in lambda parameters?

A

Yes it is allowed. But if type is provided for one it must be provided for all. And it is sometimes necessary to provide type information when the compiler cannot infer it from the context.
() -> 23
(x, y) -> x + y
(int x, int y) -> x + y

22
Q

Expression lambda vs statement lambda

A
Expression lambda can have only a single line and there is an explicit return, including for void. So for example x -> x * 3, i -> print(i), (x, y) -> x + y are expression lambdas.
Statement lambda are general where you can have curly braces block where you can write multiple lines of code. But that code needs to have explicit return statement.
For example (Thread t) -> {t.start();}, () -> {System.gc(); return 0; }

An expression lambda can be seen as args -> expr
A statement lambda can be seen as args -> {return expr;}

23
Q

Are lambda expressions allowed to declare exceptions they can throw using throws clause?

A

No, lambda expressions are neither required nor allowed to use throws clause to declare the exceptions they can throw.

24
Q

Lambda vs anonymous inner class

A
1 - An inner class creation expression is guaranteed to create a new object with unique identity but that is not true for lambda expression. It is implementation dependent.
2 - An inner class declaration creates new naming scope where this and super refer to current inner class. By contrast lambda expressions do not introduce any naming environment. So using this in lambda refers to enclosing class in which lambda is defined.
25
Q

Can lambda expressions have state?

A

No. Lambda expressions are not allowed to have state. So their identity does not matter. This allows platform flexibility to optimize in ways which would not be possible if all lambda expressions were required to have unique identity.

26
Q

Can a lambda refer to itself?

A

We cannot use this to refer to lambda, but a lambda can refer to itself if its name is in the scope but there are few restrictions. It is still possible to declare recursive lambda

class Factorial {
  IntUnaryOperator fact;
  public Factorial() {
    fact = i -> i == 0 ? 1 : i * fact.applyAsInt(i - 1);
  }
}
27
Q

Can lambda parameters and lambda body local declarations shadow field names?

A

Yes a field name can be temporarily redeclared as a parameter or local variable name

class Foo {
  Object i, j;
  IntUnaryOperator iuo = i -> { int j = 3; return i + j;}
}
28
Q

Is it possible to redeclare a local variable in lambda?

A

No, it is illegal to redeclare a local variable within a lambda

void foo() {
  final int i = 2;
  Runnable r = () -> {int i = 3; }} // illegal
}
29
Q

What is a non-capturing lambda?

A

A lambda which interact with environment only via arguments and return values are stateless or non-capturing.

30
Q

What is a capturing lambda?

A

Capture is a technical term for the retention by a lambda of a reference to its environment. The connotation is that the variable has been ensnared by the lambda and held, to be queried or in other lamguages - modified, when the lambda is later evaluated.

31
Q

Can a lambda change the captured variable?

A

No, the capture provided is restricted; the central principle of the restriction is that captured variables may not have their values changed.

32
Q

Anonymous class variable capture vs Lambda variable capture?

A

In case of Anonymous class we needed to make the variable final, but in case of Lambda, there is no need to explicitly mark it as final. It should be effectively final.