Switch expressions in Java 14

In this article we will be taking a look at switch expressions that have been incorporated in JDK 14 which was released on 17th March 2020.Switch expressions were made available as a preview language feature in JDK 12 and 13. Based on the feedback, changes were made and now this feature has been finalized in JDK 14.Let us start with a simple example of a switch block:

public int getNumberOfRooms(int budget) {
        int numberOfRooms = 0;
        switch (budget) {
            case 1000000:
                numberOfRooms = 1;
                break;
            case 2000000:
            case 3000000:
                numberOfRooms = 2;
                break;
            case 4000000:
            case 5000000:
                numberOfRooms = 3;
                break;
            default:
                System.out.println("Hello");
        }
        return numberOfRooms;
}
Vintage switch

The method above takes in a budget as parameter and depending on the budget it returns the number of rooms that one can buy with the budget. For simplicity, let us assume that we have a flat budget. 1 million can get us a single room. 2 and 3 million can get us 2 rooms and finally 4 and 5 million can get us 3 rooms.

Some observations about the usage of switch statement in the example above:

  1. Most usage of switch statements do some processing and return a value.
  2. Most case blocks have a break statement to avoid fall through otherwise it will execute the next case block till it encounters a break – it is quite easy to forget a break and well, adding a break serves the purpose but can make the code difficult to read at times. As experienced Java programmers, we are now used to it.
  3. The default case is optional and it does not enforce the programmer to throw an exception or return a value. I could add a System.out.println there and the code will compile and run.
  4. Multiple cases which require common logic to be processed have separate case labels on different lines with no break in between them which takes an effort to read and understand – Again we are used to it but imagine folks being introduced to the language for the first time.
The new modern switch
public int getNumberOfRooms(int budget) {

        int numberOfRooms = switch (budget) {
            case 1000000 -> 1;
            case 2000000, 3000000 -> 2;
            case 4000000, 5000000 -> 3;
            default -> throw new IllegalStateException("No rooms available for this budget");
        };
        return numberOfRooms;
}

  1. The new switch assigns/returns a value to a variable on the left side, hence called switch expression. Notice the semicolon on line 8 at the end of the switch block.
  2. Multiple cases are combined on the same line with a comma.
  3. The right hand side is separated with arrow (->) instead of a colon.
  4. No break in between cases, there is no fall through by default.
  5. The default case has to either return a value or throw an exception.
  6. Last but not the least and in fact an important difference is that this code is definitely more pleasing to the the eye and easier to understand.
Yield and scope in the modern switch

Let us introduce a small change in the business requirement. If we have a budget of 3 million or 5 million we need to give the customer a discount.Doing this using the vintage switch would lead to the following code:

public int getNumberOfRooms(int budget) {
        int numberOfRooms = 0;
        switch (budget) {
            case 1000000:
                numberOfRooms = 1;
                break;
            case 2000000:
            case 3000000:
                int finalPrice = (budget == 3000000) ? budget - 100000 : budget;
                System.out.println("Final price after discount " + finalPrice);
                numberOfRooms = 2;
                break;
            case 4000000:
            case 5000000:
                int finalPriceThreeRooms = (budget == 5000000) ? budget - 100000 : budget;
                System.out.println("Final price after discount " + finalPriceThreeRooms);
                numberOfRooms = 3;
                break;
            default:
                throw new IllegalStateException("No rooms available for this budget");
        }
        return numberOfRooms;
}

If you see line number 9 and line number 15 , we introduced 2 variables which does the same thing but we had to give it different names. This is because any variable introduced in case block stretches for the entire switch block.

Let us implement this using modern switch construct

public int getNumberOfRooms(int budget) {
        int numberOfRooms = switch (budget) {
            case 1000000 -> 1;
            case 2000000, 3000000 -> {
                int finalPrice = (budget == 3000000) ? budget - 100000 : budget);
                System.out.println("Final price after discount " + finalPrice);

                yield 2;
            }
            case 4000000, 5000000 -> {
                int finalPrice = (budget == 5000000) ? budget - 100000 : budget;
                System.out.println("Final price after discount " + finalPrice);

                yield 3;
            }
            default -> throw new IllegalStateException("Unexpected value: " + budget);
        };
        return numberOfRooms;
}

Using the modern switch, if a case block has multiple lines, we make use of a yield statement which indicates that the case block yields a value. Besides this, another salient feature is that the finalPrice variable introduced inside the case block remains local to that block which makes reading and understanding code easier. I have seen lots of code where variables are named using weird combinations like temp1, temp2, temp3 or finalPrice1,finalPrice2,finalPrice3 …This change does not enforce you to give meaningful names to variables but signals a clear intention about the scope of a variable in the case block.

More on the yield statement

The yield statement was introduced after seeking feedback. In JDK 12, break statement was used in switch expression which was confusing. It was hence decided to introduce the yield statement in switch expressions. I have been calling the switch in versions of JDK prior to 12 as vintage but they continue to exist along with the modern switch.

Some nuances with mixing and matching
  • We cannot use the arrow and the colon in the same switch block. We get a compile time error “Different case kinds used in switch”
public int getNumberOfRooms(int budget) {
int numberOfRooms = 0 ;
switch (budget) {
case 1000000 : numberOfRooms = 1;
case 2000000,3000000 -> {
  …
}
case 4000000, 5000000 -> { 
  …
}
default -> throw new IllegalStateException("Unexpected value: " + budget);
};
return numberOfRooms;
}
  • In case of the switch statement, we can use the new case label using the arrow. Doing this means there is no fall through and multiple cases can be combined using comma. You can add a break statement( no compiler error) but the arrow case label means there is no fall through
public int getNumberOfRooms(int budget) {
        int numberOfRooms;
        switch (budget) {
            case 1000000 -> {
                numberOfRooms = 1;
            }
            case 2000000, 3000000 -> {
                int finalPrice = (budget == 3000000) ? budget - 100000 : budget;
                System.out.println("Final price after discount " + finalPrice);
                numberOfRooms = 2;
                //redundant because of arrow.
                break;
            }
            case 4000000, 5000000 -> {
                int finalPrice = (budget == 5000000) ? budget - 100000 : budget;
                System.out.println("Final price after discount " + finalPrice);
                numberOfRooms = 3;
            }
            default -> throw new IllegalStateException("Unexpected value: " + budget);
        }
        return numberOfRooms;
    }
  • In case of a switch expression, we can use the old vintage style of using a colon for the case blocks. But since this is an expression, each case block must return a value using yield.
