JCombiner is a framework to generate combinations of collections for Java. I have written it in Java 11 using Java 9 modules (JPMS) and Gradle as build tool. JUnit 5 and Mockito are used for unit testing and Jacoco for code coverage. Streams and the Collectors API are extensively used throughout the development of JCombiner project.

Some years ago I wrote junit-parameters, which is basically a custom JUnit test runner that make it possible to add parameters to JUnit 4 test methods.

Browsing its source code SonarLint pointed me a large conditional if/else method from the ParameterTypeConverterFactory class:

This method converts the method parameter to its specific type based on its Class object. As it is few lines long, it showed me a good opportunity to refactor this code a little bit with a more elegant solution. This project has unit tests, so I could start refactoring it in small steps and start over again whether I have made a mistake.

This was the first change of breaking this complicated conditional method into a more readable one. It was safe to do so because after each change I could run my unit tests suite to assert I haven’t broken anything. The next refactoring could be towards a more object-oriented approach like Replace Conditional with Polymorphism.

What did you think about this refactoring? Have you ever had such a situation? Drop your comments here!

Although Java 9 has already been released, this post is about converting an optional collection to the Streams API introduced in Java 8.

Suppose some person could have zero, one or more cars and it is represented by the Person class below (some code omitted).

Java

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

publicclassPerson{

privateStringname;

.

.

.

publicOptional<Collection<Car>>getCars(){

returnOptional.ofNullable(cars);

}

.

.

.

}

Now we create a list of people and we want to get Mark’s cars.

Java

1

2

3

Person mark=newPerson("Mark");

List<Person>people=...

How can we do that using the Streams API, since the getCars() method return an Optional?

One possibility is to filter people’s list by Mark’s name, filter the Optional if it is present or not and map its wrapped value (our cars list):

Java

1

2

3

4

5

6

7

8

Collection<Car>markCars=people

.stream()

.filter(person->"Mark".equals(person.getName()))

.findFirst()

.map(Person::getCars)

.filter(Optional::isPresent)

.map(Optional::get)

.orElse(Collections.emptyList());

At this moment we reached the reason of this blog post. And how can we get all people’s cars? The idea here is to use the flatMap() operation unwrapping the Optional to the collection’s stream when it is present or getting an empty stream when it isn’t present: