Interesting article about JUnit 5 parameterized tests using BDD (Behaviour-Driven Development) style. It shows an example of using @CsvSource as arguments source and a specific implementation of an argument converter. Have you ever used parameterized tests in your unit tests?
Posts Tagged programming
One of the common operations of the Collectors API introduced in Java 8 is the possibility to collect results into a result container like List, Set or Map. The following example uses the collect()
method to generate a HashSet
containing unique numbers:
Now suppose a given string and the need to compute some summaries on it, like the number of uppercase, lowercase, invalid chars and how many digits are present on that string.
Applying a reduce operation on each needed summary operation would result in more than one pass through the data, like this (here I am using the var keyword introduced in Java 10):
In the above code excerpt we are iterating three times through the string to compute the summaries. If we want to iterate just one time on the give string and get the desired results, we could fallback to the traditional imperative approach:
Despite the solution above, there is another one: writing your own custom stream collector. This custom collector can compute the number of uppercase, lowercase, invalid chars and how many digits are present on the given string, in a single pass through the data. It is possible to make it run in parallel
with the Streams API as well.
The custom stream collector shown here uses the chars()
method of the String class which returns an IntStream. The IntStream
class contains a collect()
method that computes a mutable reduction on the elements and returns its result in a container class.
The next example shows the container class code. It receives and accumulates each char
of the String in the accept()
method, thus categorizing it as a digit, uppercase char, lowercase char or as an invalid char.
The complete implementation of the collect() method which produces the result of the reduction in the CharSummaryStatistics class is shown below. As a new char arrives, it is categorized in the CharSummaryStatistics.accept()
method. The CharSummaryStatistics.combine()
method is used to merge partial results.
Have you ever written a custom Java stream collector? Please drop your comments here.
The complete source code can be found on GitHub.
As a reference for writing this post, this article is part of a series about Streams and it is a good reference for learning how to aggregate and collect with Streams. All the articles from this series about Streams can be found here.
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.
Jcombiner’s source code is available under GitHub.
Code examples of its usage can be found on GitHub here. More examples can be found on this module inside JCombiner.
Share your comments about this framework here! Please feel free to contribute to it, more features are welcome!
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.
I started by defining a functional interface called ParameterConverter
:
and I created an immutable map which maps each Class
object to its associated ParameterConverter
instance (making use of method references):
Then I refactored the original conditional method to get the ParameterConverter
instance from the convertersByClass
map and mapping to an Optional
instance in case it didn’t exist.
After those refactorings, SonarLint stopped warning me. Below is the modified version of the original method with some helper methods:
The complete code can be found at my GitHub here.
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!
Great session in JavaOne 2017 about Streams and lambdas introduced in JDK8.
The session shows many examples of Java code using forEach()
with side effects and how to refactor them to a functional approach using streams and the Collectors API.
What are your experiences using Streams and lambdas in JDK 8? Are you correctly using the Collectors API?
My friends Andre and Leonnardo have sent me an interesting article about some bad habits every Java developer should stop doing in their code.
Basically the author picked up the following points and discussed each one of them, showing code examples why they aren’t good practices at all:
- Returning Null
- Defaulting to Functional Programming
- Creating Indiscriminate Getters and Setters
I agree with all these points as being bad practices in Java code. How about you? What do you think about it?
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).
public class Person { private String name; . . . public Optional> getCars() { return Optional.ofNullable(cars); } . . . }
Now we create a list of people and we want to get Mark’s cars.
Person mark = new Person("Mark"); Listpeople = ...
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):
CollectionmarkCars = 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:
CollectionallPeopleCars = people .stream() .map(Person::getCars) .flatMap(mayHaveCars -> mayHaveCars.isPresent() ? mayHaveCars.get().stream() : Stream.empty()) .collect(Collectors.toList());
We can do better and replace the above solution to be more functional using method references:
CollectionallPeopleCars = people .stream() .map(Person::getCars) .flatMap(mayHaveCars -> mayHaveCars.map(Collection::stream).orElse(Stream.empty())) .collect(Collectors.toList());
If you use IntelliJ IDEA as your favorite IDE, it has an inspection that helps replacing Optional.isPresent()
with a functional expression:
CollectionallPeopleCars = people .stream() .map(Person::getCars) .flatMap(mayHaveCars -> mayHaveCars.map(Collection::stream).orElseGet(Stream::empty)) .collect(Collectors.toList());
P.S. In Java 9, the stream()
method was added to the Optional
API, so we can rewrite the above stream pipeline into the following one:
CollectionallPeopleCars = people .stream() .map(Person::getCars) .flatMap(Optional::stream) .flatMap(Collection::stream) .collect(Collectors.toList());
In case you are interested, this post on the IntelliJ IDEA blog has some good tips when working with Java 8.
Kotlin is a statically typed language which is fully interoperable with Java.
Recently my friend Andre showed me Kotlin‘s nice syntax and I considered giving it a try.
In the meantime, my friend Leonnardo sent me this nice link which helps migrating from Java to Kotlin easily.
Let’s compare some syntax from Java and Kotlin and see the differences. Suppose we have some employees and we want to group them by their departments.
In Java we create an Employee
class, build some employees and use the Streams API to group them by their departments:
public class Employee { private final String name; private final String department; public Employee(final String name, final String department) { this.name = name; this.department = department; } public String getName() { return name; } public String getDepartment() { return department; } @Override public String toString() { return "Employee(name=" + name + ", department=" + department + ")"; } } final Employee mark = new Employee("Mark", "Accounting"); final Employee john = new Employee("John", "Management"); final Employee smith = new Employee("Smith", "Administrative"); final Employee paul = new Employee("Paul", "Accounting"); final Listemployees = Arrays.asList(mark, john, smith, paul); final Map > employeesByDepartment = employees .stream() .collect(Collectors.groupingBy(Employee::getDepartment));
In Kotlin we create a data class Employee
, build some employees and use the collection built-in groupBy
method to group them by their departments:
data class Employee(val name: String, val department: String) val mark = Employee("Mark", "Accounting") val john = Employee("John", "Management") val smith = Employee("Smith", "Administrative") val paul = Employee("Paul", "Accounting") val employees = listOf(mark, john, smith, paul) val employeesByDepartment = employees.groupBy { it.department }
As you can see, Kotlin has some syntactic sugar that makes it less verbose than Java.
If you haven’t considered trying Kotlin yet, I think it is worth giving it a try.
Interesting article about some bad programming practices, including topics like code organization, teamwork, testing and maintenance.
K Palindromes puzzle
Sep 3
Here we have the K Palindromes puzzle from Javalobby:
You probably already know what a palindrome is: a string to results in the same word, whether read left to right, or right to left. A K Palindrome is when a string can be tranformed into a palindrome by changing K characters at most. Regular palindromes have K=0.
Your challenge today is to write a method which takes a string and a value for k and returns true if it the string qualifies as a K palindrome.
Below is the code in Ruby. Our input string is omississimo
and it’s a 0 palindrome String
.
def isKPalindrome(s, k) chars = s.chars.to_a limit = chars.size - 1 count = chars[0...chars.size / 2].each_index.count {|i| !chars[i].eql?(chars[limit - i])} k == count ? true : false end puts(isKPalindrome("omississimo", 0)) #true
The output is true
. Do you have another solution? Drop your comments here!