public int getNumberOfRooms(int budget) {
        int numberOfRooms = switch (budget) {
            case 1000000: {
                yield 1;
            }
            case 2000000, 3000000: {
                int finalPrice = (budget == 3000000) ? budget - 100000 : budget;
                System.out.println("Final price after discount " + finalPrice);
                yield 2;
            }
            case 4000000, 5000000: {
                int finalPrice = (budget == 5000000) ? budget - 100000 : budget;
                System.out.println("Final price after discount " + finalPrice);
                yield 3;
            }
            default:
                throw new IllegalStateException("Unexpected value: " + budget);
        };
        return numberOfRooms;
    }

Conclusion

The new switch expression feature will make our code more readable, intuitive and less error prone. This feature acts as a foundation for more changes to come in the Java language, one of them is pattern matching.

References

https://openjdk.java.net/jeps/361

Java 8 default methods – Basic introduction

Let us assume that you have designed, published a library and you have many clients who use your library. You have followed the “Object Oriented” concepts and hence made use of interfaces, abstract classes, util classes to design your library.

After a few years, you realize that the core library is quite old, they need to move ahead with time and hence you would like to add new features to this library. At the same time you do not want your existing clients knocking at your door at 2:00 am in the morning to complain about a new piece of functionality you added which broke their existing code.

What are the possible solutions to this?

  1. Have a new interface define these methods, introduce an abstract class  to implement the interface and provide some skeletal behavior for the new functionality. This is actually a design technique that has been used in the Collection framework – The problem here is that we have abstract classes which mean that the existing client cannot extend from more than 1 class. 
  2. Classes with static methods – The problem here is that the clients cannot override the functionality if they would like to. This means clients will have to use the single implementation which does not really give them flexibility.

So how do we achieve all of the following?

  1. Add new functionality to an old library.
  2. Not break existing client code.
  3. Allow clients to inherit behavior and not state
  4. Allow clients to override behavior if needed

The answer to this is the default methods. A default method can be directly added to an interface with an implementation. Yes, you read that right! Interfaces with methods and not just the declaration but definition as well.

public interface ExistingInterface {
public void connect();
public void disconnect();
//Default method.
public default void connectUsingNewProtocol(){
System.out.println("Connection to a new device");
}
}

Some examples in the Java library which use the the default method:

1) stream method in the Collection interface – Enables any collection to be streamed.

    default Stream<E> stream() {
        return ...;
    }

2) reversed method in the Comparator interface – Enables reversing of the comparator

    default Comparator<T> reversed() {
        return Collections.reverseOrder(this);
    }

3) forEach and spliterator in the Iterable interface

One purpose of the default methods was to make changes to the Collection framework without breaking other libraries that use Collection API, like the Apache CollectionUtils or Hibernate and at the same time provide us with new functionality.

We all know that an interface can extend from another interface in Java.  By adding default methods, things get a little complicated and hence there are some things to remember when using default methods:

In the code below, Parent interface has default methods, Child extends from Parent but does not provide implementation.

interface Parent {
default public void methodOne() {
System.out.println("Method one…");
}
default public void methodTwo() {
System.out.println("Method two…");
}
}
interface Child extends Parent{
}
public class ConcreteClass implements Child {
public static void main(String[] args)
{
ConcreteClass concreteClass = new ConcreteClass();
concreteClass.methodOne();
concreteClass.methodTwo();
}
}
}

Output:

Method one…

Method two…

Conclusion : Default methods are inherited in the Child interface.

In the next example below :

Parent interface has default method, Child extends from Parent and does provide or override implementation.

interface Parent
{
default public void methodOne() {
System.out.println("Parent : Method one…");
}
default public void methodTwo() {
System.out.println("Parent : Method two…");
}
}
interface Child extends Parent
{
//overrides methodTwo
default public void methodTwo(){
System.out.println("Child : Method two…");
}
}
public class ConcreteClass implements Child
{
public static void main(String[] args)
{
ConcreteClass concreteClass = new ConcreteClass ();
concreteClass.methodOne();
concreteClass.methodTwo();
}
}

Output:

Parent: Method one…

Child: Method two…

Conclusion:The most specific/ the one at the bottom in the interface hierarchy wins!

What if the ConcreteClass class also provided the implementation for the methodTwo() above ?

public class ConcreteClass implements Child {
public void methodTwo(){
System.out.println("ConcreteClass : Method two…");
}
public static void main(String[] args) {
ConcreteClass concreteClass = new ConcreteClass ();
concreteClass.methodOne();
concreteClass.methodTwo();
}
}

Output:

Parent: Method one…

ConcreteClass: Method two…

Conclusion : Class wins over interface hierarchy!

What happens when we have same default methods in 2 “unrelated” interface and 1 concrete class implementing the 2 interfaces

interface One {
default public void callMe(){
System.out.println("One:callMe…");
}
}
interface Two
{
default public void callMe()
{
System.out.println("Two:callMe…");
}
}
public class ConcreteClass implements One, Two
{
public static void main(String[] args)
{
}
}

Output: The java compiler complains that the method callMe is being inherited from types One and Two. Well, it is our responsibility to resolve the same. This can be done in the following way:

public class ConcreteClass implements One, Two
{
@Override
public void callMe()
{
One.super.callMe();
}
public static void main(String[] args)
{
ConcreteClass concreteClass = new ConcreteClass();
concreteClass.callMe();
}
}

Depending on the implementation of the default method, we can either call the version One or the Two. This is done by using the super keyword. Without using the super keyword, it would mean we are calling the static method on the interface which is not the case here.  At the byte code level , this translates to a invokespecial instruction.

To summarize

  1. Interface hierarchy – the most specific wins
  2. Classes always win in case there is a class that implements a default method and there is an interface hierarchy.
  3. If there is still a problem, it is the responsibility of the developer to resolve it as shown above.

So, does this mean that we do not need abstract classes anymore? Well, that is not right.  What clearly distinguishes the two is state and the fact that a class can inherit only 1 class

So interfaces are always a better idea unless we need state or a skeletal implementation.

Understanding JavaScript hoisting in function declaration and function expression

