Java 8 – Builder pattern with Consumer interface

In this post, I am going to provide an example to show how we can implement the Builder pattern with Consumer interface.

With the use of Consumer interface, we can get rid of some boilerplate code in Java.

Assume that you have a model class called User and it contains a builder class inside of it. So if we want to create an User instance, then we can make use of that builder class. See the below example to know how we can do it in a normal way.


public class User {

    private String firstName;

    private String lastName;

    private int age;

    public User(UserBuilder userBuilder) {
        this.firstName = userBuilder.firstName;
        this.lastName = userBuilder.lastName;
        this.age = userBuilder.age;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("User{");
        sb.append("firstName='").append(firstName).append('\'');
        sb.append(", lastName='").append(lastName).append('\'');
        sb.append(", age=").append(age);
        sb.append('}');
        return sb.toString();
    }

    public static class UserBuilder {

        private String firstName;
        private String lastName;
        private int age;

        public UserBuilder withFirstName(String firstName){
            this.firstName=firstName;
            return this;
        }
        public UserBuilder withLastName(String lastName){
            this.lastName=lastName;
            return this;
        }
        public UserBuilder withAge(int age){
            this.age=age;
            return this;
        }

        public User build() {
            return new User(this);
        }
    }

    public static void main(String[] args) {
        User user = new UserBuilder().withFirstName("bala").withLastName("samy").withAge(77).build();
        System.out.println(user);
    }


If you look at the above example, then you can understand there are two many setter methods available in the UserBuilder class. We can avoid this with Consumer interface.

I have implemented the same with consumer interface. Refer below it.


import java.util.function.Consumer;

public class User {

    private String firstName;

    private String lastName;

    private int age;

    public User(UserBuilder userBuilder) {
        this.firstName = userBuilder.firstName;
        this.lastName = userBuilder.lastName;
        this.age = userBuilder.age;
    }

    @Override
    public String toString() {
        final StringBuilder sb = new StringBuilder("User{");
        sb.append("firstName='").append(firstName).append('\'');
        sb.append(", lastName='").append(lastName).append('\'');
        sb.append(", age=").append(age);
        sb.append('}');
        return sb.toString();
    }

    public static class UserBuilder {

        public String firstName;
        public String lastName;
        public int age;

        public UserBuilder with(Consumer function) {
            function.accept(this);
            return this;
        }

        public User build() {
            return new User(this);
        }
    }

     public static void main(String[] args) {
        User user = new User.UserBuilder().with(person -> {
                                                person.firstName = "bala";
                                                person.lastName = "samy";
                                                person.age = 77;
        }).build();
        System.out.println(user);
    }
}

Explanation:
I have removed all the setter methods available in the UserBuilder class and created only one method with() which takes the Consumer function as input.

Consumer is a functional interface in Java and it accepts a single input argument and does not return any value. Here we are going to pass the person object with the corresponding values to each field to the accept method. I have replaced the ‘person’ with ‘$’ to make it simpler.


  public static void main(String[] args) {
        User user = new User.UserBuilder().with($ -> {
                                                $.firstName = "bala";
                                                $.lastName = "samy";
                                                $.age = 77;
        }).build();
        System.out.println(user);
    }

The one drawback of this approach is to make all the fields of UserBuilder as public. But this should be fine as we are not going to modify the actual class (User) here.

Advertisements

Java 8 – Optional class

Java 8 contains a new class called ‘Optional’ in the utils package which is used to represent a value is present or not.

This class is used to avoid the Null pointer exception. So we don’t need to do any null check in our code if we use Optional object along with our object.

Refer the below example to know how we can use the Optional class.


import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;

public class OptionalMain {

    public static void main(String[] args) {

        OptionalMain optionalMain = new OptionalMain();
        optionalMain.testBasic();
        optionalMain.testFilter();
        optionalMain.testMap();
    }

    private void testBasic() {

        // Create the Optional object with a string object. Note the string is null.
        //This will create Optional.empty as the value is null
        Optional stringOptional = Optional.ofNullable(null);
        System.out.println("stringOptional:" + stringOptional);
        try {
            //If you pass null value to of method, then it will throw Null pointer exception
            System.out.println("ofNullable on Non-Empty Optional: " + Optional.of(null));
        }
        catch (NullPointerException npx) {
            npx.printStackTrace();
        }

        // Check whether the value is present in the Optional object
        System.out.println("stringOptional value is present: " + stringOptional.isPresent());

        // Get the value from the Optional object. If its null, then return the default value
        // passed to the orElse method
        System.out.println("stringOptional value " + stringOptional.orElse("EMPTY"));

        // Create the Optional object with a string object.
        Optional nameOptional = Optional.ofNullable("name");
        System.out.println("nameOptional name is present:" + nameOptional.isPresent());
        nameOptional.ifPresent(name -> System.out.println("Name is available"));

        try {
            // Get the value from the Optional object. If its null, then throw an exception
            System.out.println("stringOptional value " + stringOptional.orElseThrow(RuntimeException::new));
        }
        catch (RuntimeException ex) {
            ex.printStackTrace();
        }
    }

