# Functional Programming with Lambda Expressions and Streams ### Functional Programming with Lambda Expressions and Streams

#### 1. What is functional programming?

Functional programming is a programming paradigm—a style of building the structure and elements of computer programs—that treats computation as the evaluation of mathematical functions and avoids changing-state and mutable data.

#### 2. Can you give an example of functional programming?

```@Test
public void sumOfOddNumbers_Usual() {
List < Integer > numbers = Arrays.asList(1, 3, 4, 6, 2, 7);
int sum = 0;
for (int number: numbers)
if (number % 2 != 0) sum += number;
assertEquals(11, sum);
}

@Test
public void sumOfOddNumbers_FunctionalProgrammingExample() {
List < Integer > numbers = Arrays.asList(1, 3, 4, 6, 2, 7);
int sum = numbers.stream().filter(Test123::isOdd).reduce(0, Integer::sum);
assertEquals(11, sum);
}

static boolean isOdd(int number) {
return number % 2 != 0;
}
```

#### 3. What is a Stream?

A Stream is a source of objects. In the above example, we created a stream from List.
Streams have Intermediate Operations and Terminal Operations. In the example above, we used filter as intermediate operation and reduce as a terminal operation.

#### 4. Explain about streams with an example?

Streams are introduced in Java 8. In combination with Lambda expressions, they attempt to bring some of the important functional programming concepts to Java.

A stream is a sequence of elements supporting sequential and parallel aggregate operations. Consider the example code below. Following steps are done:-

• Step I : Creating an array as a stream

• Step II : Use Lambda Expression to create a filter

• Step III : Use map function to invoke a String function

• Step IV : Use sorted function to sort the array

• Step V : Print the array using forEach

```Arrays.stream(new String[] {
"Ram",
"Robert",
"Rahim"
})
.filter(s - > s.startsWith("Ro"))
.map(String::toLowerCase)
.sorted()
.forEach(System.out::println);
```

In general any use of streams involves :-

• Source – Creation or use of existing stream : Step I above

• Intermediate Operations – Step II, III and IV above. Intermediate Operations return a new stream

• Terminal Operation – Step V. Consume the stream. Print it to output or produce a result (sum,min,max etc).

Intermediate Operations are of two kinds :-

• Stateful : Elements need to be compared against one another (sort, distinct etc)

• Stateless : No need for comparing with other elements (map, filter etc)

#### 5. What are Intermediate Operations in Streams?

An Intermediate Operation on a Stream returns another Stream.
Examples : map, filter, distinct, sorted.

Distinct Example

```@Test
public void streamExample_Distinct() {
List < Integer > numbers = Arrays.asList(1, 1, 2, 6, 2, 3);
numbers.stream().distinct().forEach(System.out::print);
// 1263
}
```

Sorted Example

```@Test
public void streamExample_Sorted() {
List < Integer > numbers = Arrays.asList(1, 1, 2, 6, 2, 3);
numbers.stream().sorted().forEach(System.out::print);
// 112236
}
```

Filter Example

```@Test
public void streamExample_Filter() {
List < Integer > numbers = Arrays.asList(1, 3, 4, 6, 2, 7);
numbers.stream().filter(Test123::isOdd).forEach(System.out::print);
// 137
}
```

#### 6. What are Terminal Operations in Streams?

Terminal Operation either produce a result or create a side effect.

reduce is used to cumulate elements.

```@Test
public void sumOfOddNumbers_FunctionalProgramming() {
List < Integer > numbers = Arrays.asList(1, 3, 4, 6, 2, 7);
int sum = numbers.stream().filter(Test123::isOdd).reduce(0, Integer::sum);
assertEquals(11, sum);
}
```

forEach is used to create a side effect. Print to Output. Store to database.

```@Test
public void streamExample_Filter() {
List < Integer > numbers = Arrays.asList(1, 3, 4, 6, 2, 7);
numbers.stream().filter(Test123::isOdd).forEach(System.out::print);
// 137
}
```

collect is used to group elements to a collection

```@Test
public void streamExample_Collect() {
List < Integer > numbers = Arrays.asList(1, 3, 4, 6, 2, 7);
List < Integer > oddNumbers = numbers.stream().filter(Test123::isOdd).collect(Collectors.toList());
System.out.println(oddNumbers);
// [1, 3, 7]
}
```

#### 7. What are Method References?

Integer::sum, System.out::print in the above examples are method references. These two are simple static methods which are used instead of Lambda Expressions.

#### 8. What are Lambda Expressions?

A lambda expression is an anonymous function. Simply put, it’s a method without a declaration. There will be no access modifiers, no return value declaration, and no name. It’s a shorthand that allows you to write a method in the same place you are going to use it. Especially useful in places where a method is being used only once, and the method definition is short.

Syntax : Parameters -> Executed code

#### 8. Can you give an example of Lambda Expression?

In the example below, number -> System.out.print(number) is a lambda expression.

```@Test
public void lambdaExpression_simpleExample() {
List < Integer > numbers = Arrays.asList(1, 3, 4, 6, 2, 7);
numbers.stream().filter(Test123::isOdd).forEach(number - > System.out.print(number));
// 137
}
```

#### 9. Can you explain the relationship between Lambda Expression and Functional Interfaces?

Look at the earlier example : Function we passed in is number -> System.out.print(number). Input to this function is number. The function consumes it and prints it to the output.

forEach function has an interface – void java.util.stream.Stream.forEach(Consumer action)

The JavaDoc for java.util.function.Consumer reads – @FunctionalInterface : Represents an operation that accepts a single input argument and returns no result. Unlike most other functional interfaces, Consumer is expected to operate via side-effects.

When ever we create a Lambda Expression, we are defining a function which implements a predefined/custom defined Functional Interface.

#### 10. What is a Predicate?

```@FunctionalInterface
public interface Predicate < T > {
boolean test(T t);
}
@Test
public void lambdaExpression_predicate() {
List < Integer > numbers = Arrays.asList(1, 3, 4, 6, 2, 7);
numbers.stream()
.filter((number) - > (number % 2 != 0))
.forEach(number - > System.out.print(number));
// 137
}
```

(number) -> (number % 2 != 0) is a Predicate. Takes an argument and returns true of false.

Signature of filter function : Stream java.util.stream.Stream.filter(Predicate predicate). filter returns a stream consisting of the elements of this stream that match the given predicate.

#### 11. What is the functional interface – Function?

```@FunctionalInterface
public interface Function < T, R > {
R apply(T t);
}
```

#### 12. What is a Consumer?

```@FunctionalInterface
public interface Consumer < T > {
void accept(T t);
}
```

#### 12. Can you give examples of functional interfaces with multiple arguments?

```@FunctionalInterface
public interface BiFunction < T, U, R > {
R apply(T t, U u);
}
```

#### 13. What are the new features in Java 7?

• Diamond Operator.

o Example :

`Map<String , List <Trade>> trades = new TreeMap <> ();`

• Using String in switch statements

• Automatic resource management

o try(resources_to_be_closed){ // your code }

• Numeric literals with underscores

• Improved exception handling

o Multiple catches in same block

o catch(ExceptionOne | ExceptionTwo | ExceptionThree e)

#### 14. What are the new features in Java 8?

Java 8 brought in a number of important new features.

• Lamda Expressions. Example : Runnable java8Runner = () -> { Sysout(“I am running”); };

• Nashorn : javascript engine that enables us to run javascript to run on a jvm

• String.join() function

• Streams