Notice

╠ This is my personal blog and my posts here have nothing to do with my employers or any other association I may have. It is my personal blog for my personal experience, ideas and notes. ╣

Saturday, July 18, 2020

JDK 15 [Pattern Matching of instanceof operator ]

This is an enhancement of Java language with pattern matching for the instanceof operator. Currently, this feature is in the second preview in JDK 15.

So currently when we need to cast an object, we check it using instanceof operation then only we cast the object to save our self from class cast exception.

existing instanceof operator

In the above code snippet, we have to explicitly cast it to an object. 
In this enhancement, we no more have to do it. 



To run the below code you need to install JDK 14 or above and have to enable the preview feature of javac & java. 
In order to enable that preview feature. 
javac 
      --enable-preview 
        -release <version> 
      <Source file>

java 
    --enable-preview 
       <Compiled class> 


// Anindya Bandopadhyay (anindyabandopadhyay@gmail.com)
public class PatternMatchingOfInstance {
public static void main(final String args[]) {
PatternMatchingOfInstance instance = new PatternMatchingOfInstance();
Object obj = instance.getValue((instance.new IntValue(1)));
if(obj instanceof Integer) {
final Integer intValue = (Integer) obj;
System.out.println(String.format("Int value = %d", intValue));
}
//JEP 375: Pattern Matching for instanceof (Second Preview)
if(obj instanceof Integer objInt) {
System.out.println(String.format("Using Pattern Matching for instanceof: Int value = %d", objInt));
}
}
private Object getValue(final Value value) {
return value.getValue();
}
interface Value {
Object getValue();
}
class IntValue implements Value {
private final int value;
public IntValue(final int value) {
this.value = value;
}
@Override
public Integer getValue() {
return value;
}
}
class BoolValue implements Value {
private final boolean value;
public BoolValue(final boolean value) {
this.value = value;
}
@Override
public Boolean getValue() {
return value;
}
}
class StrValue implements Value {
private final String value;
public StrValue(final String value) {
this.value = value;
}
@Override
public String getValue() {
return value;
}
}
class DoubleValue implements Value {
private final double value;
public DoubleValue(final double value) {
this.value = value;
}
@Override
public Double getValue() {
return value;
}
}
class FloatValue implements Value {
private final float value;
public FloatValue(final float value) {
this.value = value;
}
@Override
public Float getValue() {
return value;
}
}
}

Output

 Happy Coding!

Wednesday, May 20, 2020

Abstract Data Type

What is the data type?

A data type is an attribute in a programming language which define the domain of values and operations on that domain.

  • Define a certain domain of value. 
  • Define operations allowed on those values. 

Example 

int type
  • Take only integer values
  • Operations supported: addition, subtraction, multiplication, bitwise operation etc.  
float type 
  • Take only floating values 
  • Operations supported: addition, subtraction, multiplication, etc.  (it does not support operations like bitwise and modulus). 


Now, what is the user-defined data type? 

A user data type is NOT an attribute in a programming language but defines by the user which define the domain of values.

In below example, we define the user-defined data type using class. Here Person class is the type which is consist of bunch of String, LocalDate and Address fields. Person class have a user define a data type of Address.

Example

public class Person {
    private String firstName;
    private String lastName;
    private LocalDate dateOfBirth;
    private Address address;
   .....
}

public class Address {
   private String firstLine;
   private String lastLine,
   private State state;
  ....
}


Abstract Data Types (ADT)

Abstract Data Types (ADT) are like user define types which define values and operations on that user define type without specifying how the operation will happen.

Example

In this example, we will define an ADT where will create a data type named MyString class and define operations like addition, subtraction, multiplication and division. 

User Define Data Type 

  • MyString is a wrapper object of string. 
Let's define the operations of MyString data type.

User Define Operations 

  • The addition will concatenation two MyString. Example: "Hello" + " world" will result in "Hello world".
  • The subtraction will substring the difference of length. If the difference of length is zero or negative then it will have an empty string. Example: 
    • "Hello" - "world" will result in an empty string
    • "Hello" - "hi" will result in "Hel
    • "hi" - "Hello" will also result in an empty string. 
  • The division will remove common character(s) from MyString. Example: "Hello" / "world" will result in "He".
  • The multiplication will concatenate characters alternatively. Example: "Hello" * "world" will result in "Hweolrllod".