    private void testFilter() {
        Optional nameOptional = Optional.of("john");
        System.out.println("Filter Operation:" + nameOptional.filter(name -> name.equals("john")));
        Optional numOptional = Optional.of(100);
        System.out.println(numOptional.filter(value -> value > 10));
        System.out.println(numOptional.filter(value -> value > 100));
    }

    private void testMap() {

        List fruits = Arrays.asList("apple", "orange", "banana");
        Optional<List> fruitsOptional = Optional.ofNullable(fruits);
        System.out.println("Fruits" + fruitsOptional.get());
        System.out.println("Mapping the Fruits " + fruitsOptional.get().stream().map(String::toUpperCase)
                .collect(Collectors.toList()));

    }
}

Output:


stringOptional:Optional.empty
stringOptional value is present: false
stringOptional value EMPTY
nameOptional name is present:true
java.lang.NullPointerException
	at java.util.Objects.requireNonNull(Objects.java:203)
	at java.util.Optional.(Optional.java:96)
	at java.util.Optional.of(Optional.java:108)	
Name is available
java.lang.RuntimeException
	at java.util.Optional.orElseThrow(Optional.java:290)
Filter Operation:Optional[john]
Optional[100]
Optional.empty
Fruits[apple, orange, banana]
Mapping the Fruits [APPLE, ORANGE, BANANA]


Stackshare

If you want to know about the tools or application stack used in any major tech company, then you can visit this web site stackshare 

This is a crowd sourcing site and it acts as a software discovery platform and lets us search for the best software tools and which companies are using them.

 

How to use WireMock for stubbing web services

WireMock is a library for stubbing and mocking REST Web services. This will be a handy one if we want to test external web services. When we use this, it will start a mock http server on the given port number so it looks like we are connecting to the actual web services.

Lets see how we can use this for writing JUnit test cases. Consider that you have two web services. one if for creating the user and another one is for fetching it. We don’t worry about the actual services. Let’s see how we can stub these services with WireMock.

I am going to use JUnit Rule for this example. Add the below dependencies in the maven pom.xml file.

<dependencies>
        <dependency>
            <groupId>com.github.tomakehurst</groupId>
            <artifactId>wiremock</artifactId>
            <version>2.7.1</version>
            <scope>test</scope>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.18</version>
        </dependency>
        <dependency>
            <groupId>org.hamcrest</groupId>
            <artifactId>hamcrest-all</artifactId>
            <version>1.3</version>
        </dependency>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>4.12</version>
        </dependency>
    </dependencies>

Now my test code is given below,


package com.wiremock;

import com.github.tomakehurst.wiremock.junit.WireMockRule;
import org.glassfish.jersey.client.JerseyClient;
import org.glassfish.jersey.client.JerseyClientBuilder;
import org.junit.After;
import org.junit.Before;
import org.junit.Rule;
import org.junit.Test;

import javax.ws.rs.core.Response;

import static com.github.tomakehurst.wiremock.client.WireMock.aResponse;
import static com.github.tomakehurst.wiremock.client.WireMock.get;
import static com.github.tomakehurst.wiremock.client.WireMock.matching;
import static com.github.tomakehurst.wiremock.client.WireMock.post;
import static com.github.tomakehurst.wiremock.client.WireMock.postRequestedFor;
import static com.github.tomakehurst.wiremock.client.WireMock.urlEqualTo;
import static com.github.tomakehurst.wiremock.client.WireMock.urlMatching;
import static javax.ws.rs.client.Entity.entity;
import static javax.ws.rs.core.MediaType.APPLICATION_XML_TYPE;
import static org.junit.Assert.assertEquals;

public class WireMockTest {

    @Rule
    public WireMockRule rule = new WireMockRule(8080);

    private static String GET_USERS = "http://localhost:8080/users/12345";
    private static String POST_USER = "http://localhost:8080/users";
    private static String USER_CONTENT = "<users>
   <user>
      <id>12345</id>
      <name>bala</name>
   </user>
</users>";

    JerseyClient client;

    @Before
    public void setUp() {
        client = JerseyClientBuilder.createClient();
    }

    @After
    public void tearDowm() {
        rule.shutdown();
    }

