Friday, February 5, 2021

Java 8 Parallel Streams - Custom Thread Pools Examples

1. Introduction


In this tutorial, You'll learn how to create custom thread pools in Java 8 for bulk data processing with parallel streams powerful API.

Parallel Stream can work well in concurrent environments and these are improved versions of streams performance at the cost of multi-threading overhead.

The main focus in this article is to look at one of the biggest limitations of Stream API and Examples on how can you use the Parallel Streams with the custom thread pools.

Custom Thread Pools In Java 8 Parallel Streams

Thursday, February 4, 2021

Java 8 GroupingBy - Group by Modifying Map Value Type

1. Overview

In this tutorial, We will learn how to modify the Map value return type for the java 8 Grouping By operation.

In the previous article, we have seen how to perform Group by operation in java 8 with count, sum actions.

After calling the Collectors.groupingby() method it returns the Map<K, V> key and value

In some of the cases you may need to return the key type as List or Set.

Java 8 GroupingBy - Group by Modifying Map Value Type


2. Modify Map Value Type to List For GroupingBy Result

In the below program, we are trying to first find the count of each string from list. Returned map key type is String, value type is Long. 

Next, Let us see how to convert Long to List<String> to take all the values into List instead of getting the count.


package com.javaprogramto.java8.collectors.groupby;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

public class GroupingByModifyValueType {

	public static void main(String[] args) {

		// Creating List and adding duplicate values.
		List<String> strings = new ArrayList<>();

		strings.add("Hello");
		strings.add("Ram");
		strings.add("Hello");
		strings.add("Sam");
		strings.add("Hello");
		strings.add("Yam");
		strings.add("Hello");
		strings.add("Raj");
		strings.add("Hello");
		strings.add("Raj");

		// Grouping by based on the count
		// Map type - <String, Long>
		Map<String, Long> countMap = strings.stream()
				.collect(Collectors.groupingBy(Function.identity(), Collectors.counting()));

		// printing the count of each string.
		System.out.println("Count : " + countMap);

		// Grouping by - change the Map value type
		// Map type - <String, List<String>>
		Map<String, List<String>> mapValueType = strings.stream()
				.collect(Collectors.groupingBy(Function.identity(), Collectors.toList()));

		System.out.println("List group by : " + mapValueType);
	}
}
 

Output:

Count : {Yam=1, Hello=5, Raj=2, Sam=1, Ram=1}
List group by : {Yam=[Yam], Hello=[Hello, Hello, Hello, Hello, Hello], Raj=[Raj, Raj], Sam=[Sam], Ram=[Ram]}
 

3. Modify Map Value Type to Set For GroupingBy Result

From the above output we are seeing the duplicate values in the list, Next, we want to remove the duplicates from it. So, we need to instruct to the groupingBy() method use Set instead of List.


package com.javaprogramto.java8.collectors.groupby;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Function;
import java.util.stream.Collectors;

public class GroupingByModifyValueTypeSet {

	public static void main(String[] args) {

		// Creating List and adding duplicate values.
		List<String> strings = new ArrayList<>();

		strings.add("Hello");
		strings.add("Ram");
		strings.add("Hello");
		strings.add("Sam");
		strings.add("Hello");
		strings.add("Yam");
		strings.add("Hello");
		strings.add("Raj");
		strings.add("Hello");
		strings.add("Raj");

		// Grouping by - change the Map value type
		// Map type - <String, Set<String>>
		Map<String, Set<String>> mapValueType = strings.stream()
				.collect(Collectors.groupingBy(Function.identity(), Collectors.toSet()));

		System.out.println("Set group by : " + mapValueType);
	}
}
 

Output:

Set group by : {Yam=[Yam], Hello=[Hello], Raj=[Raj], Sam=[Sam], Ram=[Ram]}
 

4. Modify Map value type to Custom Objects List or Set

As of now, we have shown example to work with the simple types. Now, Let us create a Trade class with name, quantity and purchased amount.

Let us get the group by stock name and its quantities from all stocks.

Trade.java

package com.javaprogramto.java8.collectors.groupby;

public class Trade {

	private String name;
	private int quantity;
	private double price;

	public Trade(String name, int quantity) {
		this.name = name;
		this.quantity = quantity;
	}