Actual Implementation 

package com.andy.adt;
import java.util.Objects;
public class MyString {
private final String myString;
public MyString(String myString) {
this.myString = myString;
}
public MyString add(MyString str2) {
return new MyString(myString + str2.toString());
}
public MyString subtract(MyString str2) {
int differenceInLength = myString.length() - str2.toString().length();
if (differenceInLength > 0) {
return new MyString(myString.substring(0, differenceInLength));
}
return new MyString("");
}
public MyString multiple(MyString str2) {
StringBuilder stringBuilder = new StringBuilder("");
int maxLength = Math.max(myString.length(), str2.toString().length());
for (int index = 0; index < maxLength; index++) {
if(index < myString.length()) {
stringBuilder.append(myString.charAt(index));
}
if(index < str2.toString().length()) {
stringBuilder.append(str2.toString().charAt(index));
}
}
return new MyString(stringBuilder.toString());
}
public MyString divide(MyString str2) {
char[] denominator = str2.toString().toCharArray();
String str = myString.toString();
for (char ch:
denominator) {
str = str.replaceAll(String.valueOf(ch), "");
}
return new MyString(str);
}
@Override
public String toString() {
return myString;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (!(o instanceof MyString)) return false;
MyString myString1 = (MyString) o;
return Objects.equals(myString, myString1.myString);
}
@Override
public int hashCode() {
return myString != null ? myString.hashCode() : 0;
}
}
view raw MyString.java hosted with ❤ by GitHub

Sample Unit Test of the Implementation 

package com.andy.adt;
import org.junit.jupiter.api.Test;
import static org.junit.jupiter.api.Assertions.*;
class MyStringTest {
private MyString myString;
@Test
public void testAdd(){
myString = new MyString("Hello");
MyString result = myString.add(new MyString(" World!"));
assertEquals("Hello World!", result.toString());
}
@Test
public void testSubtract_WhenSecondParameterIsLong() {
myString = new MyString("Hello");
MyString result = myString.subtract(new MyString(" World!"));
assertEquals("", result.toString());
}
@Test
public void testSubtract_WhenFirstParameterIsLong() {
myString = new MyString("Robot");
MyString result = myString.subtract(new MyString("Ok"));
assertEquals("Rob", result.toString());
}
@Test
public void testDivide() {
myString = new MyString("Hello");
MyString result = myString.divide(new MyString("world"));
assertEquals("He", result.toString());
}
@Test
public void testMultiple() {
myString = new MyString("Hello");
MyString result = myString.multiple(new MyString("world"));
assertEquals("Hweolrllod", result.toString());
}
}

Monday, April 27, 2020

One Time Password Generator

Simple code to generate One Time Password.
We are using java.util.SplittableRandom which was introduced in Java 8.
import java.util.SplittableRandom;
public class OTPgenerator {
public static void main(String[] p) {
int len = 6;
if(p.length > 0) {
len = Integer.valueOf(p[0]);
}
StringBuilder sb = new StringBuilder();
SplittableRandom ran = new SplittableRandom();
for(int i =0; i < len; i++) {
int n = ran.nextInt(1,10);
sb.append(n);
}
System.out.println(" Gnerated OTP " + sb.toString());
}
}

Output

Saturday, January 18, 2020

Exception flow control could be expensive.

As a developer sometimes we use exceptions as flow control. It could be expensive. I am going to show you how a simple change could help you to save a lot of time by simply not accepting exception as your code flow controller.
In this example, I will throw an exception if required data is not available during execution I will throw an IllegalArgumentException and in another case, I simply return a value using which call is going to take the decision based on the value then we will see how different it will be.


