SPECIAL CASE PATTERN (Fowler)

Most of the time, we would throw an exception to handle an unexpected behavior. In some cases, if the caller code does not want to handle that error and follow a default approach, then we can use “Special Case Pattern”. Refer the below example to know how to do that.

Assume that we have class “BillingDao” contains methods to fetch the billing details of an employee. “getBillingDetails” is a method returns the billing details of an employee by his/her company name. Assume that if it does not find the billing details, then it will throw “BillingDetailsNotFoundException “. So the client code has to handle that scenario. We can refactor this code with “Special Case Pattern”


float rate = 0.0f
try {
  BillingDetails billingDetails= billingRateDao.getBillingDetails(employee.getCompany());
  rate+= billingDetails.getRate();
} catch(BillingDetailsNotFoundException e) {
  rate += getDefaultBillingRate()
}

We will create a new class “DefaultBillingDetails” which implements “BillingDetails” and we can specify the default billing details in it.
Then we can update the “BillingRateDAO” to return the instance of DefaultBillingDetails instance of throwing an exception. So the modified code will look like below.


BillingDetails billingDetails= billingRateDao.getBillingDetails(employee.getCompany());
  rate+= billingDetails.getRate();
....
.....
public class DefaultBillingDetails implements BillingDetails {
 public int getRate() {
 // return the per default rate
 }
}

Advertisements

Java 8: Stream sorted

In this post, we are going to see how we can use Stream.sorted method to sort a collection with an example.

Consider that we have Person class contains “name” and “age” fields and want to sort the list of person objects by age and then by name.

Refer the below code to know how to do that.


import com.google.common.collect.Lists;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;

public class CollectionMain {

    static class Person {
        String name;
        Integer age;

        Person(String name, Integer age) {
            this.name = name;
            this.age = age;
        }

        @Override
        public String toString() {
            return new ToStringBuilder(this, ToStringStyle.SIMPLE_STYLE)
                .append("name", name)
                .append("age", age)
                .toString();
        }

        public String getName() {
            return name;
        }


        public Integer getAge() {
            return age;
        }

    }

    private static final Comparator PERSON_COMPARATOR = Comparator.comparing(Person::getAge).thenComparing(Person::getName);

    public static void main(String[] args) {
        List persons = Lists.newArrayList(new Person("John", 32),
            new Person("Tom", 33),
            new Person("Brad", 35),
            new Person("Varma", 38),
            new Person("Andy", 33));

        System.out.println(persons
            .stream()
            .filter(p -> p.age > 32)
            .sorted(PERSON_COMPARATOR)
            .collect(Collectors.toList()));

    }
}



[Andy,33, Tom,33, Brad,35, Varma,38]

Scala – sort/sortWith/sortBy functions

In this post, we are going to see how we can use scala sort related function with examples.

Assume that we have a list of fruits and we want to sort the fruit name in different order.

Refer the below code to know how to do that.



object SortExample {


  def main(args: Array[String]): Unit = {

    val fruits = List("Water Melon", "Banana", "Carrot", "Apple", "Plums", "Orange")

    //To sort a list by ascending order
    println(fruits.sorted)

    //To sort a list by descending order
    println(fruits.sorted.reverse)

    //To sort a list by length
    println(fruits.sortWith(_.length > _.length))

    //To sort a list by length(descending)
    println(fruits.sortWith(_.length < _.length))

  }
}

The output of the above code is given below,


List(Apple, Banana, Carrot, Orange, Plums, Water Melon)
List(Water Melon, Plums, Orange, Carrot, Banana, Apple)
List(Water Melon, Banana, Carrot, Orange, Apple, Plums)
List(Apple, Plums, Banana, Carrot, Orange, Water Melon)

Now, We will see how we can use sortBy function to sort a list.

The definition of the sortBy function is given below,



def sortBy[B](f: (A) ⇒ B)(implicit ord: math.Ordering[B]): List[A]
Sorts this Seq according to the Ordering which results from transforming an implicitly given Ordering with a transformation function.


Refer the below code, where we use sortBy function to sort the employee objects list in three different ways.


object SortByExample {

  case class Employee(name: String,
                      age: Int,
                      designation: String,
                      salary: Int)