In my previous blog, I introduced you to one of the main differences between function declaration and function expression in JavaScript. This was called hoisting and we saw that function declaration gets hoisted but function expression does not. This concept of hoisting can be understood as something getting pulled right on top in it’s respective scope. This understanding is good enough at a conceptual level but there is a lot more going on behind the scenes.

Before we embark on the details, an important concept to understand is the execution context of a variable or a function in JavaScript. When a variable is declared inside a function, the execution context for that variable is the function in which it is declared. If it is declared outside, the the execution context is the global context. This is true for functions as well.

The execution context can be either the global code, code inside a function or any eval code. A call to a function results in the formation of a new execution (functional) context.

var taxRatePercentage = 10;       //global context

function calculateTax(amount){    //new execution context - functional context
    var totalTax;

    function deductInsuranceAmount(){   //new execution context when it is called - functional context
        var insuranceAmount;

    }
}

One of the important things to understand here is that the function deductInsuranceAmount can access the totalTax variable but the calculateTax function cannot access the insuranceAmount variable.

There has to be a mechanism through which the JavaScript engine keeps track of the variables, their values and functions in a particular execution context. This is done by maintaining a lexical environment.

So a couple of things are in play here with respect to a execution context:

  1. The lexical environment
  2. The scope chain – The reason why the deductInsuranceAmount function is able to access the totalTax variable defined in the outer/parent function.

Note – To keep it simple and make it easier to comprehend the lexical environment, I am going to leave out the discussion about scope chain in this blog. However the outer reference mentioned in the tables below will give you and idea about the same.

When a function is called, it is this lexical environment that maintains the parameters passed to the function , the variables declared inside the function and the function declarations for a particular execution context.

For the code below :

var taxRatePercentage = 10;       //global context

function calculateTax(amount){    //new execution context
    var totalTax = 0;
    ....
    }
}
calculateTax(20000);

The lexical environment would look like this:

amount20000
totalTax0
outerglobalEnvironment
Simplified Lexical environment for calculateTax function

And the global environment like this:

taxPercentage10
outernull
Simplified environment for the code snippet above.

Internally, the lexical environment actually is split into 2 parts :

  1. The environment record which contains the totalTax, amount declarations as shown above.
  2. The outer link

Two phases of the execution context-

Now with this brief understanding of the lexical environment, let us turn our attention to the execution context. To reiterate, when a function is called, an execution context is created. However there are 2 phases involved with respect to the execution context. The 2 phases are :

  1. When the function is called
  2. When the function is actually executed.

These 2 phases affect the lexical environment. Let us see how.

function calculateTax(amount){    //new execution context
    var totalTax = 0;
    ....
    }
}
calculateTax(20000);

When the calculateTax is called, step 1 above, the execution context is created. Note that our function is not yet being executed. The JavaScript engine creates a lexical environment for this execution context and does the following:

amount20000
totalTaxundefined
outerglobalEnvironment
Simplified Lexical environment during creation phase of the execution context- when function is called but not executed

The parameters passed to the function are initialized with appropriate values but the totalTax variable declared inside remains ‘undefined’ during the creation phase. During phase 2(execution phase), the code is being executed and the environment record is read by the JavaScript engine and then modified as an when necessary.

amount20000
totalTax0
outerglobalEnvironment
Lexical environment when code/function is actually executed.

If we had a function expression inside this function :

function calculateTax(amount){    //new execution context - functional context
    var totalTax = 0;
    calculateInsuranceAmount();
    var calculateInsuranceAmount = function deductInsuranceAmount(){
        ...
    }
}
calculateTax(20000);

The corresponding lexical environment when the function calculateTax is called, during the creation phase would like this :

amount20000
totalTax undefined
calculateInsuranceAmount undefined
outerglobalEnvironment
Lexical environment when function is called but not yet executed.

The code above will result in a error, it will complain that calculateInsuranceAmount is not a function. This is because the function expression is not hoisted, the variable which refers to the function is initialized to undefined during the creation phase of the execution context. During the execution phase, this environment record in the lexical context will be referred to and the error will be thrown.

But if we have a function declaration and the call like this :

sayHello();

function sayHello(){
  console.log('hello');
}

When the sayHello is called, remember the 2 phases. During phase 1, the lexical environment is created but it contains a reference to the actual function in memory in case of function declaration.

sayHelloReference to function sayHello in memory
outerglobalEnvironment
Lexical environment during creation phase when sayHello is called but not executed.

When the code is actually executed, sayHello is present in this lexical environment and it points to the actual function in memory.

If we were to contrast this with function expression :

sayHello();

var sayHello = function(){
  console.log('hello');
}
//Throws 
"error"
"TypeError: sayHello is not a function

This is because, during the creation phase, the lexical environment will look like this:

sayHelloundefined
outerglobalEnvironment
Function expression in lexical environment when the function is called but not executed

This behavior is due the fact that the function expression will be initialized at code execution stage.

This is what happens in case of variables (var) too :

function printToConsole(){
  console.log(x);
  var x = 20;
}

printToConsole();

This results in undefined because during creation phase the variable x has undefined value and during the execution phase, we try to access the value on line 1 above.The lexical environment is looked up and it prints undefined.

So in step 1 : (During context creation phase, the variable is created )

xundefined
outerglobalEnvironment
x in the environment record is undefined during creation phase. The outer environment is the global environment itself.

Step 2 : The code starts executing, tries to access x by referring to the lexical environment and finds it as undefined above.

If we had it like this :

function printToConsole(){
  var x = 20;
  console.log(x);
}

printToConsole();

In Step 1: (During context creation phase, the variable is created )

xundefined
outerglobalEnvironment
Creation phase – The lexical environment for the printToConsole function above.

When the code starts executing , the interpreter executes var x = 20, it looks up at the lexical environment, sees an x there and modifies the value of x to look like the following :

x20
outer globalEnvironment
During execution phase, the variable x is found in the lexical environment and it modifies it to set appropriate value.

Now when the code comes to line 3, it can clearly see the value of 20 assigned to the variable x. This is hoisting from a behind the scenes perspective. This is what happens in case of function declaration, function expression.

Confusion between Lexical and Variable Environment

The specification uses both lexical and variable environment when it addresses the execution context. I have referred to the lexical environment in my explanations above. You can refer to the specification here to get a better understanding of the same. I would also urge you to read an excellent article by Dmitry Soshnikov to get a deeper understanding of the same.

