Wednesday, 24 June 2020

Power of Lambda - II

There is a very common interview question or you can say common requirement in our daily coding life we come across.

"Write a Java program to count the occurrence of each character in a string"

There are various type of logics to achieve this
  • using array
  • using Java maps etc...
But here I am going to demonstrate how it can be achieved in a smarter way using the power of lambda.
String statement = "A quick brown fox jumps over the lazy dog!";
final Map<Character, Integer> charOccurrenceMap = new HashMap<>();
statement.chars()
.forEach(ch -> charOccurrenceMap
.merge((char)ch, 1, (prevValue, value) -> prevValue + value));
System.out.println(charOccurrenceMap);
Output
{A=1,  =8, !=1, a=1, b=1, c=1, d=1, e=2, f=1, g=1, h=1, i=1, j=1, k=1, l=1, m=1, n=1, o=4, 
p=1, q=1, r=2, s=1, t=1, u=2, v=1, w=1, x=1, y=1, z=1}

Realtime Example

"Let's you have a collection of customer requests and want to count number of 
requests initiated by each account"
class CustomerRequest {
long accNo;
String reqPayload;
// some other details
public CustomerRequest(long accNo, String reqPayload) {
this.accNo = accNo;
this.reqPayload = reqPayload;
}
//getter and setter
}
public class Main {
public static void main(String[] args) {
List<CustomerRequest> requestList = generateDummyCustomerRequests();
final HashMap<Long, Integer> requestCountMap = new HashMap<>();
requestList
.stream()
.map(CustomerRequest::getAccNo)
.forEach(accNumber -> requestCountMap
.merge(accNumber, 1, (prevCount, value) -> prevCount + 1));
System.out.println(requestCountMap);
}

// this is a helper method to build dummy customer requests
private static List<CustomerRequest> generateDummyCustomerRequests() {
final ArrayList<CustomerRequest> customerRequests = new ArrayList<>();
customerRequests.add(new CustomerRequest(123, "payload 1"));
customerRequests.add(new CustomerRequest(345, "payload 2"));
customerRequests.add(new CustomerRequest(123, "payload 3"));
customerRequests.add(new CustomerRequest(456, "payload 4"));
customerRequests.add(new CustomerRequest(345, "payload 5"));
return customerRequests;
}
}
Output
{456=1, 345=2, 123=2}
Here is what java documentation of Map.merge() method says:
If the specified key is not already associated with a value or is
associated with null, associates it with the given non-null value.
Otherwise, replaces the associated value with the results of the given
remapping function, or removes if the result is {@code null}. This
method may be of use when combining multiple mapped values for a key.
For example, to either create or append a {@code String msg} to a
value mapping: map.merge(key, msg, String::concat)
How it works internally is:
V oldValue = map.get(key);
V newValue = (oldValue == null) ? value :
             remappingFunction.apply(oldValue, value);
if (newValue == null)
    map.remove(key);
else
    map.put(key, newValue);
I hope it helps to understand how powerful is Java lambda and stream API. Please start 
using in your daily coding. Please feel free to share your comment and feedback.

1 comment:

  1. Here all content so useful and helpful for beginner and experience both.This site is so amazing, This sites gives good knowledge of javaThis is very helpful for me.

    ReplyDelete