	public Trade(String name, int quantity, double price) {
		super();
		this.name = name;
		this.quantity = quantity;
		this.price = price;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getQuantity() {
		return quantity;
	}

	public void setQuantity(int quantity) {
		this.quantity = quantity;
	}

	public double getPrice() {
		return price;
	}

	public void setPrice(double price) {
		this.price = price;
	}

	@Override
	public String toString() {
		return "Stock [ " + name + ", " + quantity + ", " + price + "]";
	}
}
 

Group By with trade name and List of quantities.

Normally, we perform the count, summing, min or max but now we need to collect the a value from Trade object into List.

Below example will modify the grouping by Map value type to List<Integer>.


package com.javaprogramto.java8.collectors.groupby;

import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

public class GroupingByModifyCustomObjects {

	public static void main(String[] args) {

		// Creating List and adding duplicate values.
		List<Trade> Trades = new ArrayList<>();

		Trades.add(new Trade("JP Morgan", 10));
		Trades.add(new Trade("ICICI", 20));
		Trades.add(new Trade("HDFC", 30));
		Trades.add(new Trade("ICICI", 40));
		Trades.add(new Trade("JP Morgan", 50));
		Trades.add(new Trade("JP Morgan", 60));

		// group by - Trade name + List<Integer> list of Quantity's

		Map<String, List<Integer>> noOfTradesByName 
			= Trades
				.stream()
				.collect(Collectors
				.groupingBy(Trade::getName, 
						Collectors.mapping(Trade::getQuantity, Collectors.toList())));

		// printing the count of each string.
		System.out.println("No of stocks by name in each trade: " + noOfTradesByName);
	}
}
 

Output:

No of stocks by name in each trade: {ICICI=[20, 40], HDFC=[30], JP Morgan=[10, 50, 60]}
 

We can change the type to Set using toSet() method also.


5. Conclusion

In this article, We have seen how to modify the Map value type for the group by result in java 8.

GitHub

How to convert List to Map in Java 8?

Wednesday, February 3, 2021

Sorting ArrayList in Reverse or Descending Order in Java 8

1. Overview

In this article, We will learn how to sort ArrayList in descending order in java. Sometimes this is referred as collections reverse or decreasing order.

To get the list in the reverse order, we need to use Collections.reverseOrder() and Collections.sort() methods together.

Sorting ArrayList in Reverse or Descending Order in Java 8


2.  Sort ArrayList In Descending order using Collections.reverseOrder()

We have already shown how to sort list in ascending order using Collections.sort() method.

In the below examples, we are using the built-in comparator from the reverseOrder() method and passing it to the Collections.sort() method.


package com.javaprogramto.java8.arraylist;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;

public class ArrayListReverseOrder1 {

	public static void main(String[] args) {

		// Creating ArrayList
		List<Integer> numbersList = new ArrayList<>();

		// Adding values to List
		numbersList.add(150);
		numbersList.add(50);
		numbersList.add(250);
		numbersList.add(500);
		numbersList.add(350);

		// printing before sorting
		System.out.println("Before sorting : " + numbersList);

		// Getting the descending order comparator
		Comparator<Integer> reverseComparator = Collections.reverseOrder();

		// Sorting with the reverse comparator with sort() method.
		// sort() method internally uses this comparator to sort in the descending order
		Collections.sort(numbersList, reverseComparator);

		// printing the final list after reverse order sorting. Original list only
		// sorted.
		System.out.println("After sorting : " + numbersList);
	}
}

 

Output:

Before sorting : [150, 50, 250, 500, 350]
After sorting : [500, 350, 250, 150, 50]
 

3.  Sort ArrayList In Descending order using Collections.reverse()

Next, look at the another way to sort the arraylist in descending order using two methods as below.

Collections.sort(arraylist); --> first sorts the list in the ascending order

Collections.reverse(arraylist); --> Next, reverse the sorted list.

Example:


import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

public class ArrayListReverseOrder2 {

	public static void main(String[] args) {

		// Creating ArrayList
		List<Integer> numbersList = new ArrayList<>();

		// Adding values to List
		numbersList.add(150);
		numbersList.add(50);
		numbersList.add(250);
		numbersList.add(500);
		numbersList.add(350);

		// printing before sorting
		System.out.println("Before sorting : " + numbersList);

		// sorting the list in the ascending order
		Collections.sort(numbersList);

		// reversing the sorted list into descending order
		Collections.reverse(numbersList);

		// printing the final list after reverse order sorting. Original list only
		// sorted.
		System.out.println("After sorting : " + numbersList);

	}

}
 

This program also produces the same output as in the section 2.

4. Java 8 Sort ArrayList Descending Order

Sorting list in reverse order is pretty easy from stream.sorted(Collections.reverseOrder()) in java 8 api.

We can use parallelStream() method to work efficiently with larger data volumes.

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;

public class ArrayListReverseOrder2 {

