Writing your own custom Java stream collector

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: Combinations of collections for Java

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!

Refactoring large conditional method using method references

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!

3 Things Every Java Developer Should Stop Doing

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:

  1. Returning Null
  2. Defaulting to Functional Programming
  3. 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?

Using Scala to update LiveJournal tags – Part I

Some days ago I started to use the Scala programming language to update my Livejournal tags using its XML-RPC protocol reference. First I had to check if some tags of mine were entered wrong, so I’ve done this Scala program to list all of them:

   1:import org.apache.xmlrpc.client.XmlRpcClient;
   2:import org.apache.xmlrpc.client.XmlRpcClientConfigImpl;
   3:import org.apache.xmlrpc.client.XmlRpcCommonsTransportFactory;
   4:import java.net.URL;
   5:import java.util.Map
   6:import java.util.HashMap
   7:import scala.collection.immutable.TreeSet
   9:object LJListTag {
  10:     def main(args: Array[String]) {
  11:         val config = new XmlRpcClientConfigImpl()
  12:         config.setEnabledForExtensions(true);
  13:         config.setServerURL(new URL("http://www.livejournal.com/interface/xmlrpc"))
  14:         val client = new XmlRpcClient()
  15:         client.setConfig(config)
  16:         val params = new HashMap[String, String]
  17:         params.put("username", "user")
  18:         params.put("password", "password")
  19:         var paramsToServer = new Array[Object](1)
  20:         paramsToServer(0) = params
  21:         val results = client.execute("LJ.XMLRPC.getusertags", paramsToServer).asInstanceOf[Map[String, String]];
  22:         printEachTag(results)
  23:     }
  25:     def printEachTag(results: Map[String, String]) {
  26:        var allTags = new TreeSet[String]
  27:        val iterator = results.values().iterator()
  28:           while(iterator.hasNext()) {
  29:             val resultFromRPCData = iterator.next().asInstanceOf[Array[Any]]
  30:             resultFromRPCData.foreach(singleResult => allTags += extractTag(singleResult))
  31:           }
  32:        allTags.foreach(tag => println(tag))
  33:     }
  35:    def extractTag(singleResult: Any): String = {
  36:        val tag = singleResult.asInstanceOf[HashMap[String, String]]
  37:        return tag.get("name")
  38:    }

Just fill your user and password to have all of your LiveJournal tags printed on the standard output. The experience was so amazing, since you can use all the Java libraries (Scala is fully interoperable with Java and runs on top of the JVM). I used a TreeSet because I wanted print my tags sorted according its alphabetical order. I’m continuously studying Scala and its API, so the code above doesn’t use any advanced Scala constructs. If you have any suggestion about the code or how to use better the Scala constructs, post your comments here. It will be all appreciated.

The Fan programming language

Cedric has showed us an interesting programming language called Fan, which has a lot of useful features. The ones I liked most are:

  • Familiar Syntax: Java and C# programmers will feel at home with Fan’s curly brace syntax.
  • Concurrency: Tackle concurrency with built-in immutability, message passing, and REST oriented transactional memory.
  • Static and Dynamic Typing: Don’t like the extremes – take the middle of the road.
  • Object Oriented: Everything is an object.
  • Functional: Functions and closures are baked in.

Here are some code chunks, showing its closures syntax:

// find files less than one day old
files := dir.list.findAll |File f->Bool|
    return DateTime.now – f.modified < 1day

// print the filenames to stdout
files.each |File f|
    echo("$f.modified.toLocale: $f.name")

I haven’t tried the Fan language a lot yet (I’ll post my comments here when I do it), but I congratulate the Fan authors for being possible to run it on both the JVM and .Net. I agree with Cedric when he said about the possibility to declare constructors with arbitrary names (although they must be prefixed with the new keyword) and invoke it as static methods of the class. From designer of the class point of view, it’s easy to identify the constructor (it’s highlighted by the new keyword), but from the client it’s difficult because there’s no way to differentiate a constructor from a static method call. It’s a bit odd to be able to do that. Just take a look at the code:

// Using an arbitrary name as a constructor
class Person
    new create(Int age) { this.age = age; }
    Int age
p = Person.create(20)

Anyway, I think it’s a good work to make the language have both object-oriented and functional constructs and be portable to both the Java VM and the .NET CLR. Good work guys!