Wednesday, April 8, 2020

'var' to declare variables in Java !!!

Hello all ! Can you guess what will be  the output of the following code snippet in Java?


Add.java
=======
public class Add{
public int add(){
var x = 10;
var y = 20;
var sum = x+y;
return sum;
}
public static void main(String[] args){
Add a = new Add();
System.out.println(a.add());  // what is the o/p?
}
}

OK !!! You might have the following answers :
  • Compile time error ('var' is not a type)
  • Success with O/P = 30
For me , it is success with a valid output as 30. Suddenly you might be thinking "am i crazy !!!"
Yes I am a crazy developer.  In the above code snippet, there is no error if you are using Java-10. (Even if you have Java-8 , you can also achieve this ; Read completely, you will figure it out.)

If you have coded in Scala, Go, C#, Kotlin or simple in Javascript, then you know that they all have some kind of local variable type inference already build in.

e.g.  Javascript has let and varScala and Kotlin have var and val, C++ has auto, C# has var, and Go has support via declaration with : = the  operator.


Although type inference was improved a lot in Java 8 with the introduction of Lambda expression, method references, and Streams, but still local variables needed to be declared with proper types , but that's gone now . Let's discuss it more .


'var' In JAVA  

It enhances the Java language to extend type inference to declaration of local variables with initializers. This feature has been introduced in Java-10 and is build under JEP 286: Local-Variable Type Inference .

Why 'var' in Java ?

Java developers have long been complaining  about the degree of boilerplate code and ceremonies involved while writing Java code. 

Example :

In below example we know that the RHS is a String type, still we are writing String on LHS.
String str ="Java";
Same in below example, we are assigning a list of String values, still we need to specify the type .
List<String> list = Arrays.asList("Deb","Honey","Rosalin");
Here we are creation a Customer type on RHS, but still on LHS, we need to write Customer as type.
Customer customer = new Customer();


The use of var also makes your code concise by reducing duplication, e.g. the name of the Class that comes in both right and left-hand side of assignments as shown in the following example:
Customer customer = new Customer();// infers Customer
var bos = new ByteArrayOutputStream(); // infers ByteArrayOutputStream
var str ="Java";// infers String
var  list = Arrays.asList("Deb","Honey","Rosalin"); // infers List<String>

How to achieve the same in Java-8

Cool !!! As per java -8 , officially it is not supported(supported from Java-10). But yes, we can still achieve it . If you want to achieve ORM tool as Hibernate, you are going beyond the java and using a third party provided tool. Same as we can achieve it using a third party dependency LOMBOK plugin.


Ex : 
import lombok.*;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Data
class Customer{
private String name;
private int age;
public List<Customer> createNewCustomers(){
var customers = new ArrayList<Customer>();
for(var i=20;i<25;i++) {
var name ="Name-"+i;
var age =i;
var customer = new Customer(name,age);
customers.add(customer);
}
return customers;
}
}
///////
var c = new Customer();
var customers =c.createNewCustomers();
System.out.println(customers);

Points To Remember

So now you know tat how can you declare local variables without declaring the type in Java 10. It is time to consider some important factors before you start writing for production code.
  • This feature is built under JEP 286 - Local-Variable Type Inference.
  • The var allows local variable type inference, which means the type for the local variable will be inferred by the compiler.
  • The local variable type inference (or Java 10 var type) can only be used to declare local variables, e.g. inside methods, on initializer code block, indexes in the enhanced for loop, lambda expressions, and local variables declared in a traditional for loop.
  • You cannot use it for declaring formal variables and return types of methods, declaring member variables or fields, constructor formal variables, or any other kind of variable declaration.

Risks and Assumptions

Risk: Because Java already does significant type inference on the RHS (lambda formals, generic method type arguments, diamond), there is a risk that attempting to use var on the LHS of such an expression will fail, and possibly with difficult-to-read error messages.

Ex .
case -1
var x;
^
('var' on a local variable requires an initializer expression)
case-2
var f = () -> { };
^(lambda expression needs an explicit target-type) 
case -3
var m = this::l; (error: cannot infer type for local variable m)

That's all about var in Java 10, an interesting Java 10 feature that allows you to declare local variables without declaring their type. Like other language feature, local variable type inference can be used to write both clear and unclear code. The responsibility for writing clear code lies on the developer. See more for style guidelines of var.


Sunday, April 5, 2020