  def main(args: Array[String]): Unit = {

    val employees = List(Employee("Bala", 31, "Developer", 500000),
      Employee("John", 33, "Tester", 200000),
      Employee("Bob", 35, "Tech Lead", 300000),
      Employee("Woods", 30, "Manager", 400000),
      Employee("Robert", 30, "Tester", 200000),
      Employee("Jon", 30, "Tester", 100000),
      Employee("Paul", 26, "Sales Person", 100000),
      Employee("Jason", 25, "Sales Executive", 100000),
      Employee("Jill", 25, "Sales Executive", 200000),
      Employee("Steve", 27, "Product Owner", 500000))

    employees
      .sortBy(_.age)
      .foreach(println(_))

    employees
      .sortBy(x => (x.salary, x.age))
      .foreach(println(_))

    val orderForDesignation = Map("Product Owner" -> 0, "Manager" -> 1, "Tech Lead" -> 2, "Developer" -> 3, "Tester" -> 4)

    employees
      .sortBy(x => (orderForDesignation.get(x.designation).orElse(Some(10)), x.name))
     .foreach(println(_))

  }

}

We have Employee case class and it contains name, salary, designation and age fields and we create a list with different details, then we call sortBy function and pass the age field to sort the list by age.

The output looks like below,


Employee(Jason,25,Sales Executive,100000)
Employee(Jill,25,Sales Executive,200000)
Employee(Paul,26,Sales Person,100000)
Employee(Steve,27,Product Owner,500000)
Employee(Woods,30,Manager,400000)
Employee(Robert,30,Tester,200000)
Employee(Jon,30,Tester,100000)
Employee(Bala,31,Developer,500000)
Employee(John,33,Tester,200000)
Employee(Bob,35,Tech Lead,300000)

Now we want to sort the list by salary and then age. To do that we have to pass the salary and age fields to sortBy function in the right order.
The output looks like below,


Employee(Jason,25,Sales Executive,100000)
Employee(Paul,26,Sales Person,100000)
Employee(Jon,30,Tester,100000)
Employee(Jill,25,Sales Executive,200000)
Employee(Robert,30,Tester,200000)
Employee(John,33,Tester,200000)
Employee(Bob,35,Tech Lead,300000)
Employee(Woods,30,Manager,400000)
Employee(Steve,27,Product Owner,500000)
Employee(Bala,31,Developer,500000)


Now, we want to sort it by designation but follow a different order. The order should be like this “Product Owner -> Manager -> Tech Lead -> Developer -> Tester.

To do that we have to maintain a Map contains designation to order mapping and this Map to be used in sortBy function and we also use name as secondary sorting.

The output looks like below,


Employee(Steve,27,Product Owner,500000)
Employee(Woods,30,Manager,400000)
Employee(Bob,35,Tech Lead,300000)
Employee(Bala,31,Developer,500000)
Employee(John,33,Tester,200000)
Employee(Jon,30,Tester,100000)
Employee(Robert,30,Tester,200000)
Employee(Jason,25,Sales Executive,100000)
Employee(Jill,25,Sales Executive,200000)
Employee(Paul,26,Sales Person,100000)


Java 8 – groupingBy Collector

In this post, we will see how to use groupingBy collector with an example.

Consider that we have a person class and it contains id, age, fullname and city fields. We have a list of person objects and we want to group by age. Lets see how we can do that with an example.

Here is the Person class.

Person.java



import org.apache.commons.lang.builder.EqualsBuilder;
import org.apache.commons.lang.builder.HashCodeBuilder;
import org.apache.commons.lang.builder.ToStringBuilder;
import org.apache.commons.lang.builder.ToStringStyle;

public class Person {

    private String id;

    private int age;

    private String fullName;

    private String city;

    public Person(String id, int age, String fullName, String city){
        this.id = id;
        this.age = age;
        this.fullName = fullName;
        this.city = city;
    }

    public String getId() {
        return id;
    }

    public int getAge() {
        return age;
    }

    public String getFullName() {
        return fullName;
    }

    public String getCity() {
        return city;
    }

    @Override
    public String toString() {
        return ToStringBuilder.reflectionToString(this, ToStringStyle.SIMPLE_STYLE);

    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;

        if (o == null || getClass() != o.getClass()) return false;

        Person person = (Person) o;

        return new EqualsBuilder()
                .append(age, person.age)
                .append(id, person.id)
                .append(fullName, person.fullName)
                .isEquals();
    }

    @Override
    public int hashCode() {
        return new HashCodeBuilder(17, 37)
                .append(id)
                .append(age)
                .append(fullName)
                .toHashCode();
    }
}


To group the person list by age, the code is given below,


 //Group the person list by age
        Map<Integer, List> personListByAge = personList
                .stream()
                .collect(groupingBy(Person :: getAge));

The output will look like below,


{36=[id1,36,Peter,columbus, id3,36,Alex,hopkins], 37=[id2,37,John,columbus], 30=[id4,30,Ram,new york, id5,30,Bala,houston, id5,30,Bala,houston]}