	public static void main(String[] args) {

		// Creating ArrayList
		List<Integer> numbersList = new ArrayList<>();

		// Adding values to List
		numbersList.add(150);
		numbersList.add(50);
		numbersList.add(250);
		numbersList.add(500);
		numbersList.add(350);

		// printing before sorting
		System.out.println("Before sorting : " + numbersList);

		List<Integer> descendingList = numbersList.stream()
				.sorted(Collections.reverseOrder())
				.collect(Collectors.toList());

		// printing the final list after reverse order sorting. Original list only
		// sorted.
		System.out.println("After sorting : " + descendingList);
	}
}
 


5. Conclusion

In this article, We have seen how to sort the ArrayList in descending order in older and new java 8 streams.

GitHub

How to sort Map by values in java 8?

Tuesday, February 2, 2021

Sorting HashMap by Value in Java 8 in Ascending and Descending Order

1. Overview

In this tutorial, We will learn how to sort HashMap by value using java 8 API

Most of the times, we do sort the hashmap based on the keys but not rather than its values. There are some scenarios for example HashMap stores the name as key and age as value. Now, we want to sort the customers based on the their value age.

Let us explore the techniques to do sort the values of hashmap in java 8.

Sorting HashMap by Value in Java 8 in Ascending and Descending Order



2. Sort HashMap By Value Java 8 - Ascending Order


Below example is to sort the map on values using Stream.sort() and Entry.comparingByValue() methods.

Entry.comparingByValue() does sorting in the ascending order.

Java 8 example:


package com.javaprogramto.collections.hashmap;

import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.stream.Collectors;

public class SortHashMapByValues {

	public static void main(String[] args) {

		// creating HashMap
		Map<String, Integer> namesAges = new HashMap<>();

		// storing the values
		namesAges.put("Hari", 35);
		namesAges.put("Jhon", 30);
		namesAges.put("Jakey", 50);
		namesAges.put("kane", 45);

		Map<String, Integer> sortByValueMap = namesAges.entrySet().stream().sorted(Entry.comparingByValue())
				.collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue(),
						(entry1, entry2) -> entry2, LinkedHashMap::new));

		System.out.println("HashMap before sorting by value - " + namesAges);
		System.out.println("HashMap after sorting by value - " + sortByValueMap);
	}

}
 
Output:
HashMap before sorting by value - {Hari=35, Jakey=50, Jhon=30, kane=45}
HashMap after sorting by value - {Jhon=30, Hari=35, kane=45, Jakey=50}
 
From the output, you can observe that new map is sorted based on the customer ages.

If you do not understand this java 8 lambda and stream operations, do not worry. I will explain you step by step and breaking down into separate statements.

Read the written comments for each line in the code and this will help you out for better understanding.

Once you are clear, you can write the code in single line.

package com.javaprogramto.collections.hashmap;

import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class SortHashMapByValues {

	public static void main(String[] args) {

		// creating HashMap
		Map<String, Integer> namesAges = new HashMap<>();

		// storing the values
		namesAges.put("Hari", 35);
		namesAges.put("Jhon", 30);
		namesAges.put("Jakey", 50);
		namesAges.put("kane", 45);

		// Step 1: Getting the entry set from map
		Set<Map.Entry<String, Integer>> entrySet = namesAges.entrySet();

		// Step 2: converting entry set to stream
		Stream<Entry<String, Integer>> stream = entrySet.stream();

		// Step 3: comparator to sort using values.
		Comparator<Map.Entry<String, Integer>> comparator = Entry.comparingByValue();

		// Step 4: sorting the stream using comparator created in above step.
		Stream<Entry<String, Integer>> sortedStream = stream.sorted(comparator);

		// Step 5: Getting the each key and value from entry object from above stream.
		// Finally, adding each entry to the LinkedHashMap.
		// LinkedHashMap is used to preserve the insertion order. If you do not collect
		// object into LinkedHashMap then final sorted map looks like same as the
		// original map before sorting.
		Collector<Entry<String, Integer>, ?, Map<String, Integer>> toMap = Collectors.toMap(entry -> entry.getKey(),
				entry -> entry.getValue(), (entry1, entry2) -> entry2, LinkedHashMap::new);

		// Step 6: Collecting the sorted stream into Map.
		Map<String, Integer> finalSortedByValueMap = sortedStream.collect(toMap);

		// printing
		System.out.println("HashMap before sorting by value - " + namesAges);
		System.out.println("HashMap after sorting by value - " + finalSortedByValueMap);
	}
}

 
This program also generates the output as same as above single line stream example.