Spring Data JPA : Query by Example

Spring Data JPA : Query by Example(QBE)




If you are a java developer and if anyone asks to you to create an enterprise application, suddenly your head will move left & right around the JAVA orbit and Spring/Spring Boot framework will hit your brain. Of course others might be, but it is often. Am i right ?

Spring Boot  ecosystem is an evolution of Spring framework which helps to create stand-alone, production-grade Spring based applications with minimal effort.

Lucky-draw Coupons 


In a festival time, my manager asked me to implement the following use case .
  1.  You have to find all the customers whose first name ends with some given character and to send some random lucky draw coupon code which they can redeem on a e-commerce site. 
Yes, i can use native DB query ; but he doesn't give green signal !!! for db query, because later he has to do some intermediate operations too and he ordered me to achieve it using spring boot . 

You might also be interested in the related tutorials:

Spring Data JPA

It facilitates the implementation of JPA based repositories. It makes the life easier to build spring based applications that uses data access technologies.

Spring Data JPA Query By Example

If you are using Spring Data JPA, you might have used JpaRepository of spring data JPA. If you check the JpaRepository.class you will find the below signature :

public interface JpaRepository<T, ID>
  extends PagingAndSortingRepository<T, ID>,
QueryByExampleExecutor<T> {}

See, it extends QueryByExampleExecutor .So what is this and why it has extended ?

Query By Example(QBE) is a developer-friendly querying technique which facilitates to write dynamic query without any specific query-language.

It allows us to execute queries based on an Example entity instance. The field of the Example instance needs to be populated with the desired criteria values. 

In Spring Data JPA we can use org.springframework.data.domain.Example instance which takes an entity instance (called 'probe' in this context). E.g
//get all the customers whose first name is ending with 'dra' 
var customers = Customers.builder().firstName(ending).build();
 var matcher = ExampleMatcher.matching()
.withIgnoreNullValues()
.withMatcher("firstName", match ->                  match.endsWith().ignoreCase(true));
 var example = Example.of(customers, matcher);

By default, fields having null values are ignored in the underlying query, so above Example will be equivalent to the following JPQL:
SELECT t from Customer c where c.firstName = '%dra';

Examples

I am going to implement the same above mentioned use case.
1. Get All customers
2. Get all customers whose first name ends with 'dra'
3. Get all customers whose last name ends with 'das'
4. Get all customers whose first name equals 'Rosalin'
5. Get all customers whose wallet balance is 2000
Let's start with a simple example:

Entity : Customer.java


@Entity
@Table(name = "customers")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode
@ToString
@Builder
public class Customers implements Serializable{
private static final long serialVersionUID = 34131213L;
@Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
@Column(name = "first_name", nullable = false)
    private String firstName;
@Column(name = "last_name")
    private String lastName;
@Column(name = "balance")
private Long   walletBalance;
}

Service : CustomerService.java

public List<Customers> findByFirstNameEnding(String ending) {
var customers = Customers.builder().firstName(ending).build();
var matcher = ExampleMatcher.matching()
.withIgnoreNullValues()
.withMatcher("firstName", match -> match.endsWith().ignoreCase(true));
var example = Example.of(customers, matcher);
return (List<Customers>) customerRepository.findAll(example);
}

Find the complete code on github.



In this tutorial, we have used Spring Data JPA Query By Example technique to generate queries. You might also be interested in the related tutorials:

Thursday, April 2, 2020

CyclicBarrier : Java Concurrency

CyclicBarrier 


How many of you are aware about CyclicBarrier ? Almost all Java developers. Am i right ? When my boss asked me the same, i was thinking is it related to any cycle path of national highway. Oh, later on i found that it is a concept if Java Concurrency.In this article, we will dig it more.


Introduction

It is a synchronization aid(Synchronizers) that allows a set of threads to all wait for each other to reach a common barrier point. 

CyclicBarriers are useful in programs involving a fixed sized party of threads that must occasionally wait for each other. The barrier is called cyclic because it can be re-used after the waiting threads are released.

It is a part of the java.util.concurrent package which almost contains more than 57 numbers of classes.

CyclicBarrier is similar to CountDownLatch in Java(of course there are some differences) and allows multiple threads to wait for each other (barrier) before proceeding.




CyclicBarrier Usage

The CyclicBarrier supports a barrier action, which is a Runnable that is executed once the last thread arrives. 

There are two types of constructor available. 