My understanding is that the Lexical Environment was introduced for let,const declarations and for with,catch statements which creates block scope. Another link which explain the difference between the two.

Conclusion

Every function executes in a new execution context. An execution context among other things has a lexical environment which tracks the variables, the values of those variables and the functions. An execution context has 2 phases, creation phase and the execution phase. The lexical environment is created during the creation phase and then modified during execution phase. This gives us a feeling of hoisting of variables and functions declarations.

Further Reading

If you want to take your JavaScript skills to the next level, Toptal has a set of Q&A here to help you get started.

Function declaration vs Function expression in JavaScript

In my previous blog, I introduced you to the basics of function declaration and function expression in JavaScript. In this article, we will answer the following questions:

  1. Why do we need a function expression ?
  2. What is the difference between the two ?

Why do we need a function expression when we have function declaration ?

One of the areas where this can be extremely useful is when you want to pass a function as a parameter to another function and return a function from another function. Let us consider the code below :

function callbackRef(callback) {
  callback();
}


callbackRef(function printHello(){
  console.log('Hello');
});

callbackRef(function printHowdy(){
  console.log('Howdy');
});

The output of the above is Hello Howdy. To break this down, Lines 6 and 10 call the function callbackRef and pass the entire function as a parameter to the function callbackRef. This is accepted by the parameter callback and then we finally execute the function by : callback(). This is the same as function expression where we say :

var callback = function (){

}
callback();

Using function references in the way mentioned above, we can compose and add dynamic behavior. Another use of the function expression is used to create powerful design pattern called the Module Design Pattern which I will explain in another blog.

What is the difference between a function declaration and function expression ?

In JavaScript we can do the following :

printToConsole();

function printToConsole(){
  console.log('hello');
}

To our suprise, the program runs fine and it prints hello even if the function is called before it has been declared. The reason behind this is a concept called hoisting. The English meaning of the word hoisting is something that is raised. Applying this to the function declaration, function declaration is hoisted. What does this mean ?

Mental Model:

//Imagine the function above to be picked up like this :
function printToConsole(){
  console.log('hello');
}
printToConsole();


A simple mental model to understand this is to imagine the function declaration to be hoisted(picked up) in it’s corresponding scope. Now with this understanding, I hope it is clear why the function runs successfully.

Now consider the same example using function expression :

pToC();

var pToC = function printToConsole(){
  console.log('hello');
}

I have used function expression here instead of function declaration. What do you think happens here ? Does it run successfully ?

Well, it does not. It doesn’t run but we also get the following error :

“error”

“ReferenceError: pToC is not defined

In case of function expression , there is no hoisting. As the function expression in not raised up, pToC() throws an error.

Conclusion

The main difference between function declaration and function expression in JavaScript is called hoisting. This difference is more at a conceptual level.

I will dig deeper into this concept of hoisting in my next blog.

Function declaration and Function expression in JavaScript

If you are a backend developer who has never tried JavaScript before, learning JavaScript can be an exhilarating experience but at the same time it can give you a feeling of going  down a rabbit hole. I am going to write a few articles to save a fellow backend developer both time and frustration.

There is a certain vocabulary involved which you should be aware of when you start learning JavaScript.If you are a backend developer wanting to get your hands into JavaScript, there is a good chance that you will get to see a lot of code before you actually starting coding. During this process of learning you will see functions being written in different ways and sometimes this can be a point of confusion.

This article will introduce you to a couple of ways of writing functions in JavaScript.

First way to write a function is:

function calulateTax(amount){
 ...
 return amount * 10;
}

This is called a function declaration. If you are a Java developer, you wouldn’t be too surprised. Keyword function followed by the name of the function, parenthesis to pass any parameters and finally the function body. We need not mention the type of the parameter passed to the function or the type of return value.This function will be executed when you call this function as shown below:

calculateTax(2000);

Second way to write a function is:

var taxCalculation = function(){
   return 20000;
}

This is called a function expression. There is no name(anonymous) given to the function above, it is being referred to by the taxCalculation variable. You could add a name to the function if you wanted.

var calculateTax = function taxCalculator(){
  return 20000;
}

The name of the function, taxCalculator may be useful in stacktraces and inside the function (to call it recursively). To call this function, we need to use the name of the variable :

var taxableAmount = calculateTax();




Third way to write a function :

var calculateTax  = () => return 2000;
var taxableAmount = calculateTax();

or simply

var calculateTax  = () => 2000;  // implicit return as it is single statement
var taxableAmount = calculateTax();

If you are a Java or a .Net developer, this third type should be easy to grasp, this is an arrow function expression in JavaScript.

Conclusion

At a broad level, there are 2 ways of declaring functions in JavaScript : function declaration and function expression. I want to keep this article short and not get into the differences between them.

I will get into the differences between the two in my next blog.

Java 8 : Imperative vs Declarative style of coding

The focus of this article is to compare the imperative style of solving a problem vs declarative style using a couple of examples.It assumes basic knowledge about Lambdas and Streams introduced in Java 8.

Example 1:   I do not wish to give you the problem statement on purpose. Look at the code below and try to figure out the intention of the code.


List<Player> validPlayers = new ArrayList<>();
FootballLeague premierLeague = null;
for(FootballLeague league:leagues)
{
if(league.getLeagueName() == LeagueName.PREMIER_LEAGUE )
{
premierLeague = league;
break;
}
}
if(null != premierLeague)
{
List<Player> players = premierLeague.getPlayers();
for(Player player: players)
{
if(player.getAge() <= 25)
{
validPlayers.add(player);
}
}
}
Collections.sort(validPlayers, new Comparator<Player>() {
@Override
public int compare(Player p1, Player p2 ) {
return p1.getName().compareTo(p2.getName());
}
});
StringBuilder builder = new StringBuilder();
for(Player player : validPlayers)
{
builder.append( player.getName()+ ",");
}
return builder.substring(0,builder.length()-1);

I am sure you read that code very carefully and possibly a couple of times. What does it do? You might read it again ! Most developers have a short memory. You know that you might have to revisit this code at some point and hence you will probably add comments in the code above like sort by name , remove last comma etc.

From a list of football leagues, the code checks if the league is the English Premier league, selects all the players who play for the English premier league where their age is <= 25 years. It then sorts them by their names and then finally returns a comma separated list of their names.