Note:
When you divide the stream into multiple lines, JVM does not execute the code immediately after executing the each line. All stream operations are invoked if and if only the terminal operations are called such as collect(), max(), min() methods.

3. Sort HashMap By Value Java 8 - Descending Order


Next, Learn how to sort the HashMap by values in Descending order using Collections.reverseOrder() method.

package com.javaprogramto.collections.hashmap;

import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.stream.Collector;
import java.util.stream.Collectors;
import java.util.stream.Stream;

public class SortHashMapByValues {

	public static void main(String[] args) {

		// creating HashMap
		Map<String, Integer> namesAges = new HashMap<>();

		// storing the values
		namesAges.put("Hari", 35);
		namesAges.put("Jhon", 30);
		namesAges.put("Jakey", 50);
		namesAges.put("kane", 45);

		Map<String, Integer> sortedMapInDescending = namesAges.entrySet()
			.stream()
			.sorted(Collections.reverseOrder(Entry.comparingByValue()))
			.collect(Collectors.toMap(entry -> entry.getKey(), entry -> entry.getValue(),
					(entry1, entry2) -> entry2, LinkedHashMap::new));
		
		// printing
		System.out.println("HashMap before sorting by value - " + namesAges);
		System.out.println("HashMap after sorting by value in descending order- " + sortedMapInDescending);
	}
}
 
Output:
HashMap before sorting by value - {Hari=35, Jakey=50, Jhon=30, kane=45}
HashMap after sorting by value in descending order- {Jakey=50, kane=45, Hari=35, Jhon=30}
 

4. HashMap Sorting using Method Reference


Example program using java 8 method ref concept.

// sorting using method ref
// Descending
Map<String, Integer> sortedMapInDescendingOrder = namesAges.entrySet()
.stream()
.sorted(Collections.reverseOrder(Entry.comparingByValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
		(entry1, entry2) -> entry2, LinkedHashMap::new));

// Ascending
Map<String, Integer> sortedMapIAscendingOrder = namesAges.entrySet()
.stream()
.sorted(Collections.reverseOrder(Entry.comparingByValue()))
.collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue,
	(entry1, entry2) -> entry2, LinkedHashMap::new));

 


5. Conclusion


In this article, We have seen how to sort HashMap by Value in Java 8 in descending or ascending order.

And alos seen using Method Reference concept.


Java String Programs - Programming Examples for Interviews (2021)

1. Overview

In this article, We will see what are the String programs frequently asked in the java interviews.
All may be asked in the face to face or telephonic technical rounds. Every java programmer must know all of these questions.

Some of these will be tricky but easy if you understand clearly.

Java String Programs - Programming Examples for Interviews


2. Java String Programs


Next, Look at the java string based programs with example codes.

2.1 How to split the string with a delimiter


public class StringSplitExample1 {

    public static void main(String[] args) {
        String str = "java@program@to.com";

        String[] splitArray = str.split("@");

        for(String value : splitArray){
            System.out.println(value);
        }
    }
}



2.2 How to get codepoints for a String?


String str = "Code Points as Stream";
System.out.println("Input string value : "+str);

IntStream intStream = str.codePoints();
System.out.println("Printing each char from string as ASCII value");

intStream.forEach(value -> System.out.print(value+" "));

Output:
Input string value : Code Points as Stream
Printing each char from string as ASCII value
67 111 100 101 32 80 111 105 110 116 115 32 97 115 32 83 116 114 101 97 109 

2.3 How to remove the Zero's from String?


String str = "Digit ZERO 0 is not considered in input name. So removing all Zero's 00000000";
IntStream intStream = str.codePoints();

String zeroRemovedString = intStream.filter(ch -> ch != 48)
         .collect(StringBuilder::new, StringBuilder::appendCodePoint, StringBuilder::append)
         .toString();