public CyclicBarrier(int parties)

Creates a new CyclicBarrier that will trip when the given number of parties (threads) are waiting upon it, and does not perform a predefined action when the barrier is tripped.

Optionally, we can pass the second argument to the constructor, which is a Runnable instance. This has logic that would be run by the last thread that trips the barrier:

public CyclicBarrier(int parties, Runnable barrierAction

Example :


CyclicBarrier: Consider the same IT world scenario where manager divided modules between development teams (A and B). He goes on leave and asked both team to wait for each other to complete their respective task once both are done assign it to QA team for testing.
Here manager thread works as main thread and development team works as worker thread. Development team threads wait for other development team threads after completing their task.

Implementation

Let's consider the following scenario. 
Suppose we have two different services performs some operations and store the corresponding results in a list which should wait for each other to complete the execution. When both the services finish performing their action, the main thread starts procession the data and gives the sum of all numbers. 
public class CyclicBarrierDemo {
private CyclicBarrier cyclicBarrier;
    private List<List<Integer>> partialResults= Collections.synchronizedList(new ArrayList<>());
    private Random random = new Random();
    
    public void runSimulation() {
        cyclicBarrier = new CyclicBarrier(2, new AggregatorThread());
        Thread worker = new Thread(new ServiceOneThread());
        worker.start();
        
        Thread worker2 = new Thread(new ServiceTwoThread());
        worker2.start();
    }
    public static void main(String[] args) {
    CyclicBarrierDemo demo = new CyclicBarrierDemo();
        demo.runSimulation();
    }
    
    
    
    class AggregatorThread implements Runnable {
     
        @Override
        public void run() {
            String thisThreadName = Thread.currentThread().getName();
            System.out.println(thisThreadName + ": Computing sum of 2 service" );
            int sum = 0;
            System.out.println(partialResults);
            for (List<Integer> threadResult : partialResults) {
                System.out.print("Adding ");
                for (Integer partialResult : threadResult) {
                    System.out.print(partialResult+" ");
                    sum += partialResult;
                }
                System.out.println();
            }
            System.out.println(thisThreadName + ": Final result = " + sum);
        }
    }
    
    class ServiceOneThread implements Runnable{
    @Override
    public void run() {
    
    System.out.println("Service-1 run method");
    List<Integer> partialResult = new ArrayList<>();
    for (int i = 0; i < 10; i++) {    
    Integer num = random.nextInt(10);
    partialResult.add(num);
    }
    System.out.println("Service-1 partial results :" + partialResult);
    partialResults.add(partialResult);
    try {
    System.out.println("Service-1 is moving to sleeping state...");
    Thread.sleep(100000);
    System.out.println("Service-1 is comes up from sleeping state...");
    System.out.println("Service-1  waiting for others to reach barrier.");
    cyclicBarrier.await();
    
    } catch (InterruptedException e) {
    } catch (BrokenBarrierException e) {
    }
    }
    }
    
    
    class ServiceTwoThread implements Runnable{
    @Override
    public void run() {
    System.out.println("Service-2 run method");
    List<Integer> partialResult = new ArrayList<>();
    for (int i = 0; i < 10; i++) {    
    Integer num = random.nextInt(5);
    partialResult.add(num);
    }
    partialResults.add(partialResult);
    try {
    System.out.println("Service-2 numbers :" + partialResult);
    System.out.println("Service-2  waiting for others to reach barrier.");
    cyclicBarrier.await();
    } catch (InterruptedException e) {
    } catch (BrokenBarrierException e) {
    }
    }
    }
    
}



Output :
Service-1 run method
Service-1 partial results :[8, 0, 8, 3, 9, 2, 6, 1, 4, 2]
Service-1 is moving to sleeping state...   //see here, service-1 moved to sleep
Service-2 run method
Service-2 numbers :[2, 0, 0, 2, 3, 0, 0, 4, 2, 2]
Service-2  waiting for others to reach barrier.
Service-1 is comes up from sleeping state...
Service-1  waiting for others to reach barrier.
Thread-0: Computing sum of 2 service //main thread
[[8, 0, 8, 3, 9, 2, 6, 1, 4, 2], [2, 0, 0, 2, 3, 0, 0, 4, 2, 2]]
Adding 8 0 8 3 9 2 6 1 4 2 
Adding 2 0 0 2 3 0 0 4 2 2 
Thread-0: Final result = 58