So our problem statement:  Given a list of football leagues, select all the players who play for the English Premier League and are <=25 years of age. Then sort their names and return them as comma separated.  Let us break this problem statement about what we want to do:

  1. Select all the players who play in the Premier league
  2. Remove all the players who are above 25 years of age
  3. Sort the names of the players
  4. Get their name and make them comma separated

Let us code this now using declarative style.

Declarative style:


return leagues.stream()
.filter(league -> league.getLeagueName() == LeagueName.PREMIER_LEAGUE)
.flatMap(league ->league.getPlayers().stream())
.filter(player -> player.getAge() <=25)
.sorted(Comparator.comparing(Player::getName))
.map(player ->player.getName())
.collect(Collectors.joining(","));

Look at the code above and the problem statements from 1-4. Don’t you think that the code above reads more like the problem statement? Not only does it read like the problem statement, the code does not have any garbage variables, no for loops instructing how we want to iterate and select. We are focusing more on what we want rather how we want to do it. Hence it is also easier to make any changes to the code in case the requirements change which means the maintenance is easy.  

We could have used a .sorted(Comparator.naturalOrder()) above and done the mapping to get the name first before sorting.


return leagues.stream()
.filter(league -> league.getLeagueName() == LeagueName.PREMIER_LEAGUE)
.flatMap(league ->league.getPlayers().stream())
.filter(player -> player.getAge() <=25)
.map(player ->player.getName())
.sorted(Comparator.naturalOrder())
.collect(Collectors.joining(","));

Example 2:  Given a list of strings,we need to output the strings based on their length. If the input string is “I”, ”ate”, ”food”, ”slept”. The output should be

1 – I

3-ate

4-food,slept

Imperative style:


Map<Integer, List<String>> lengthMap = new HashMap<>();
for(String string : strings)
{
List<String> sameLength = null;
Integer length = string.length();
if(lengthMap.get(length) == null)
{
sameLength = new ArrayList<>();
sameLength.add(string);
lengthMap.put(length, sameLength);
}else
{
List<String> sameLengthString = lengthMap.get(length);
sameLengthString.add(string);
}
}
return lengthMap;

Hmm, one thing is clear that we need a Hashmap. The key will be the length of string and the value will be the actual string. So what are we doing here

  1. Create a new hashmap
  2. Iterate through the list of strings
  3. Create  a new list
  4. If the current string has length x and x is already in the map then get the list corresponding to the length and add the current string to that list, else
  5. Create a new list and add the length of string and the string length as key , value as actual string.
  6. Done !

In short, we are grouping strings by their length.

Declarative style:


return strings.stream()
.collect(Collectors.groupingBy(String::length)));

What are we doing here:

  1. Group all the strings by length
  2. Done !

Again, the code is expressive and it translates to the problem statement very clearly !

The Collectors.groupingBy method returns a Map of Integer, List<String> or K, V where

K- the type that we are grouping by

V – The elements that we are operating on ( in this case, String)

Note that we have not considered the case where strings can repeat. This can be solved easily by using a Set instead of a List which would be pretty easy in both imperative and declarative style.

Declarative style does make your code more readable and concise.Declarative code might not be the magical solution to all problems, if you find the declarative style getting too complicated, stick to the old imperative style of programming.

Sorting a list in Java with null values

I am going to tell you a story with 2 characters, the developer and the quality analyst(QA). The developer is working on  a very simple application which deals with teenagers and the brand of cell phone they use.

I think the relation between developers and QA is like a one night stand, well, not the typical one! One fine day the QA finds bugs and thanks to your manager (who leaves home early), the developer and the QA are made to stay back and work all night until the bug is fixed and the code is completely bug free.(Yeah, right !)

Our developer friend has written a Teenager class which has an age field and a phoneBrand field.


public class Teenager {
private int age;
private String phoneBrand;
//getters,setters
}

view raw

Teenager.java

hosted with ❤ by GitHub

Manager: We have a new requirement,there is a need for a survey and hence the application needs to return the list of teenagers by increasing age. If two teenagers have the same age, then we need to return the list considering the brand of the cell phones in alphabetical order.

Developer: This will take time. I need to make sure that I write the code using Object Oriented Principles.

Manager: Alright, I give you a days time.( You know he does not understand Object oriented principles !)

You bring all your Object oriented skills to the table, create a separate class for the comparator as the sorting is done using 2 different fields, the age field and then the phoneBrand field. The comparator class looks like this:


public class TeenageSorter implements Comparator<Teenager>{
@Override
public int compare(Teenager t1, Teenager t2)
{
if( t1.getAge() == t2.getAge())
{
return (t1.getPhoneBrand().compareTo(t2.getPhoneBrand()));
}
return t1.getAge() > t2.getAge()? 1 : –1;
}
}

The input to your sort function is a List of Teenagers. You call the sort method like this:

Collections.sort(teens, new TeenageSorter());

Everything works fine.Given an input like this:


List<Teenager> teens = new ArrayList<>();
teens.add(new Teenager(15,"Apple"));
teens.add(new Teenager(16,"Samsung"));
teens.add(new Teenager(14,"Xiaomi"));
teens.add(new Teenager(16,"Apple"));

Output:

[Age:14 |Phone:Xiaomi, Age:15 |Phone:Apple, Age:16 |Phone:Apple, Age:16 |Phone:Samsung]

Sorted by increasing age and as there are 2 teenagers aged 16, the one with the Apple phone is followed by Samsung using alphabetical order. You check in the code and inform your manager that you are done with your task.

A few hours later, at around 6 pm when you are just about to leave, the QA guy comes to your desk.

QA : Your code is not working .

Developer : That is not possible ![Unpleasant stare]

QA : I am not sure, I added a teenager but did not give him a phone !

You think about it for a second, your coding skills (spelt  “ego”) are at stake, you have to come up with a reply.You know you left that part in the code but…

Developer: How can a teenager not have a phone ! [ You know in your heart that you never had a cell phone as a teenager]

QA : Well, yes, all teenagers do but currently our system allows me to do that, I followed the steps, kept the brand name of the phone empty, it crashed !

Well, you take a deep breath.You know you assumed that the data will never be null. You got what you deserved , a null pointer exception !

You go to your manager and tell him that it is possible that a teenager might not have a phone, so the requirement has to be discussed now. You involve the business analyst as well and explain the situation. The analyst says, well, if a teenager does not have a cell phone and two teenagers have the same age, we need to put them at the end of the list.