package com.andy.control;
public class FlowControlExample {
public static void main(String[] args) {
FlowControlExample example = new FlowControlExample();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100_000_000; i++) {
try {
String fullName = example.getFullNameThrowException(null, "middle", "");
} catch (IllegalArgumentException e) {
}
}
long timeTaken = System.currentTimeMillis() - startTime;
System.out.println(" Time taken to complete in case of exception is thrown. " + (timeTaken / 1000) + " in secs.");
startTime = System.currentTimeMillis();
for (int i = 0; i < 100_000_000; i++) {
String fullName = example.getFullNameReturnValue(null, "middle", "");
}
timeTaken = System.currentTimeMillis() - startTime;
System.out.println(" Time taken to complete in case of a value returned. " + (timeTaken / 1000) + " in secs.");
}
private String getFullNameThrowException(String firstName, String middleName, String lastName) {
if ((firstName == null || firstName.isEmpty()) && (lastName == null || lastName.isEmpty())) {
throw new IllegalArgumentException(" First and / or Last name cannot be null or empty.");
}
return firstName + " " + middleName + " " + lastName;
}
private String getFullNameReturnValue(String firstName, String middleName, String lastName) {
if ((firstName == null || firstName.isEmpty()) && (lastName == null || lastName.isEmpty())) {
return "";
}
return firstName + " " + middleName + " " + lastName;
}
}


Code Output


In case of exception, it will take around a minute for execution and in another case it is insignificant. Both methods are invoked one million times to determine the impact.
Code Output
I request you to think again if you are using exception as your flow controller in a code which will be invoked many times.

Then what if I have to address an exception scenario 

If I need to address an exception scenario then for optimization I could pre-allocate the exception object so that I can use them multiple times.

package com.andy.control;
public class FlowControlExample {
private static final IllegalArgumentException ILLEGAL_ARGUMENT_EXCEPTION = new IllegalArgumentException(" First and / or Last name cannot be null or empty.");
public static void main(String[] args) {
FlowControlExample example = new FlowControlExample();
long startTime = System.currentTimeMillis();
for (int i = 0; i < 100_000_000; i++) {
try {
String fullName = example.getFullNameThrowException(null, "middle", "");
} catch (IllegalArgumentException e) {
}
}
long timeTaken = System.currentTimeMillis() - startTime;
System.out.println(" Time taken to complete in case of exception is thrown. " + timeTaken + " in milliSecs.");
startTime = System.currentTimeMillis();
for (int i = 0; i < 100_000_000; i++) {
String fullName = example.getFullNameReturnValue(null, "middle", "");
}
timeTaken = System.currentTimeMillis() - startTime;
System.out.println(" Time taken to complete in case of a value returned. " + timeTaken + " in milliSecs.");
}
private String getFullNameThrowException(String firstName, String middleName, String lastName) {
if ((firstName == null || firstName.isEmpty()) && (lastName == null || lastName.isEmpty())) {
throw ILLEGAL_ARGUMENT_EXCEPTION;
}
return firstName + " " + middleName + " " + lastName;
}
private String getFullNameReturnValue(String firstName, String middleName, String lastName) {
if ((firstName == null || firstName.isEmpty()) && (lastName == null || lastName.isEmpty())) {
return "";
}
return firstName + " " + middleName + " " + lastName;
}
}

Code Output


In this case, you can see the result is much better but still high than return statement.

Let me know your thoughts about it. 

Monday, July 15, 2019

JDK 12 switch statement... No expression

In Java language, there are lots of improvement and new paradigm changes like lambda expression, streams, etc.
In JDK 12 you can use switch statement as an expression instead of a statement. Okay, what is the difference?

Let's write code a code to understand the difference.
/**
* Copyright © 2019, Anindya Bandopadhyay. All rights reserved.
*
* JDK 12 switch
*/
public class Jdk8Switch {
private static String numberInString(int num){
String str = null;
switch (num) {
case 1: str = "One";
break;
case 2: str = "Two";
break;
case 3: str = "Three";
break;
case 4: str = "Four";
break;
case 5: str = "Five";
break;
case 6: str = "Six";
break;
case 7: str = "Seven";
break;
case 8: str = "Eight";
break;
case 9: str = "Nine";
break;
case 0: str = "Zero";
break;
default:
str = "Please pass a single digit number.";
}
return str;
}
private static String oddOrEvenWithIn9(int num) {
String str = null;
switch(num){
case 2:
case 4:
case 6:
case 8:str = "even";
break;
case 1:
case 3:
case 5:
case 7:
case 9:str = "odd";
break;
}
return str;
}
public static void main(String[] args) {
System.out.println(numberInString(3));
System.out.println(oddOrEvenWithIn9(8));
}
}
view raw Jdk8Switch.java hosted with ❤ by GitHub