    private void stubFor(){
      rule.stubFor(post(urlEqualTo("/users")).willReturn(aResponse().withStatus(200));
rule.stubFor(get(urlEqualTo("/users/12345")).willReturn(
                aResponse().withHeader("Content-Type", "application/xml")
                        .withBody(USER_CONTENT)));
    }

    @Test
    public void testAddUser() {
        stubFor();
        client.target(POST_USER).request().post(entity(USER_CONTENT, APPLICATION_XML_TYPE));
        rule.verify(postRequestedFor(urlMatching("/users"))
                            .withRequestBody(matching(USER_CONTENT))
                            .withHeader("Content-Type", matching("application/xml")));

    }

    @Test
    public void testGetUser() {
        stubFor();
        Response response = client.target(GET_USERS).request().get();
        String output = response.readEntity(String.class);
        System.out.println("output: "+output);
        assertEquals(200, response.getStatus());
        assertEquals(USER_CONTENT, output);
    }
}

Explanation:
The first step is to add the WireMockRule and pass the port number on which the mock server is going to be run. You can specify any port number. By default its 8080.

Now the next step is to add the stubFor for both services(getUser, addUser)
For adding user service, the method is POST and it will return the response status as 200. For getting the user service, the method is GET and it will the return the static user response XML.

The next step is to call the services with the REST client object.
The final step is to do the verification. We can do the same kind of verification as such verifying the actual response.

Refer the code @https://github.com/dkbalachandar/java-wiremock-tester

Java 8 – Lambda Predicates

Predicate is a functional interface in java 8. It’s used to hold the lambda expression and takes a value or an object and return a boolean value.

This is very handy if you want to do any validation or filtering anythig.

Refer the below example to know how to use the Predicate for validating the number whether it’s even or not and some more operations.


import java.util.function.Predicate;

public class PredicateMain {

    public static void main(String[] args) {
        // Validate whether the number is even or not.
        System.out.println("Predicates.isEven(2)::" + Predicates.isEven().test(2));
        // Validate whether the number is odd or not.
        System.out.println("Predicates.isOdd(3) ::" + Predicates.isOdd().test(3));
        // Validate whether the number is even and also greater than 100
        System.out.println("Predicates.isEven().and(Predicates.isGreaterThan100(100)) ::"
                + Predicates.isEven().and(Predicates.isGreaterThan100()).test(100));
        // Validate whether the number is even and also greater than 100
        System.out.println("Predicates.isEven().and(Predicates.isGreaterThan100(102)) ::"
                + Predicates.isEven().and(Predicates.isGreaterThan100()).test(102));
        // Validate whether the number is even or greater than 100
        System.out.println("Predicates.isEven().or(Predicates.isGreaterThan100(101)) ::"
                + Predicates.isEven().or(Predicates.isGreaterThan100()).test(101));
        // Validate whether the number is even and negate the result.
        System.out.println("Predicates.isEven().negate(11) ::" + Predicates.isEven().negate().test(11));
    }

    static class Predicates {

        public static Predicate isEven() {
            return number -> number % 2 == 0;
        }

        public static Predicate isOdd() {
            return number -> number % 2 != 0;
        }

        public static Predicate isGreaterThan100() {
            return number -> number > 100;
        }
    }
}


Output:



Predicates.isEven(2)::true
Predicates.isOdd(3) ::true
Predicates.isEven().and(Predicates.isGreaterThan100(100)) ::false
Predicates.isEven().and(Predicates.isGreaterThan100(102)) ::true
Predicates.isEven().or(Predicates.isGreaterThan100(101)) ::true
Predicates.isEven().negate(11) ::true


Refer the below example to know how we can use this for filtering


import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;

public class PredicateCollections {

    public static void main(String[] args) {

        List users = Arrays.asList(new User("Bob", 51, 170), new User("john", 52, 80), new User("paul", 45 ,120), new User("alex", 46, 150), new User("scott", 56, 150));

        //All the users whose age are above 50
        List above50Users = filter(users, isAgeAbove50());
        System.out.println("The above 50 age users \n" + above50Users);

        //All the users whose age are below 50
        List below50Users = filter(users, isAgeBelow50());
        System.out.println("The below 50 age users \n"+ below50Users);

        //We can also use the negate expression. Lets see how we can do that
        above50Users = filter(users, isAgeBelow50().negate());
        System.out.println("The above 50 age users \n" + above50Users);

        below50Users = filter(users, isAgeAbove50().negate());
        System.out.println("The below 50 age users \n"+ below50Users);

        //Users whose age is above 50 and weight is more than 100
        List above50AndExcessWeightUsers = filter(users, isAgeAbove50().and(isWeightGtThan100()));
        System.out.println("The above 50 and excess weight users \n"+ above50AndExcessWeightUsers);
    }

    public static Predicate isAgeAbove50() {
        return user -> user.age > 50;
    }