You have been asked to fix this in the next few hours.You start thinking about this problem. If the teenager does not have a phone, it means the phoneBrand field is null. Hence the sorting has to now deal with nulls.You look at your Comparator and this is what you come up with:


public class TeenageSorter implements Comparator<Teenager>{
@Override
public int compare(Teenager t1, Teenager t2) {
if( t1.getAge() == t2.getAge()){
return sortByPhoneBrand(t1.getPhoneBrand(),t2.getPhoneBrand());
}
return t1.getAge() > t2.getAge()? 1 : –1;
}
private int sortByPhoneBrand(String phoneBrand1,String phoneBrand2){
if(phoneBrand1 == null && phoneBrand2 == null){
return 0;
}
if(phoneBrand1 == null && phoneBrand2 != null){
return 1;
}
if(phoneBrand1 != null && phoneBrand2 == null){
return1;
}
return phoneBrand1.compareTo(phoneBrand2);
}
}

A shiny new method to sort the phoneBrand. This time when you test your code, you supply the following input:


List<Teenager> teens = new ArrayList<>();
teens.add(new Teenager(15,"Apple"));
teens.add(new Teenager(16,"Samsung"));
teens.add(new Teenager(14,"Xiaomi"));
teens.add(new Teenager(14,"Samsung"));
teens.add(new Teenager(16,"Apple"));
teens.add(new Teenager(16,null));

Output:

[Age:14 |Phone:Samsung, Age:14 |Phone:Xiaomi, Age:15 |Phone:Apple, Age:16 |Phone:Apple, Age:16 |Phone:Samsung, Age:16 |Phone:null]

The list above is sorted by increasing age. When the age is the same,16, the teenager without the phone gets pushed to the end of the list as if the teenager is not wanted. You check in the code and leave for the day (night?)  and you are still feeling bad that the teenager does not have a phone.

The next morning, the QA does his testing, things are working fine!

QA : Everything is fine now.

Developer : Yes, I know !  [Arrogance is the key, isn’t it ! ]

Is there a chance to refactor your code ? You look at your code and ask yourself if you can refactor that code somehow. The comparator methods do not really look that clean. It is kind of buggy. It is not that clear when nulls starting popping up, should you return a 1 or a -1 ? It is more like trial and error at times. Imagine what happens if you are asked to sort by another field in addition to the 2 fields above? What if we add another field, earphoneBrand. If two teens are aged the same, have the same phone then sort by the brand of the ear phones. What if someone does not have earphones ?

You remember reading about Lambdas in Java 8 and start exploring if they made any changes to the Comparator interface. On further reading, you actually discover a lot and come up with the following analysis:

  1. Comparator present in the java.util.package is a functional interface and hence..
  2. Usage of the anonymous inner class can be replaced with usage of Lambdas.
  3. There are default methods in the Comparator interface now which can also sort objects if they are null.

So let us revisit the problem statement:

Given a list of Teenagers:

a) sort the list by age first

b) if age is the same then sort by phone brand name and

c) if the teenager does not have a phone(null), then it should be kept at the end for that particular age.

Declarative style:


Collections.sort(teens,
Comparator.comparing(Teenager::getAge)
.thenComparing(Teenager::getPhoneBrand,Comparator.nullsLast(Comparator.naturalOrder())));

What ? What is that ? Let us break that down a little bit, following a, b and c above.


Comparator<Teenager> phoneBrandPossibleNulls =
Comparator.comparing(Teenager::getPhoneBrand,Comparator.nullsLast(Comparator.naturalOrder()));
Collections.sort(teens, Comparator.comparing(Teenager::getAge)
.thenComparing(phoneBrandPossibleNulls));

The code on lines 1 and 2 creates a comparator to sort by the phone brand and instructs how to deal with null values. Line 4 combines the two, if the age is the same then compare with the phone brand. The part, Comparator.nullsLast(Comparator.naturalOrder()) means that when we get 2 phoneBrand objects, we can have various combinations. Both null, one of them null and none of them null. The code says, use natural order for sorting phoneBrand fields and if you encounter a null, then put them at the end of the list.

I must admit the code does need a little bit of explanation this time, but it is still expressive enough and probably takes getting used to the function composition part. But the code flows well, any kind of changes to it are quite easy rather than the imperative style. The focus is more on what you want. If you get a new requirement of putting the teenager without a phone at the beginning of the list, all we need to do is modify the code to use Comparator.nullsFirst above. If we need to sort by another field, add another thenComparing().

You are so enthusiastic about Java 8 but then it dawns upon you that your manager has not yet approved that you switch to Java 8 and you are still coding with an old version. Well, send him an email and tell him that you feel like this:

outdated1

 

Well, if you are still stuck with prior versions of Java , there are other libraries to do that. One solution is to use the Google Guava libraries. The Google Guava library has something similar to the Java 8 style of composing functions.It uses chaining of comparators like above.


Collections.sort(teens,new Comparator<Teenager>() {
@Override
public int compare(Teenager t1, Teenager t2)
{
return
ComparisonChain.start()
.compare(t1.getAge(), t2.getAge())
.compare(t1.getPhoneBrand(), t2.getPhoneBrand(),Ordering.natural().nullsLast())
.result();
}
});

This chaining is not very different from the Java 8 style, in fact a few things in the Google Guava library have served as an inspiration to the designers of the JDK library. So if you cannot switch to Java 8 yet, you could use the google guava version, it is much cleaner that writing a comparator of your own with all null checks and other checks.

It has been a couple of days since you checked in the code, things seem quiet, the QA, Business Analyst and the Manager, nobody has turned up at your desk. It means everything is working fine !

Not a JavaScript problem : 0.1 + 0.2 is not equal to 0.3

I have been a back-end developer for some time now but I have decided to learn some front end (JavaScript) stuff too! I know, you must be thinking , it’s 2017, why on earth have I  decided to learn vanilla JavaScript ! May be I should be learning frameworks like ReactJS, Angular, Vue. Sure, why not, that is the idea but I would like to get the basics (JavaScript) right first.

I have been learning the basics of JavaScript and it turns out that quite a number of people mention a few WTF’s with JavaScript . One of them being:  0.1 + 0.2  !== 0.3.  If you are in a state of shock now, well , you should be there for a few more seconds….

Time to come out now ! Well, this is not a problem with JavaScript . Don’t believe me ?

Let us try the same thing in a different language:

Java:


public class FloatingPoint {
public static void main(String[] args) {
System.out.println(0.1 + 0.2);
}
}

view raw

Snippet.java

hosted with ❤ by GitHub

Output 

0.30000000000000004

So obviously this is not equal to 0.3

Right way to do it : Using BigDecimal


import java.math.BigDecimal;
public class FloatingPointCorrected {
public static void main(String[] args) {
System.out.println(new BigDecimal("0.1").add(new BigDecimal("0.2")));
}
}

If you tried the same in Python, you will still get the same unexpected result.

Right way to do it in JavaScript : Using toFixed function


+(0.1 + 0.2).toFixed(1);

Using the toFixed function from Number object helps us in setting the number of digits after the decimal point.It returns a string and hence we need the + operator at the beginning.

So let us not give JavaScript, the language, criminal status for an offense it never committed !

But why is 0.1 + 0.2 ! = 0.3, take a look here : Floating point Math

Conclusion

Let us not find incorrect reasons to criticize the language. Learning JavaScript so far has been a fun learning experience. Of course there have been some WTF moments as well.

JavaScript is powerful ! I urge you to learn it.

Introduction to JShell : The Java Shell

In this article we will be taking a look at the new tool, JShell, which is a part of the Java 9 release.

What is JShell ?

It is an interactive tool or shell also referred to as REPL ( Read- Evaluate-Print loop) that is packaged as part of  Java 9 release. REPL is basically Reading input or data typed by the user, Evaluating the input , Printing the result that was evaluated and then going back to read the next input(Looping).

Why JShell ?

It is a very handy tool for developers both old and new wanting to explore the Java language by trying or experimenting snippets of code.

First time Java developers who wish to get started with the Java language can use JShell to write small pieces of code and later on move to IDE’s like Eclipse, STS, IntelliJ to set up full fledged projects.

For the experienced Java developer who wants to explore a new API or try out short  examples, the JShell can be quite useful. Let us say you are in the midst of fixing a bug or implementing a new functionality in an existing class using an API you have not tried before. Typical way to do this would be to create a new class with a main method in your code repository, type in the sample code for the API, right-click and run. Finally, we would copy the code and paste it somewhere in the existing code. As we age, we tend to forget a few things like deleting the sample file with the main method or sometimes we might even create a main method in an existing class where the new code is needed. While checking in, we might just check in the file with the main method only for your lead to do a code review which will obviously be rejected. This is assuming your lead does a proper code review !

Starting JShell

Open a command prompt, go to your  <Jdk 9  Installation>/bin directory and type jshell. You can also add it to your environment variables so that it can be started from any directory on the command prompt.

Some of the things we can do with JShell

  • Additionaddition

You don’t need JShell to check that 2+3=5. However make note of the variable created above , $1. This is a temporary variable. But, did you realize that we did not write a class with a main method with a System.out.println to print the result of 2+3 ?

  • Exploring Lambdas, the shiny new feature – Wait a minute, these are more like shiny old features introduced in Java 8!Consumer_Lambda

Did you notice the nice lambda created above ?

  • Can’t remember the method in the Consumer interface?Consumer_Lambda_Tab

Type in the name of the variable(s) created above , followed by a dot and press tab ! You get a bunch of methods that can be called on the Consumer interface. For the Consumer interface, it is the accept method that we are interested in.

  • Let’s try something with Streamsstreams

The moment you create a Stream which is referenced by the strings variable above, notice the type of strings. It is a ReferencePipeLine, JShell returns the type of the variable too!

  • Create a class, declare methods and variablesclass

Notice that after typing class Test { and pressing enter, JShell is intelligent enough to figure out that you are not yet done with the current statement and hence it waits for the next line of code.

  • Listing out variables declared so farvars

Get a list of all the variables using the /var command. To get a list of all the methods, use the /methods command.

  • Listing all the code typed in so farlist

Use the /list command. We performed an addition, created a Lambda , a Stream , created a class, then an object and called the getValue method. The /list command, simply lists them.

  • Typed in some code, time for a tea break, worried about machine crash ?save

You can save your code snippets using the /save command. Make sure you have the right permissions to save/create a file. You can follow that up with a /open command which will simply execute the code in the file.

  • Made a mistake, want to edit something ?editTyping the /edit command as shown above opens up a window where you can go and edit the code you typed. Using our knowledge of method reference, we can change the lambda expression from (String s) -> System.out.println(s) to System.out::println. On clicking the accept button, the change is reflected.

editpost_edit

Notice that the /vars command now lists the updated reference to the Lambda expression.

  • Create a package

Come on , JShell is not for that. The entire thing is just in a package. Now, don’t whine that JShell does not allow you to create packages. It is not meant to do that !

  • Want to quit JShell ?

Inform JShell by typing  /exit. JShell politely says GoodBye to you. Well, you could be a little rude and press Ctrl-D to exit JShell, in that case don’t expect JShell to say Goodbye!

Conclusion

JShell is a great addition to the JDK 9 release. Use it to experiment snippets of code and get immediate feedback. This article was just a quick introduction. JShell also has an API which can be used to integrate it into an IDE or a tool.

JDK 9 reached GA on 21st September 2017, to take a look at all the features, visit the openjdk site here.

Java 8 map and flatMap

In this post, we will be taking a look at the map and flatMap methods introduced in Java 8. We will be looking at a scenario where the map method does not produce the required output and why we really need the flatMap method. I will be using multiple examples to illustrate the same and also show you imperative and declarative styles of coding.

map: Let us consider the scenario where we have a collection of Person objects. Given a list of person objects, what if we wanted to return only the names of the people who have UK citizenship.

The imperative style of writing code would give us the following:


public List<String> getNamesOfUKCitizens(List<Person> persons)
{
List<String> allUKCitizens = new ArrayList<>();
for(Person p : persons)
{
if(p.getCitizenship() == Citizenship.UK){
allUKCitizens.add(p.getName());
}
}
return allUKCitizens;
}

To get this, we have to initialize an empty list, iterate through the loop, filter the people who have UK citizenship and then add the names to the empty list we create.Let’s try and solve this the  declarative way, using the map method.

The map method basically takes an object of one type and gives us an object of another type.


public List<String> getNamesOfUKCitizens()
{
return persons.stream()
.filter( p -> p.getCitizenship() == Citizenship.UK)
.map(p -> p.getName())
.collect(Collectors.toList());
}

Map_Flatmap_Pic1
filter,map and collect – Once the knob is turned on, everything happens !

The signature of the map method:

<R> Stream<R> map(Function<? super T,? extends R> mapper)

The signature looks complicated but it is easy to understand. The R is the output type of the stream and T is the input type.

Remember how the filter method (explained here) took a Predicate as a parameter? The map method takes a Function. This is also a functional interface. The function gets applied to each element. The p -> p.getName is a lambda expression, the function that gets applied to the Person object.  To understand this better, we could write the same thing as follows:


public List<String> getNamesOfUKCitizens()
{
Function<Person,String> mapper = p -> p.getName();
return persons.stream()
.filter( p -> p.getCitizenship() == Citizenship.UK)
.map(mapper)
.collect(Collectors.toList());
}

Remember that the map method takes one object and returns exactly one object. This is 1-1.

Few more examples of map API:

1.Given a list of numbers, we want to generate the square of each number:

We have input as a list of numbers of 1 type and we want to transform it:

Input: List<Integer> numbers = Arrays.asList(1,2,3,4,5);


numbers.stream()
.map( number -> number * 2)
.collect(Collectors.toList());

 Output:

[2, 4, 6, 8, 10]

2. Given a list of string, convert each string to upper case:

Transformation of one type to another, this time String to String – use map function

Input:

List<String> strings = Arrays.asList(“abc”,”pqr”,”xyz”);


strings.stream()
.map(s -> s.toUpperCase())
.collect(Collectors.toList()));