By default, the groupingby collector returns a map with value as list of person objects. If you want to remove duplicates and collect the objects as set, then we have to pass the downstream parameter such as toSet().


  //Group the person list by age and remove duplicates
        Map<Integer, Set> personListByAgeNoDuplicates = personList
                .stream()
                .collect(groupingBy(Person :: getAge, toSet()));

The output will look like below,


{36=[id1,36,Peter,columbus, id3,36,Alex,hopkins], 37=[id2,37,John,columbus], 30=[id5,30,Bala,houston, id4,30,Ram,new york]}


If you want to group a person list by age and then again group the results by city, then we have to pass the groupingby(city) collector inside of the first groupingby.

Note that this will return a Map and an inner map which contains the group by field as key and the list of person objects.


 //Group the person list by age and then group the result of the first group by city

        Map<Integer, Map<String, List>> personListByAgeAndCity = personList
                .stream()
                .collect(groupingBy(Person :: getAge, groupingBy(Person :: getCity)));



The output will look like below,


{36={hopkins=[id3,36,Alex,hopkins], columbus=[id1,36,Peter,columbus]}, 37={columbus=[id2,37,John,columbus]}, 30={houston=[id5,30,Bala,houston, id5,30,Bala,houston], new york=[id4,30,Ram,new york]}}


The code is given below,

GroupByMain.java



import com.google.common.collect.Lists;

import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Set;

import static java.util.stream.Collectors.groupingBy;
import static java.util.stream.Collectors.toSet;

public class GroupByMain {

    public static void main(String[] args) {

        Comparator comparator = Comparator.comparing(Person :: getAge);
        Person person1 = new Person("id1", 36, "Peter","columbus" );
        Person person2 = new Person("id2", 37, "John", "columbus");
        Person person3 = new Person("id3", 36, "Alex", "hopkins");
        Person person4 = new Person("id4", 30, "Ram", "new york");
        Person person5 = new Person("id5", 30, "Bala", "houston");
        Person person6 = new Person("id5", 30, "Bala", "houston");

        List personList = Lists.newArrayList(person1, person2, person3, person4, person5, person6);

        //Group the person list by age
        Map<Integer, List> personListByAge = personList
                .stream()
                .collect(groupingBy(Person :: getAge));

        System.out.println(personListByAge);

        //Group the person list by age and remove duplicates
        Map<Integer, Set> personListByAgeNoDuplicates = personList
                .stream()
                .collect(groupingBy(Person :: getAge, toSet()));

        System.out.println(personListByAgeNoDuplicates);

        //Group the person list by age and then group the result of the first group by city

        Map<Integer, Map<String, List>> personListByAgeAndCity = personList
                .stream()
                .collect(groupingBy(Person :: getAge, groupingBy(Person :: getCity)));

        System.out.println(personListByAgeAndCity);

    }
}

Scala – Currying function

A Currying function is a function which has multiple parameter list but can be called with few arguments and yields another function which accepts the missing parameters as its arguments.

Consider that we have a list names and want to add prefix and suffix to each name. Let’s see how we can do this with a curried function.

Scala-Currying

In the above example, the function “addPrefixSuffix” is a curried function which accepts three arguments such as prefix, suffix and name. So in the “main” function, I pass only two arguments to this so it will yield another function to accept the missing parameter(name).

Scala – Higher Order Function

Higher order Function is a functional programming principle that takes other functions as arguments or returns a function as output.

In this post, we are going to see that with an example.

Assume that we have a list of string and want to iterate it and append and prepend $ symbol to each value and collect the modified values as list. Refer the below example to know how we can do that with the higher-order function principle.

Scala Higher order function

In the above example, “modifyList” is a higher order function as it takes the “format” function as an argument. The “format” function is performing the append and prepend operation to each value. This example is pretty simple one and we can do it without a higher order function.

Java: Stream.Reduce

In this post, we are going to see how we can use Stream reduce operation on a list with an example.

Stream.Reduce()

Stream.Reduce() is a general purpose reduction operation. We can use this operation to process a list and find out the max, min and average value. It’s like applying to a list of values and get a single result value.

The syntax is given below


T reduce(T identity, BinaryOperator accumulator)

Here identity is the initial value and accumulator is a function for combining values.

reduce

In the above example, I have a list of string and want to find out the long string in it. I have used reduce operation to find it out.

Let’s see another example. Assume that we want to process a list and modify the value of it and then reduce the value into a single value. Refer the below example to know how we can achieve this with reduce operation.

reduce-modify-list