A programming kata is an exercise which helps a programmer hone his skills through practice and repetition.
This article is part of the series Java Tutorial Through Katas.
The article assumes that the reader already has experience with Java 7, that he is familiar with the basic usage of JUnit tests with Hamcrest matchers and that he knows how to run them from his favorite IDE (ours is IntelliJ IDEA).
Tests that prove that the solution is correct are displayed below. Recommended way to solve this kata is to use test-driven development approach (write the implementation for the first test, confirm that it passes and move to the next). Once all of the tests pass, the kata can be considered solved.
Since many of the new features added to Java 8 were inspired by Scala and other functional programming languages, short comparison of Java 7 (or earlier), Java 8 and Scala solutions is provided at the end of the article.
One possible solution is provided below the tests. Try to solve the kata by yourself first.
Reverse Polish Notation
In reverse Polish notation the operators follow their operands; for instance, to add 3 and 4, one would write "3 4 +" rather than "3 + 4". If there are multiple operations, the operator is given immediately after its second operand; so the expression written "3 - 4 + 5" in conventional notation would be written "3 4 - 5 +" in RPN: 4 is first subtracted from 3, then 5 added to it. An advantage of RPN is that it obviates the need for parentheses that are required by infix. While "3 - 4 * 5" can also be written "3 - (4 * 5)", that means something quite different from "(3 - 4) * 5". In postfix, the former could be written "3 4 5 * -", which unambiguously means "3 (4 5 *) -" which reduces to "3 20 -"; the latter could be written "3 4 - 5 *" (or 5 3 4 - *, if keeping similar formatting), which unambiguously means "(3 4 -) 5 *".
More info can be found in the Wikipedia.
The goal of this kata is to create a program that performs calculations using reverse Polish notation.
Test code can be found in the GitHub ReversePolishNotationTest.java.
[ONE POSSIBLE SOLUTION]
Java 8 solution code can be found in the ReversePolishNotation.java.
Java 7 (old earlier) equivalent can be found in the ReversePolishNotationSeven.java.
Scala solution can be found in the Scala Tutorial Through Katas: Reverse Polish Notation (Medium) post.
First difference between Java 8 and 7 can be found in tests themselves. New IntStream class with range methods together with forEach provides a bit cleaner way to generate a range of numbers.
In the implementation code, we're using function as calc method argument. BiFunction represents a function that accepts two arguments and produces a result. Java 7 solution uses the enum Sign instead. Using function resulted in more open and cleaner code.
Method is declared as:
To call the method with multiply operation:
Java 7 solution used much more code to describe similar functionality using enum:
In this case Scala seems to be working in almost the same way as Java 8. The only difference is in few shortcuts that can be taken. For example, equivalent to Java 8 calcSign call is:
Another difference is Scala's preference for immutability that can be seen in the foldLeft method.
What was your solution? Post it as a comment so that we can compare different ways to solve this kata.
Test-Driven Java Development
Test-Driven Java Development book wrote by Alex Garcia and me has been published by Packt Publishing. It was a long, demanding, but very rewarding journey that resulted in a very comprehensive hands-on material for all Java developers interested in learning or improving their TDD skills.
If you liked this article I am sure that you'll find this book very useful. It contains extensive tutorials, guidelines and exercises for all Java developers eager to learn how to successfully apply TDD practices.