Output:  [ABC, PQR, XYZ]

3.Given a list of string, find the length of each string:

Input:

List<String> strings = Arrays.asList(“abc”,”pqr”,”xyz”);

Input to the map is a string and output is the length of each string.


strings.stream()
.map(s -> s.length())
.collect(Collectors.toList()));

Output: [3, 3, 3]

FlatMap: To understand the flatMap, let us consider a different example. Let us consider there are 3 systems and each system returns a list of strings. There is an application which combines these lists and sends the data back to us. Our system needs to take this input and generate all the strings as a single output.

List<String> system1 = Arrays.asList(“AB”,”cd”,”EF”);

List<String> system2 = Arrays.asList(“GH”,”ij”);

List<String> system3 = Arrays.asList(“kl”,”MN”,”op”);

//Combination

List<List<String>> input = Arrays.asList(system1,system2,system3);

Attempt 1: The input type is a List of List<String>.  We want to get all the strings from this input. We know that the map function helps us to transform an object. Will it help us here?  Let us take this step by step.


input.stream()
.map(list -> list)
.forEach(System.out::println)

The call to the input.stream()  returns a Stream<List<String>>

This gives an output:

[AB, CD, EF]

[GH, ij]

[kl, MN, op]

When we apply the map function, each time we are getting a list. But we need the individual elements in that list as a combined result. How do we get that?

When we have a single list as shown below and we applied the stream() to method to it, what happened?

List<String> strings = Arrays.asList(“A”,”b”,”C”);

strings.stream()

              .forEach(System.out::println);

This gave us the individual elements in that stream. So will applying the stream method to the list above solve the issue? Let’s try

Attempt 2:  Applying a stream to the list and using a map


input.stream()
.map(list -> list.stream())
.forEach(System.out::println)

This gives a weird output like this:

java.util.stream.ReferencePipeline$Head@87aac27

java.util.stream.ReferencePipeline$Head@3e3abc88

java.util.stream.ReferencePipeline$Head@6ce253f1

This gives us a stream of objects. So the usage of the map method in this scenario is not right. This is because the map method as mentioned earlier takes an input and produces one output. But in this case, the map method takes a list and we want the individual elements of that list to be combined together. This is not what the map function does. We need to use a different function.

Attempt 3: Using a flatMap


input.stream()
.flatMap(list -> list.stream())
.forEach(System.out::println);

This gives us the required output:

AB

cd

EF

GH

ij

kl

MN

Op

Let us break flatMap up into 2 operations:

map:

[ [AB, CD, EF]      [GH, ij]           [kl, MN, op] ]

  Stream 1             Stream 2           Stream 3

flatten it:

AB, cd, EF             GH, ij               kl ,MN ,op

The flatMap() does a map + flat. Flattening here is of the individual streams from each item in the list to a single stream. The flatMap() methods needs a stream and hence the list->list.stream().The flatMap method takes an input and can give either 0 or more elements.

Let us consider another example to understand this well. Let us consider 3 different football leagues. The English Premier league, the LIGA BBVA or the Spanish League and the Bundesliga. Each league has a list of teams. We can represent this as:


public class League {
private String leagueName;
private List<Team> teams;
}

view raw

League.java

hosted with ❤ by GitHub


public class Team
{
private String name;
public Team(String teamName){
this.name=teamName;
}
}

view raw

Team.java

hosted with ❤ by GitHub

Problem: Given a list of leagues, we need to return the names of the all the teams in the leagues.

Imperative style:


private static List<String> displayAllTeamNamesImperative(List<League> leagues){
List<String> teamNames = new ArrayList<>();
for(League league : leagues)
{
List<Team> teams = league.getTeams();
for(Team team : teams)
{
teamNames.add(team.getName());
}
}
return teamNames;
}

Declarative style using map:

We have a list of leagues. When we call stream() on it, it will operate on a single League object. But a league has multiple teams in it.  If we try solving this using map() then we land up getting this:


leagues.stream()
.map(league -> league.getTeams().stream())
.forEach(System.out::println);

Output:

java.util.stream.ReferencePipeline$Head@87aac27

java.util.stream.ReferencePipeline$Head@3e3abc88

java.util.stream.ReferencePipeline$Head@6ce253f1

We land up getting 3 streams. This means that the map operation is not the right fit here. We need a function that can take these streams and combine each of these elements in these streams to a unified output.

This is the scenario for a flatMap() as we have a collection of collections. So the input is  a collection of leagues and each league has another collection which is team.


private static List<String> displayAllTeamNamesFunctional(List<League> leagues)
{
return leagues.stream()
.flatMap(league ->league.getTeams().stream())
.map( team ->team.getName())
.collect(Collectors.toList());
}

When you have a collection of collections and want a unified output, use the flatMap.

I hope you have understood the basics of both map and flatMap methods and the scenarios in which they should be applied.