In the above code, you can clearly see these switch statement with fall through structure and irritating 😠 break statement. Expressing switch as a statement is error-prone, repetitive and roundabout.
In JDK 12 switch expression will come in non-fall through it means no break statement anymore.

So what does switch expression means?

static void howMany(int k) {
    System.out.println(
        switch (k) {
            case  1 -> "one"
            case  2 -> "two"
            default -> "many"
        }
    );
}

Let's rewrite the above come in JDK 12 using the latest switch expression and see how many lines of code we could reduce it and how readable our code it will be.

/**
* Copyright © 2019, Anindya Bandopadhyay. All rights reserved.
*
* JDK 12 switch
*/
public class Jdk12Switch {
private static String numberInString(int num){
String str = switch (num) {
case 1 -> "One";
case 2 -> "Two";
case 3 -> "Three";
case 4 -> "Four";
case 5 -> "Five";
case 6 -> "Six";
case 7 -> "Seven";
case 8 -> "Eight";
case 9 -> "Nine";
case 0 -> "Zero";
default -> "Please pass a single digit number.";
};
return str;
}
private static String oddOrEvenWithIn9(int num) {
String str = switch(num){
case 0 -> "Zero";
case 2, 4, 6, 8 -> "even";
case 1, 3, 5, 7, 9 -> "odd";
default -> "Not applicate";
};
return str;
}
public static void main(String[] args) {
System.out.println(numberInString(3));
System.out.println(oddOrEvenWithIn9(8));
}
}
Keep it simple.

Oh ! please do remember that as this language enhancement not present in JDK 12 while compiling and running the JDK 12 code you need to add few arguments.



javac --enable-preview -source 12 -Xlint:preview Jdk12Switch.java 



java --enable-preview -source 12 Jdk12Switch 



 Please do share this with others and ask/discuss questions if you have.
Happy learning!

Wednesday, January 16, 2019

How to support multiple types of multi-tenancy database?

In this proposed solution, we are going to support multiple tenants with different types of multi-tenancy database models in one application.
To achieve this we need to have tenant identifier columns in all tables, and all query should have the association of tenant identifier as criteria.
We will be adding another column to have database identifier along with tenant identifier.
In this example, we have five tenants but T1 & T2 tenants have their own database implementation named D1 & D2 respectively, and T3, T4 & T5 tenant has the common database named ‘CD’/Common Database.


 

We going to have three databases named D1, D2 and CD, three data sources for these three databases. In application, we going to have the map of tenant identifier and the database identifier.  In the persistent layer of the application, we are going to retrieve the tenant identifier from the tenant context and get the data source with respect to it. We will be populating the tenant identifier in each persistence call and all the update, delete and retrieve call will have tenant identifier as criteria along with other criteria.
By this way, we can support multiple multiple types of multitenancy database implementation models.

Business Impact 

We can efficiently able to manage different categories of clients like we can group up small clients into a common database. As a result, these small clients will be benefited from shared storage cost and low database maintenance cost. On the other side, big clients could have their own database and it will make sure they can scale well in the future. 

Looking forward to your questions & suggestions.





Friday, January 26, 2018

Java Unit Testing of POJO class

I have created a tool to help the developer to do test coverage of their POJO Bean classes.

Java POJO classes are supposed to be tested while testing any business logic but in the real world, it does not happen. So I created this framework which will help developers while showing coverage to reviewers & auditors, and also help to discover silly mistakes which happen mostly during field name refactoring.

 I personally recommend developers that try to get these POJO tested while testing business logic if you somehow could not do it then this tool comes second.

This is a very simple to use the framework with lots of features which developers required in the real world.





Here is Wiki to learn this framework.


I am open to your feedback, please try it and let me know your feedback.