Output:
Digit ZERO  is not considered in input name. So removing all Zero's


2.4 How to check the string is palindrome or not?


public class StringPalindromeAppend {

    public static void main(String[] args) {
		
        String input1 = "civic";
		
        StringBuffer buffer = new StringBuffer();

        for (int i = input1.length() - 1; i >= 0; i--) {
            buffer.append(input.charAt(i));
        }
		
        String reversedString1 = buffer.toString();

        if (input1.equals(reversedString1)) {
            System.out.println(input1 + " is a palindrome");
        } else {
            System.out.println(input1 + " is not a palindrome");
        }

    }
}



2.5 How to check the String Palindrome recursively ?


public static boolean isPalindrome(String s) {

	// if the string has one or zero characters then recursive call is stopped.
	if (s.length() == 0 || s.length() == 1)
		return true;

	// checking the first and last character of the string. if equals then call the
	// same function with substring from index 1 to length -1. Because substring
	// excludes the endIndex.
	// if these two values are not same then string is not Palindrome so this
	// returns false.
	if (s.charAt(0) == s.charAt(s.length() - 1))
		return isPalindrome(s.substring(1, s.length() - 1));

	// this statment is executed if and if only first and last character of string
	// at any time is not equal.
	return false;
}



2.6 How to count vowels and consonants for String ?


String input = "This is using Collectors api methods !!!!";

List<Character> vowels = new ArrayList<>(Arrays.asList('a', 'e', 'i', 'o', 'u'));
input = input.toLowerCase();

IntStream stream = input.chars();

Map<Boolean, Long> finalResultMap = stream.mapToObj(ch -> (char) ch).filter(ch -> (ch >= 'a' && ch <= 'z'))
        .collect(Collectors.partitioningBy(ch -> vowels.contains(ch), Collectors.counting()));

System.out.println("Total count of vowels : " + finalResultMap.get(new Boolean(true)));
System.out.println("Total count of consonants : " + finalResultMap.get(new Boolean(false)));

Output:

Total count of vowels : 11
Total count of consonants : 20



2.7 How to compare different String objects with != operator ?


String status = new String("Failure");

if (status.intern() != "Failure") {
	System.out.println("Valid age");
} else {
	System.out.println("Invalid age");
}

Use intern() method to get the original string from String constant pool for string contents comparision with != operator.


2.8 How to find the first non repeated character from String ?


public static String firstNonRepeatedCharacterJava8(String input) {

  Map chars = input.codePoints().mapToObj(cp -> cp)
    .collect(Collectors.groupingBy(Function.identity(), LinkedHashMap::new, Collectors.counting()));

  int pos = chars.entrySet().stream().filter(e -> e.getValue() == 1L).findFirst().map(Map.Entry::getKey)
    .orElse(Integer.valueOf(Character.MIN_VALUE));

  return String.valueOf(Character.toChars(pos));
 }



2.9 How to convert String to Date in java 8?


String isoDateInString = "May 30, 2020";

DateTimeFormatter customFormatter = DateTimeFormatter.ofPattern("MMM d, yyyy");

LocalDate date = LocalDate.parse(isoDateInString, customFormatter);

System.out.println("Locale Date : "+date); // 2020-05-30


2.10 How to convert String to Int ?


Conversion from String to integer can be done using following techniques.

Integer.parseInt()
Integer.valueOf()
Integer Constructor
DecimalFormat




2.11 How to check String contains only digits ?


public boolean checkStringOnlyDigitsIsDigit(String input) {

 IntStream intStream = input.chars();
 boolean isMatched = intStream.anyMatch(ch -> Character.isDigit(ch));

 return isMatched;

}
 


2.12 How to reverse the words in String?


 public String reverseWordsWithStringBuilder(String input) {

  // step 1: converting input string into stream.
  Stream-<String-> stream = pattern.splitAsStream(input);

  // step 2: reversing each word.
  Stream->StringBuilder-> intermeidateOutput = stream.map(word -> new StringBuilder(word).reverse());

  // step 3: merging all reversed words with empty space " "
  String reversedInput = intermeidateOutput.collect(Collectors.joining(" "));

  return reversedInput;
 }
 


3. Conclusion


In this article, we have seen the most used java string programs with examples. All questions are already explained in different ways in the previous article.