    public static Predicate isAgeBelow50() {
        return user -> user.age < 50;
    }
    public static Predicate isWeightGtThan100() {
        return user -> user.weight > 100;
    }

    public static List filter(List users, Predicate p) {
        return users.stream().filter(p::test).collect(Collectors.toList());
    }

    static class User {

        String name;
        int age;
        int weight;

        User(String name, int age, int weight) {
            this.name = name;
            this.age = age;
            this.weight = weight;
        }

        @Override
        public String toString() {
            return "name:"+name +" age:"+age + " weight:"+weight;
        }
    }
}

Output:


The above 50 age users 
[name:Bob age:51 weight:170, name:john age:52 weight:80, name:scott age:56 weight:150]
The below 50 age users 
[name:paul age:45 weight:120, name:alex age:46 weight:150]
The above 50 age users 
[name:Bob age:51 weight:170, name:john age:52 weight:80, name:scott age:56 weight:150]
The below 50 age users 
[name:paul age:45 weight:120, name:alex age:46 weight:150]
The above 50 and excess weight users 
[name:Bob age:51 weight:170, name:scott age:56 weight:150]


Jersey REST service and Thread Local usage

In this exercise, I am going to provide an example to show how we can use the ThreadLocal with the Jersey REST service.

Consider that it’s a REST application and we need the user details in the application flow many places. The User details will be retrieved with the header information availbale in the HttpServletRequest.
One solution is to pass the HttpServletRequest object whereever its required. But its a tedious job.
So an another way is to use the ContainerRequestFilter and processes the request, then extract out the header and call the back end to get the User details and put into the ThreadLocal storage so that it can be accessible anywhere in that thread flow.

Refer the below sample code to know how to do that. We don’t use the Spring Framework here.

DataHolder:
This class holds the static ThreadLocal variable and it has getter and setter for User object. We will be setting the User Object from the ContainerRequestFilter


package com.utils;

public class DataHolder{

    private static final ThreadLocal userThreadLocal = new ThreadLocal();

    public static void setUser(User user) {
        userThreadLocal.set(user);
    }

    public static User getUser() {
        return userThreadLocal.get();
    }

    public static void remove() {
        userThreadLocal.remove();
    }
}

UserDataCaptureRequestFilter
This filter will intercept the request and extract out the header and retrieve the user details and put it into the ThreadLocal.



package com.filters;

import javax.servlet.http.HttpServletRequest;
import javax.ws.rs.container.ContainerRequestContext;
import javax.ws.rs.container.ContainerRequestFilter;
import javax.ws.rs.core.Context;
import javax.ws.rs.ext.Provider;
import java.io.IOException;

@Provider
public class UserDataCaptureRequestFilter implements ContainerRequestFilter {
    @Context
    private HttpServletRequest httpRequest;

    @Override
    public void filter(ContainerRequestContext requestContext) throws IOException {
        //Get the User data from the back end system with the request header/cookie. I have not given the getUser() method but assume it will get the user details 
        User user = getUser(httpRequest);
        DataHolder.setUser(user);
    }
}


Application
The ResourceConfig class where we can specify the packages to look into for the end points and context


public class Application extends ResourceConfig {
    public Application() {
        packages(true, "com.resource");
        packages(true, "com.filters");
    }
}

 
UserResource
This service returns the User details in JSON format. Here We have not retrived the User Details once again since we already retrieved the data in the filter itself. So the data would be available in the Thread scope. So we could use it


package com.resource;

import com.utils.DataHolder;
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;
import javax.ws.rs.core.Response;

@Path("user")
public class UserResource{

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public Response getUser() {
       
        return Response.ok().entity(DataHolder.getUser()).type(MediaType.APPLICATION_JSON).build();
    }
}

 

 

Finding the majority Element with Moore’s Voting Algorithm

Leetcode problem:

https://leetcode.com/problems/majority-element/description/

Problem Description:

Given an array of size n, find the majority element. The majority element is the element that appears more than ⌊ n/2 ⌋ times.

You may assume that the array is non-empty and the majority element always exists in the array.

Algorithm Link:

https://www.cs.utexas.edu/~moore/best-ideas/mjrty/index.html

moores-voting-algorithm

Solution:


public class Main {

    public static int majorityElement(int[] nums) {

        int currentElement = 0;
        int counter = 0;
        for (int num : nums) {
            if (counter == 0) {
                currentElement = num;
                counter = 1;
            }
            else {
                if (num == currentElement) {
                    counter++;
                }
                else {
                    counter--;
                }
            }
        }
        return currentElement;
    }

    public static void main(String[] args) {

        int[] nums = new int[] { 1, 3, 4, 5, 5, 1, 1 };
        System.out.println(majorityElement(nums));
    }
}