Showing posts with label Java 8. Show all posts
Showing posts with label Java 8. Show all posts

Monday, June 17, 2024

Filter a Map by Keys and Values using Java Stream

Filter a Map by Keys and Values using Java Stream

Discover how to filter a Map by keys, values, or both using Java 8’s Stream API with the filter() and collect() methods. These straightforward code snippets demonstrate how to create generic functions for filtering any Map based on its keys or values. Let us delve into understanding how to filter a map by keys and values.

1. Introduction


In Java, a Map is a part of the Java Collections Framework and is used to store key-value pairs. Each key in a map is unique, and each key maps to exactly one value. Maps provide a way to look up values based on their corresponding keys, making data retrieval efficient.

Common implementations of the Map interface include HashMap, TreeMap, and LinkedHashMap. These implementations differ in terms of ordering, performance, and underlying data structures. For instance, HashMap offers average constant-time performance for most operations like get and put, while TreeMap maintains a sorted order of keys.

Maps are versatile and widely used in Java applications to manage and manipulate collections of data where relationships between keys and values are important.

1.1 Filter a Map by Keys


To filter a map by keys, we can use the Stream API to process the entries and collect them back into a map. Here is an example:

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
 
public class FilterMapByKey {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("apple", 10);
        map.put("banana", 20);
        map.put("cherry", 30);
        map.put("date", 40);
 
        // Filter the map to keep only keys starting with 'a'
        Map filteredMap = map.entrySet()
            .stream()
            .filter(entry -> entry.getKey().startsWith("a"))
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
 
        System.out.println(filteredMap);
    }
}

Here’s a code breakdown:

  • map.entrySet().stream() – Creates a stream from the map’s entry set.
  • filter(entry -> entry.getKey().startsWith("a")) – Filters the entries where the key starts with ‘a’.
  • collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)) – Collects the filtered entries back into a map.

The code output is:

{apple=10}

1.2 Filter a Map by Values


Filtering a map by values follows a similar approach. Here is an example:

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
 
public class FilterMapByValue {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("apple", 10);
        map.put("banana", 20);
        map.put("cherry", 30);
        map.put("date", 40);
 
        // Filter the map to keep only values greater than 20
        Map filteredMap = map.entrySet()
            .stream()
            .filter(entry -> entry.getValue() > 20)
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
 
        System.out.println(filteredMap);
    }
}

Here’s a code breakdown:

  • map.entrySet().stream() – Creates a stream from the map’s entry set.
  • filter(entry -> entry.getValue() > 20) – Filters the entries where the value is greater than 20.
  • collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)) – Collects the filtered entries back into a map.

The code output is:

{date=40, cherry=30}

1.3 Filter a Map by Keys and Values, Both


Sometimes, you may need to filter a map by both keys and values. Here is how you can do that:

import java.util.HashMap;
import java.util.Map;
import java.util.stream.Collectors;
 
public class FilterMapByKeyAndValue {
    public static void main(String[] args) {
        Map map = new HashMap();
        map.put("apple", 10);
        map.put("banana", 20);
        map.put("cherry", 30);
        map.put("date", 40);
 
        // Filter the map to keep only keys starting with 'c' and values greater than 20
        Map filteredMap = map.entrySet()
            .stream()
            .filter(entry -> entry.getKey().startsWith("c") && entry.getValue() > 20)
            .collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue));
 
        System.out.println(filteredMap);
    }
}

Here’s a code breakdown:

  • map.entrySet().stream() – Creates a stream from the map’s entry set.
  • filter(entry -> entry.getKey().startsWith("c") && entry.getValue() > 20) – Filters the entries where the key starts with ‘c’ and the value is greater than 20.
  • collect(Collectors.toMap(Map.Entry::getKey, Map.Entry::getValue)) – Collects the filtered entries back into a map.

The code output is:

{cherry=30}

Using the Stream API in Java 8 and later versions, filtering maps by keys, values, or both becomes a clean and efficient process. The examples provided demonstrate how to perform these operations effectively.

2. Conclusion


In conclusion, filtering maps by keys, values, or both in Java can be efficiently accomplished using the Stream API introduced in Java 8. By leveraging the power of streams, developers can create concise and readable code to handle these common tasks. Whether you need to filter entries based on specific key patterns, value ranges, or a combination of both, the examples provided demonstrate the flexibility and ease with which these operations can be performed. This approach not only enhances code readability but also ensures that operations on collections are both functional and expressive.

Source: javacodegeeks.com

Friday, June 7, 2024

Gson Support for Java 8 Date-Time Types

Gson Support for Java 8 Date-Time Types

Java 8 introduced a robust date and time API with classes such as LocalDate, LocalDateTime, and ZonedDateTime. These classes provide an improved way to handle dates and times compared to the legacy java.util.Date and java.util.Calendar classes. However, by default, Gson does not support these new date-time types. This lack of support can lead to issues when trying to serialize and deserialize these types to and from JSON. This article will demonstrate how to create these custom serializers and deserializers for LocalDate, LocalDateTime, and ZonedDateTime.

1. Set Up Gson


To use Gson, first, ensure the library is included in the project. If using Maven, add the following dependency to the pom.xml:

<dependency>
    <groupId>com.google.code.gson</groupId>
    <artifactId>gson</artifactId>
    <version>2.11.0</version>
</dependency>

2. Example Problem


Consider a simple Java class containing a LocalDate field:

Person.java

public class Person {
    private String name;
    private LocalDate birthDate;
 
    public Person(String name, LocalDate birthDate) {
        this.name = name;
        this.birthDate = birthDate;
    }
 
    // Getters and setters omitted for brevity
}

Now, let’s try to serialize an instance of this Person class using default Gson:

DefaultGsonExample.java

public class DefaultGsonExample {
 
    public static void main(String[] args) {
         
        Person person = new Person("John Doe", LocalDate.of(2022, 10, 1));
        Gson gson = new Gson();
        String json = gson.toJson(person);
        System.out.println("Serialized JSON: " + json);
    }
}

Output is:

WARNING: An illegal reflective access operation has occurred
WARNING: Illegal reflective access by com.google.gson.internal.reflect.ReflectionHelper (file:/Users/omozegieaziegbe/.m2/repository/com/google/code/gson/gson/2.10.1/gson-2.10.1.jar) to field java.time.LocalDate.year
WARNING: Please consider reporting this to the maintainers of com.google.gson.internal.reflect.ReflectionHelper
WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations
WARNING: All illegal access operations will be denied in a future release
Serialized JSON: {"name":"John Doe","birthDate":{"year":2022,"month":10,"day":1}}

As seen, the birthDate field is not properly serialized. Now let’s try to deserialize a JSON string back to a Person object:

DefaultGsonExample.java

public class DefaultGsonExample {
 
    public static void main(String[] args) {
        String json = "{\"name\":\"John Doe\",\"birthDate\":\"1990-01-01\"}";
        Gson gson = new Gson();
        Person person = gson.fromJson(json, Person.class);
        System.out.println("Deserialized Person: " + person.getBirthDate());
    }
}

Output is:

com.google.gson.JsonSyntaxException: java.lang.IllegalStateException: Expected BEGIN_OBJECT but was STRING at line 1 column 33 path $.birthDate
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read (ReflectiveTypeAdapterFactory.java:397)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$1.readIntoField (ReflectiveTypeAdapterFactory.java:212)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$FieldReflectionAdapter.readField (ReflectiveTypeAdapterFactory.java:433)
    at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.read (ReflectiveTypeAdapterFactory.java:393)
    at com.google.gson.Gson.fromJson (Gson.java:1227)
    at com.google.gson.Gson.fromJson (Gson.java:1137)
    at com.google.gson.Gson.fromJson (Gson.java:1047)
    at com.google.gson.Gson.fromJson (Gson.java:982)
    at com.jcg.defaultjsonexample.DefaultGsonExample.main (DefaultGsonExample.java:18)
    at org.codehaus.mojo.exec.ExecJavaMojo$1.run (ExecJavaMojo.java:279)
    at java.lang.Thread.run (Thread.java:834)

The deserialization fails with a JsonSyntaxException, indicating that Gson expected a JSON object but encountered a string instead. This occurs because Gson does not know how to handle the LocalDate type, resulting in a mismatch between the expected and actual JSON structures.

3. Solution: Custom Serializers and Deserializers


To resolve this issue, we need to create custom serializers and deserializers for Java 8 date-time types and register them with Gson. These custom adapters convert LocalDateTime instances to JSON strings and vice versa. This is crucial because LocalDateTime is not natively supported by Gson, and attempting to serialize or deserialize LocalDateTime objects without custom adapters will result in errors or incorrect data representation.

3.1 LocalDate Serializer and Deserializer

We will create a class for handling LocalDate type in Gson.

LocalDateAdapter.java

import com.google.gson.JsonDeserializationContext;
import com.google.gson.JsonDeserializer;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonParseException;
import com.google.gson.JsonSerializationContext;
 
import java.lang.reflect.Type;
import java.time.LocalDate;
import java.time.format.DateTimeFormatter;
 
public class LocalDateAdapter implements JsonSerializer<LocalDate>, JsonDeserializer<LocalDate> {
 
    private static final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE;
 
    @Override
    public JsonElement serialize(LocalDate src, Type typeOfSrc, JsonSerializationContext context) {
        return new JsonPrimitive(src.format(formatter));
    }
 
    @Override
    public LocalDate deserialize(JsonElement json, Type typeOfT, JsonDeserializationContext context) throws JsonParseException {
        return LocalDate.parse(json.getAsString(), formatter);
    }
}

3.1.1 Register LocalDateAdapter with Gson

With the custom serializer and deserializer LocalDateAdapter ready, we need to register it with a Gson instance.

CustomDateTimeExample.java

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.time.LocalDate;
 
public class CustomDateTimeExample {
 
    public static void main(String[] args) {
        Gson gson = new GsonBuilder()
                .registerTypeAdapter(LocalDate.class, new LocalDateAdapter())
                .create();
 
        Person person = new Person("John Doe", LocalDate.of(2022, 10, 1));    
         
        // Serialize
        String json = gson.toJson(person);
        System.out.println("Serialized Person with LocalDate: " + json);
         
        //Deserialize
        Person deserializedPerson = gson.fromJson(json, Person.class);
        System.out.println("Deserialized Person with LocalDate: " + deserializedPerson);
    }
 
}

The program output is:

Serialized Person with LocalDate: {"name":"John Doe","birthDate":"2022-10-01"}
Deserialized Person with LocalDate: Person(name=John Doe, birthDate=2022-10-01)
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS

Output from using custom serializer and deserializer for gson support with Java 8 local time

3.2 LocalDateTime Serializer and Deserializer

Create a LocalDateTimeAdapter class to implement both JsonSerializer<LocalDateTime> and JsonDeserializer<LocalDateTime>. I used the DateTimeFormatter.ISO_LOCAL_DATE_TIME to ensure that the date-time is formatted according to the ISO-8601 standard.

LocalDateTimeAdapter.java

import com.google.gson.JsonDeserializer;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonParseException;
 
import java.lang.reflect.Type;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
 
public class LocalDateTimeAdapter implements JsonSerializer<LocalDateTime>, JsonDeserializer<LocalDateTime> {
    private static final DateTimeFormatter formatter = DateTimeFormatter.ISO_LOCAL_DATE_TIME;
 
    @Override
    public JsonElement serialize(LocalDateTime src, Type typeOfSrc, com.google.gson.JsonSerializationContext context) {
        return new JsonPrimitive(src.format(formatter));
    }
 
    @Override
    public LocalDateTime deserialize(JsonElement json, Type typeOfT, com.google.gson.JsonDeserializationContext context) throws JsonParseException {
        return LocalDateTime.parse(json.getAsString(), formatter);
    }
}

Explanation

◉ Serialization: The serialize method takes a LocalDateTime object and converts it to a JSON primitive string using the ISO-8601 format. This ensures that the LocalDateTime is represented as a standard string in JSON.
◉ Deserialization: The deserialize method takes a JSON element (expected to be a string) and converts it back to a LocalDateTime object using the same ISO-8601 format. This ensures that the string is correctly parsed back into a LocalDateTime instance.

3.2.1 Register LocalDateTimeAdapter with Gson

To handle LocalDateTime objects correctly, we need to register our custom LocalDateTimeAdapter with Gson. Here is how to register the LocalDateTimeAdapter:

CustomDateTimeExample.java

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.time.LocalDateTime;
 
public class CustomDateTimeExample {
 
    public static void main(String[] args) {
       Gson gson = new GsonBuilder()
                .registerTypeAdapter(LocalDateTime.class, new LocalDateTimeAdapter())
                .create();
 
 
        Person person = new Person("John Doe", LocalDateTime.now());    
         
        // Serialize
        String json = gson.toJson(person);
        System.out.println("Serialized Person with LocalDateTime: " + json);
         
        //Deserialize
        Person deserializedPerson = gson.fromJson(json, Person.class);
        System.out.println("Deserialized Person with LocalDateTime: " + deserializedPerson);
    }
 
}

Output is:

Serialized Person with LocalDateTime: {"name":"John Doe","birthDate":"2024-06-05T17:32:36.982656"}
Deserialized Person with LocalDateTime: Person{name=John Doe, birthDate=2024-06-05T17:32:36.982656}

3.3 ZonedDateTime Serializer and Deserializer

Let’s create a ZonedDateTimeAdapter class that implements both JsonSerializer<ZonedDateTime> and JsonDeserializer<ZonedDateTime>. I used the DateTimeFormatter.ISO_ZONED_DATE_TIME to ensure that the date-time, including the time zone information, is formatted according to the ISO-8601 standard.

ZonedDateTimeAdapter.java

import com.google.gson.JsonDeserializer;
import com.google.gson.JsonSerializer;
import com.google.gson.JsonElement;
import com.google.gson.JsonPrimitive;
import com.google.gson.JsonParseException;
 
import java.lang.reflect.Type;
import java.time.ZonedDateTime;
import java.time.format.DateTimeFormatter;
 
 
public class ZonedDateTimeAdapter implements JsonSerializer<ZonedDateTime>, JsonDeserializer<ZonedDateTime> {
    private static final DateTimeFormatter formatter = DateTimeFormatter.ISO_ZONED_DATE_TIME;
 
    @Override
    public JsonElement serialize(ZonedDateTime src, Type typeOfSrc, com.google.gson.JsonSerializationContext context) {
        return new JsonPrimitive(src.format(formatter));
    }
 
    @Override
    public ZonedDateTime deserialize(JsonElement json, Type typeOfT, com.google.gson.JsonDeserializationContext context) throws JsonParseException {
        return ZonedDateTime.parse(json.getAsString(), formatter);
    }
}

3.3.1 Register ZonedDateTimeAdapter with Gson

Similarly, to handle ZonedDateTime objects, we need to register our custom ZonedDateTimeAdapter with Gson. This ensures that Gson knows how to correctly serialize and deserialize ZonedDateTime instances, preserving both the date-time and the time zone information.

Here’s how to register the ZonedDateTimeAdapter:

CustomDateTimeExample.java

import com.google.gson.Gson;
import com.google.gson.GsonBuilder;
import java.time.ZonedDateTime;
 
public class CustomDateTimeExample {
 
    public static void main(String[] args) {
       Gson gson = new GsonBuilder()
                .registerTypeAdapter(ZonedDateTime.class, new ZonedDateTimeAdapter())
                .create();
 
 
        Person person = new Person("John Doe", ZonedDateTime.now());    
         
        // Serialize
        String json = gson.toJson(person);
        System.out.println("Serialized Person with ZonedDateTime: " + json);
         
        //Deserialize
        Person deserializedPerson = gson.fromJson(json, Person.class);
        System.out.println("Deserialized Person with ZonedDateTime: " + deserializedPerson);
    }
}

In the code above, the registerTypeAdapter method is used to register our custom-type adapter (ZonedDateTimeAdapter) for the ZonedDateTime class.

Output is:

Serialized Person with ZonedDateTime: {"name":"John Doe","birthDate":"2024-06-05T17:36:30.947555+01:00[Africa/Lagos]"}
Deserialized Person with ZonedDateTime: Person{name=John Doe, birthDate=2024-06-05T17:36:30.947555+01:00[Africa/Lagos]}

Source: javacodegeeks.com

Friday, July 9, 2021

Java 8 Streams Filter With Multiple Conditions Examples

Oracle Java, Java 8 Streams, Oracle Java Tutorial and Material, Oracle Java Preparation, Oracle Java Learning, Oracle Java Prep, Oracle Java Certification

A quick guide to java 8 streams filtering concept with multiple conditions. This demonstrates how to use filter() in a more advanced way with examples

More Info: 1Z0-809: Java SE 8 Programmer II

1. Overview

In this tutorial, We’ll learn how to utilise stream filter() with several filter conditions (can be more than one condition).

Normally, we apply a single condition to streams using filter() method with lambda and then store the results in Lists or Sets.

However, we’ll learn how to use the filter() method with as many condition filters as we require.

More filters can be applied in a variety of methods, such using the filter() method twice or supplying another predicate to the Predicate.and() method.

In the next sections, we’ll look at examples with single and multiple conditions.

2. Stream.filter() with Single Condition

First, We’ll start by looking at how to apply the single filter condition to java streams.

Predicate is passed as an argument to the filter() method. Each value in the stream is evaluated to this predicate logic.

There are only a few methods in Predicate functional interface, such as and(), or(), or negate(), and isEquals().

package com.oraclejavacertified.java8.streams.filter;

import java.util.List;

import java.util.function.Predicate;

import java.util.stream.Collectors;

import java.util.stream.Stream;

/**

 * Example to filter the steam with single condition.

 * 

 */

public class FilterSingleCondition {

    public static void main(String[] args) {

        System.out.println("Fruites stream : " + getStream().collect(Collectors.toList()));

        // filter 1

        Predicate<String> nofruitWordFilter = name -> !name.contains("fruit");

        List<String> filteredList1 = getStream().filter(nofruitWordFilter).collect(Collectors.toList());

        System.out.println("filteredList 1 : " + filteredList1);

        // filter 1

        Predicate<String> noLetterOFilter = name -> !name.contains("o");

        List<String> noLetterOFilterList = getStream().filter(noLetterOFilter).collect(Collectors.toList());

        System.out.println("noLetterOFilterList : " + noLetterOFilterList);

    }

    // creating the stream of strings.

    private static Stream<String> getStream() {

        Stream<String> fruitesStream = Stream.of("mango", "grapes", "apple", "papaya", "jack fruit", "dragon fruit");

        return fruitesStream;

    }

}

Output:

Fruites stream : [mango, grapes, apple, papaya, jack fruit, dragon fruit]

filteredList 1 : [mango, grapes, apple, papaya]

noLetterOFilterList : [grapes, apple, papaya, jack fruit]

In the preceding example, we generated two predicate filters but only applied one of them to the stream at a time.

And it has generated two distinct outputs, which you should carefully examine.

3. Stream.filter() – Java 8 Stream Filter Multiple Parameters or Conditions

In the previous section, we have seen how to create a filter in java for stream

Next, we’ll attempt two different approaches of applying many conditions to a stream.

3.1 Invoking the filter() method on the stream multiple times

Take a look at the results after using the filter() method twice with different predicates criteria.

package com.oraclejavacertified.java8.streams.filter;

import java.util.List;

import java.util.function.Predicate;

import java.util.stream.Collectors;

import java.util.stream.Stream;

/**

 * Example to filter the steam with multiple conditions.

 * 

 */

public class FilterMultipleCondition {

    public static void main(String[] args) {

        System.out.println("Fruites stream : " + getStream().collect(Collectors.toList()));

        // filter 1

        Predicate<String> nofruitWordFilter = name -> !name.contains("fruit");

        // filter 2

        Predicate<String> noLetterOFilter = name -> !name.contains("o");

        // to remove the fruites with word "fruit" and with letter "o".

        List<String> result = getStream().filter(nofruitWordFilter)

                .filter(noLetterOFilter)

                .collect(Collectors.toList());

        // printing the final result

        System.out.println("Final result : " + result);

    }

    // creating the stream of strings.

    private static Stream<String> getStream() {

        Stream<String> fruitesStream = Stream.of("mango", "grapes", "apple", "papaya", "jack fruit", "dragon fruit");

        return fruitesStream;

    }

}

Output:

Fruites stream : [mango, grapes, apple, papaya, jack fruit, dragon fruit]

Final result : [grapes, apple, papaya]

3.2 Invoking Predicate.and() method with two conditions

Let’s utilise the method firstPredicate.and(secondPredicate) now. Pass the second predicate as a parameter to the and() function on the first predicate.

This signifies that the first predicate receives each instance from the stream. If the first predicate returns true, the second predicate receives the same value.

Finally, the result of filter() method will be satisfied by first and second predicate’s.

You can also use p1.and(p2.and(p3) to call with multiple predicates.

List<String> andPredicateResult = getStream().filter(nofruitWordFilter
        .and(noLetterOFilter))
        .collect(Collectors.toList());
 
System.out.println("andPredicateResult : "+andPredicateResult);

Output:

andPredicateResult : [grapes, apple, papaya]

When you call the filter() method several times and the predicate.and() method, the results are the same. However, it is recommended that you use the predicate and() method as needed.

this is similar to the grouping the multiple conditions into the single conditions as single predicate to filter() method.

You can use predicate or() or isEquals() methods with the multiple predicate conditions.

Source: javacodegeeks.com

Wednesday, July 7, 2021

Java 8 – Converting a List to String with Examples

Oracle Java 8, Oracle Java Certification, Oracle Java Guides, Oracle Java Career, Oracle Java Preparation

A quick guide to convert List to String in java using different methods and apache commons api with examples.

1. Overview

In this tutorial, we will learn how to convert List to String in java with example programs.

This conversion is done with the simple steps with java api methods.

First, we will understand how to make List to String using toString() method.

Next, Collection to String with comma separator or custom delimiter using Java 8 Streams Collectors api and String.join() method.

Finally, learn with famous library apache commands StringUtils.join() method.

For all the examples, input list must be a type of String as List<String> otherwise we need to convert the non string to String. Example, List is type of Double then need to convert then double to string first.

2. List to String Using Standard toString() method

List.toString() is the simplest one but it adds the square brackets at the start and end with each string is separated with comma separator.

The drawback is that we can not replace the comma with another separator and can not remove the square brackets.

package com.oraclejavacertified.convert.list2string;

import java.util.Arrays;

import java.util.List;

/**

 * Example to convert List to string using toString() method.

 *

 */

public class ListToStringUsingToStringExample {

    public static void main(String[] args) { 

    // creating a list with strings.

    List<String> list = Arrays.asList("One",

                      "Two",

                      "Three",

                      "Four",

                      "Five");

    // converting List<String> to String using toString() method

    String stringFromList = list.toString();

    // priting the string

    System.out.println("String : "+stringFromList);     

    }

}

Output:

String : [One, Two, Three, Four, Five]

3. List to String Using Java 8 String.join() Method

The above program works before java 8 and after. But, java 8 String is added with a special method String.join() to convert the collection to a string with a given delimiter.

The below example is with the pipe and tilde separators in the string.

import java.util.Arrays;

import java.util.List;

/**

 * Example to convert List to string using String.join() method.

 * 

 */

public class ListToStringUsingString_JoinExample {

    public static void main(String[] args) {

    // creating a list with strings.

    List<String> list = Arrays.asList("One",

                      "Two",

                      "Three",

                      "Four",

                      "Five");

    // converting List<String> to String using toString() method

    String stringFromList = String.join("~", list);

    // priting the string

    System.out.println("String with tilde delimiter: "+stringFromList);

    // delimiting with pipe | symbol.

    String stringPipe = String.join("|", list);

    // printing

    System.out.println("String with pipe delimiter : "+stringPipe);

    }

}

Output:

String with tilde delimiter: One~Two~Three~Four~Five

String with pipe delimiter : One|Two|Three|Four|Five

4. List to String Using Java 8 Collectors.joining() Method

Collectors.join() method is from java 8 stream api. Collctors.joining() method takes delimiter, prefix and suffix as arguments. This method converts list to string with the given delimiter, prefix and suffix.

Look at the below examples on joining() method with different delimiters. But, String.join() method does not provide the prefix and suffix options.

If you need a custom delimiter, prefix and suffix then go with these. If you do not want the prefix and suffix then provide empty string to not to add any before and after the result string.

import java.util.Arrays;

import java.util.List;

import java.util.stream.Collectors;

/**

 * Example to convert List to string using Collectors.joining() method.

 * 

 */

public class ListToStringUsingString_JoinExample {

    public static void main(String[] args) {

    // creating a list with strings.

    List<String> list = Arrays.asList("One",

                      "Two",

                      "Three",

                      "Four",

                      "Five");

    // using java 8 Collectors.joining with delimiter, prefix and suffix

    String joiningString = list.stream().collect(Collectors.joining("-", "{", "}"));

    // printing

    System.out.println("Collectors.joining string : "+joiningString);

    String joiningString3 = list.stream().collect(Collectors.joining("@", "", ""));

    // printing

    System.out.println("Collectors.joining string with @ separator : "+joiningString3);

    }

}

Output:

Collectors.joining string : {One-Two-Three-Four-Five}

Collectors.joining string with @ separator : One@Two@Three@Four@Five

5. List to String Using Apache Commons StringUtils.join() method

Finally way is using external library from apache commons package. This library has a method

StringUtils.join() which takes the list and delimiter similar to the String.join() method.

import org.apache.commons.lang3.StringUtils;

/**

 * Example to convert List to string using apache commons stringutils.join() method.

 * 

 */

public class ListToStringUsingStringUtils_JoinExample {

    public static void main(String[] args) {   

    // creating a list with strings.

    List<String> list = Arrays.asList("One",

                      "Two",

                      "Three",

                      "Four",

                      "Five");

    // using java 8 Collectors.joining with delimiter, prefix and suffix

    String joiningString = StringUtils.join(list, "^"); 

    // printing

    System.out.println("StringUtils.join string with ^ delimiter : "+joiningString);

    String joiningString3 = StringUtils.join(list, "$");

    // printing

    System.out.println("StringUtils.join string with @ separator : "+joiningString3);

    }

}

Output:

StringUtils.join string with ^ delimiter : One^Two^Three^Four^Five

StringUtils.join string with @ separator : One$Two$Three$Four$Five

Source: javacodegeeks.com    

Monday, June 21, 2021

Java 8 IntStream With Working Examples

Oracle Java Tutorial and Material, Oracle Java Certification, Core Java, Oracle Java Preparation, Oracle Java Career

A quick guide to understand primitive int representation of Stream as interface IntStream to support integer operations and with the useful examples.

More Info: 1Z0-819: Oracle Java SE 11 Developer

1. Overview

In this tutorial, We’ll learn how to use the IntStream in java 8 and it uses with example programs.

For int primitives, the Java IntStream class is a specialization of the Stream interface. It’s a stream of primitive int-valued items that can be used in both sequential and parallel aggregate operations.

AutoCloseable and BaseStream interfaces are implemented by IntStream, which is part of the java.util.stream package.

We will learn the following topics in this course.

◉ IntStream Creation

◉ ForEach loop

◉ IntStream ranges

◉ IntStream min and max

◉ IntStream find

◉ IntStrem map

◉ IntStream filter

◉ IntStream distinct

◉ IntStream to Array

◉ IntStream to List

2. Creating IntStream

An IntStream can be generated in a variety of ways, but it cannot be created using a new keyword.

The IntStream objects are created using the methods listed below.

◉ IntStream.of()

◉ IntStream.range()

◉ IntStream.rangeclosed()

◉ IntStream.generate()

◉ IntStream.iterate()

Let us explore the ways to use these methods with example programs. to create an instance for IntStream with primitive int values.

2.1 IntStream.of()

This function returns a sequentially ordered stream with the provided values as its elements.

It is available in two forms: single element stream and multiple values stream.

IntStream of(int t) – Returns a stream consisting of a single supplied element.

IntStream of(int… values) – Returns a stream with all the components supplied.

package com.oraclejavacertified.java8.intstream;

import java.util.stream.IntStream;

public class IntStreamOf {

    public static void main(String[] args) {

        IntStream singleValue = IntStream.of(10);

        IntStream multipleValeus = IntStream.of(1, 5, 10, 20, 30);

    }

}

2.2 IntStream.range()

range() is used to generate the numbers in the order with incremental by one.

static IntStream range(int startInclusive, int endExclusive) — here the end range is exclusive.

IntStream range10to30 = IntStream.range(10, 20);

2.3 IntStream.rangeclosed()

rangeClosed() is also used to generate the numbers in the order with incremental by one but it includes the end index of this method.

static IntStream rangeClosed(int startInclusive, int endInclusive)

IntStream range10to15closed = IntStream.range(10, 15);

2.4 IntStream.generate()

Use the generate() method if you wish to generate random numbers with custom logic.

IntStream random = IntStream.generate( () -> { return (int) Math.random() * 5000;});

2.5 IntStream.iterate()

The iterate() method is identical to the generate() method, except instead of random values, it uses incremental or decrement custom logic for large values.

Due to the fact that the iterate() method generates an infinite stream of integers, you must use the limit() function to get the first n numbers.

IntStream iterate = IntStream.iterate(1000, i -> i + 4000).limit(5);

3. IntStream forEach()


Typically we can use the traditional for loop for certain range. However, the same thing may be accomplished by using the IntStream.forEach() function instead.

package com.oraclejavacertified.java8.intstream;
 
import java.util.stream.IntStream;
 
public class IntStreamOf {
 
    public static void main(String[] args) {
         
        System.out.println("for loop");
        for(int i = 1000; i < 20000 ; i = i + 4000) {
            print(i);
        }
         
        System.out.println("intstream foreach loop");
        IntStream iterate = IntStream.iterate(1000, i -> i + 4000).limit(5);
         
        iterate.forEach(n -> print(n));
         
         
    }
     
    private static void print(int n) {
        System.out.println(n);
    }
 
}

4. IntStream ranges 


Two methods are offered by the IntStream API to work with numbers generated in a defined range.

range(start, endExclusive): excludes the end index from the output range.

rangeClosed(start, endInclusive): this method includes the end index from the output range.

The below program output gives you clear understanding between range() and rangeClosed() methods.

IntStream range10to15range = IntStream.range(10, 15);
        IntStream range10to15closed = IntStream.rangeClosed(10, 15);
         
        System.out.println("range(10, 15) : "+Arrays.toString(range10to15range.toArray()));
        System.out.println("rangeClosed(10, 15) : "+Arrays.toString(range10to15closed.toArray()));

Output:

range(10, 15) : [10, 11, 12, 13, 14]
rangeClosed(10, 15) : [10, 11, 12, 13, 14, 15]

5. IntStream min and max


IntStream has utility methods for determining the minimum and maximum values from a series of numbers or random numbers.

Use min() method to retrieve the lowest value from int stream.

Use max() method to retrieve the highest value from int stream.

System.out.println("range(10, 15) min value : "+IntStream.range(10, 15).min().getAsInt());
System.out.println("range(10, 15) max value : "+IntStream.range(10, 15).max().getAsInt());

Output:

range(10, 15) min value : 10
range(10, 15) max value : 14

6. IntStream find value


Use findFirst() or findAny() methods on the InstStream object to get the first or any value.

findFirst() vs findAny() indepth

By default, IntStream is created as sequential stream unless call the parallel() on the IntStream.

For sequential streams, the findFirst() and findAny() methods return the same result. If the stream is parallel, however, the findAny() method gives a random value.

System.out.println("findFirst value : "+IntStream.iterate(10, i -> i + 2).limit(100).findFirst().getAsInt());
System.out.println("findAny value : "+IntStream.iterate(10, i -> i + 2).limit(100).findAny().getAsInt());
 
System.out.println("parallel findAny value : "+IntStream.iterate(10, i -> i + 2).limit(100).parallel().findAny().getAsInt());

Output:

findFirst value : 10
findAny value : 10
parallel findAny value : 160

7. IntStream map() or flatMap()


Java 8 IntStream With Working Examples
We can transform the IntStream into the new form using map() method but flatMap() method does the flatten the IntStreams into primitives.

Usage of map() and flatMap() does not give much difference with IntStream usage.

IntStream mapInput = IntStream.iterate(10, i -> i + 1).limit(10);
 
System.out.println("map input stream : "+Arrays.toString(mapInput.toArray()));
 
IntStream mapOutput = mapInput.map( i -> i * 2);
 
System.out.println("map Output stream : "+Arrays.toString(mapOutput.toArray()));
 
IntStream input1 = IntStream.iterate(10, i -> i + 1).limit(10);
 
System.out.println("flat map : "+Arrays.toString(input1.flatMap( i -> IntStream.of(i)).toArray()));

Output:

map input stream : [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]
map Output stream : [20, 22, 24, 26, 28, 30, 32, 34, 36, 38]
flat map : [10, 11, 12, 13, 14, 15, 16, 17, 18, 19]

8. IntStream filter


Use filter() method to filter the integer values based on the given IntPredicate condition.

After applying the filter() method then next you can call forEach() or collect() method to convert it into List or Set.

IntStream stream = IntStream.range(100, 200);
 
// filter by number divisible by 5 and 7
System.out.println("numbers divisible by 5 and 7 are : ");
stream.filter(i -> (i % 5 == 0 && i % 7 == 0)).forEach(System.out::println);
 
IntStream stream2 = IntStream.range(100, 200);
 
List<Integer> primes = stream2.filter(IntStreamOf::checkPrime).boxed().collect(Collectors.toList());
 
System.out.println("Prime numbers (100, 200) are "+primes);

Output:

numbers divisible by 5 and 7 are : 
105
140
175
Prime numbers (100, 200) are [101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199]

9. IntStream distinct()


Use distinct() method to remove the duplicate values from IntStream.

Arrays.toString(IntStream.of(1, 2, 3, 1, 2, 3).distinct().toArray());

Output:

[1, 2, 3]

10. IntStream to Array and List or Set


Use toArray() method to collect the output of IntStream into Array.

Use collect() method to collect the output of IntStream into List or Set.

To remove the duplicates from int stream, you can collect the results into Set rather than using distinct() method. But distinct() is recommended.

int[] intArray = IntStream.of(1, 2, 3, 1, 2, 3).toArray();
System.out.println("int array : "+Arrays.toString(intArray));
 
List<Integer> list = IntStream.of(1, 2, 3, 1, 2, 3).boxed().collect(Collectors.toList());
System.out.println("IntStream to List : "+list);
 
Set<Integer> set = IntStream.of(1, 2, 3, 1, 2, 3).boxed().collect(Collectors.toSet());
System.out.println("IntStream to Set : "+set);

Source: javacodegeeks.com

Monday, May 17, 2021

Java 8 Streams – Group By Multiple Fields with Collectors.groupingBy()

Java 8 Streams, Oracle Java Tutorial and Material, Oracle Java Exam Prep, Oracle Java Preparation, Oracle Java Certification

A guide to group by two or more fields in java 8 streams api. Examples to grouping List by two fields.

1. Overview

In this post, We will learn how to group by multiple fields in java 8 using Streams Collectors.groupingBy() method and example programs with custom objects.

2. Group By Multiple Fields Example in Java 8

First, Create a class Employee with below properties.

int id

String name

String designation

String gender

long salary

Create argument constructor and setter, getters methods for all properties. And also add toString() method to see the Employee object in readable format.

Next, We will try to implement the group by on two fields such as designation and gender. On these two fields get the group by count.

Look at the below examples, you will see the code with the groupingBy() is used twice. This is called as Collectors chaining and observe the output.

package com.oraclejavacertified.java8.collectors.groupby;

public class Employee {

    private int id;

    private String name;

    private String designation;

    private String gender;

    private long salary;

    public Employee(int id, String name, String designation, String gender, long salary) {

        super();

        this.id = id;

        this.name = name;

        this.designation = designation;

        this.gender = gender;

        this.salary = salary;

    }

    public int getId() {

        return id;

    }

    public void setId(int id) {

        this.id = id;

    }

    public String getName() {

        return name;

    }

    public void setName(String name) {

        this.name = name;

    }

    public String getDesignation() {

        return designation;

    }

    public void setDesignation(String designation) {

        this.designation = designation;

    }

    public String getGender() {

        return gender;

    }

    public void setGender(String gender) {

        this.gender = gender;

    }

    public long getSalary() {

        return salary;

    }

    public void setSalary(long salary) {

        this.salary = salary;

    }

    @Override

    public String toString() {

        return "Employee [id=" + id + ", name=" + name + ", designation=" + designation + ", gender=" + gender

                + ", salary=" + salary + "]";

    }

}

Example – Group By Two Properties:

package com.oraclejavacertified.java8.collectors.groupby;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;

public class GroupingByMultipleFieldsExample {

    public static void main(String[] args) {

        // Creating List and adding Employees values.

        List<Employee> employeesList = new ArrayList<>();

        employeesList.add(new Employee(101, "Glady", "Manager", "Male", 25_00_000));

        employeesList.add(new Employee(102, "Vlad", "Software Engineer", "Female", 15_00_000));

        employeesList.add(new Employee(103, "Shine", "Lead Engineer", "Female", 20_00_000));

        employeesList.add(new Employee(104, "Nike", "Manager", "Female", 25_00_000));

        employeesList.add(new Employee(105, "Slagan", "Software Engineer", "Male", 15_00_000));

        employeesList.add(new Employee(106, "Murekan", "Software Engineer", "Male", 15_00_000));

        employeesList.add(new Employee(107, "Gagy", "Software Engineer", "Male", 15_00_000));

        // group by - multiple fields

        // Grouping by designation and Gender two properties and need to get the count.

        Map<String, Map<String, Long>> multipleFieldsMap = employeesList.stream()

                .collect(

                        Collectors.groupingBy(Employee::getDesignation, 

                                Collectors.groupingBy(Employee::getGender, 

                                        Collectors.counting())));

        // printing the count based on the designation and gender.

        System.out.println("Group by on multiple properties" + multipleFieldsMap);

    }

}

Output:

Group by on multiple properties

{Software Engineer={Male=3, Female=1}, Manager={Female=1, Male=1}, Lead Engineer={Female=1}}

From the output, you can clearly observe that we can see the count by designation and gender type.

In this program, we have gathered the count of employees but rather than this we can get the list of Employees.

3. Java 8 – Group By Multiple Fields and Collect Aggregated Result into List

First, Collect the list of employees as List<Employee> instead of getting the count. That means inner aggregated Map value type should be List.

To get the list, we should not pass the second argument for the second groupingBy() method.

// Example 2

// group by - multiple fields

// Grouping by designation and Gender two properties and need to get the count.

Map<String, Map<String, List<Employee>>> multipleFieldsMapList = employeesList.stream()

        .collect(

                Collectors.groupingBy(Employee::getDesignation, 

                        Collectors.groupingBy(Employee::getGender)));

// printing the count based on the designation and gender.

System.out.println("Group by on multiple properties and Map key as List" + multipleFieldsMapList);

Output:

Group by on multiple properties and Map key as List 

{

Software Engineer={Male=[

                        Employee [id=105, name=Slagan, designation=Software Engineer, gender=Male, salary=1500000], Employee [id=106, name=Murekan, designation=Software Engineer, gender=Male, salary=1500000], Employee [id=107, name=Gagy, designation=Software Engineer, gender=Male, salary=1500000]], 

                    Female=[Employee [id=102, name=Vlad, designation=Software Engineer, gender=Female, salary=1500000]]}, 

Manager={

        Female=[Employee [id=104, name=Nike, designation=Manager, gender=Female, salary=2500000]], 

        Male=[Employee [id=101, name=Glady, designation=Manager, gender=Male, salary=2500000]]}, 

Lead Engineer={Female=[Employee [id=103, name=Shine, designation=Lead Engineer, gender=Female, salary=2000000]]}}

4. Java 8 – Group By Multiple Fields – Avoid Collectors Chaining

Image
We can avoid the Collectors chaining such as calling groupingby() function several times. If we want to group by 4 fields then need to call Collectors.groupingBy() also 4 times which makes code ugly and not readable.

Let us create the separate class with the group by properties and write implementation for equals(), hashcode() methods for object comparisons.

Creating new class for GroupBy fields makes us to call only once the groupingBy() method.

Below examples are implemented as described and suggested way.

GroupBy Class:

class GroupBy {

    private String designation;

    private String gender;

    public GroupBy(String designation, String gender) {

        super();

        this.designation = designation;

        this.gender = gender;

    }

    @Override

    public int hashCode() {

        return this.designation.length() + this.gender.length();

    }

    @Override

    public boolean equals(Object obj) {

        GroupBy other = (GroupBy) obj;

        if (other.getDesignation().equals(this.designation) && other.getGender().equals(this.gender))

            return true;

        return false;

    }

    public String getDesignation() {

        return designation;

    }

    public void setDesignation(String designation) {

        this.designation = designation;

    }

    public String getGender() {

        return gender;

    }

    public void setGender(String gender) {

        this.gender = gender;

    }

    @Override

    public String toString() {

        return "GroupBy [designation=" + designation + ", gender=" + gender + "]";

    }

}

Employee Class:

package com.oraclejavacertified.java8.collectors.groupby.multiple;

public class Employee {

    private int id;

    private String name;

    private long salary;

    private GroupBy groupBy;

    public Employee(int id, String name, long salary, GroupBy groupBy) {

        super();

        this.id = id;

        this.name = name;

        this.salary = salary;

        this.groupBy = groupBy;

    }

    // setters and getters

    @Override

    public String toString() {

        return "Employee [id=" + id + ", name=" + name + ", salary=" + salary + ", groupBy=" + groupBy + "]";

    }

}

Optimized Group By Multiple Fields Example  

package com.oraclejavacertified.java8.collectors.groupby.multiple;

import java.util.ArrayList;

import java.util.List;

import java.util.Map;

import java.util.stream.Collectors;

public class GroupingByMultipleFieldsExample {

    public static void main(String[] args) {

        // Creating List and adding Employees values.

        List<Employee> employeesList = new ArrayList<>();

        employeesList.add(new Employee(101, "Glady", 25_00_000, new GroupBy("Manager", "Male")));

        employeesList.add(new Employee(102, "Vlad", 15_00_000, new GroupBy("Software Engineer", "Female")));

        employeesList.add(new Employee(103, "Shine", 20_00_000, new GroupBy("Lead Engineer", "Female")));

        employeesList.add(new Employee(104, "Nike", 25_00_000, new GroupBy("Manager", "Female")));

        employeesList.add(new Employee(105, "Slagan", 15_00_000, new GroupBy("Software Engineer", "Male")));

        employeesList.add(new Employee(106, "Murekan", 15_00_000, new GroupBy("Software Engineer", "Male")));

        employeesList.add(new Employee(107, "Gagy", 15_00_000, new GroupBy("Software Engineer", "Male")));

        // Example 1

        // group by - multiple fields

        // Grouping by designation and Gender two properties and need to get the count.

        Map<GroupBy, Long> multipleFieldsMap = employeesList.stream()

                .collect(Collectors.groupingBy(Employee::getGroupBy, Collectors.counting()));

        // printing the count based on the designation and gender.

        System.out.println("Group by on multiple properties" + multipleFieldsMap);

    }

}

Output:

Group by on multiple properties

    { GroupBy [designation=Lead Engineer, gender=Female]=1, 

      GroupBy [designation=Software Engineer, gender=Male]=3, 

      GroupBy [designation=Software Engineer, gender=Female]=1, 

      GroupBy [designation=Manager, gender=Male]=1, 

      GroupBy [designation=Manager, gender=Female]=1

    }


5. Grouping By Using Apache Commons Pair.of()


If you have only two fields and do not wish to use the Record or Another class with the Group by properties then we can use the Pair.of() from apache commons library.

// Example 3
// group by - multiple fields
// Grouping by designation and Gender two properties with Pair.of()
 
Map<Pair<String, String>, Long> multipleFieldsMapPair = employeesList.stream()
        .collect(Collectors.groupingBy(e -> Pair.of(e.getDesignation(), e.getGender()), Collectors.counting()));
 
// printing the count based on the designation and gender.
System.out.println("Group by on multiple fields with Pair - " + multipleFieldsMapPair);

Output:

Group by on multiple fields with Pair - 
{
    (Software Engineer,Male)=3, 
    (Software Engineer,Female)=1, 
    (Lead Engineer,Female)=1, 
    (Manager,Female)=1, 
    (Manager,Male)=1
}

Source: javacodegeeks.com

Wednesday, May 5, 2021

Java 8 Parallel Streams – Custom Thread Pools Examples

A brief intro to custom thread pools and their use in Java 8 parallel streams. Examples on how to use custom pools with the Parallel streams API which avoids common thread pool usage.

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.

Java 8 Parallel Streams, Core Java, Java 8, Oracle Java Tutorial and Material, Oracle Java Learning, Oracle Java Preparation, Java Career

2. Java 8 Parallel Streams


First, let us see how to create Parallel Streams from a Collection.

To make a stream that can run by multiple cores of the processer, you just need to call parallelStream() method.

package com.oraclejavacertified.java8.streams.parallel.streams;
 
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;
 
public class ParallelStreamCreation {
 
    public static void main(String[] args) {
 
        List<Integer> intList = Arrays.asList(10, 20, 30, 40, 50);
 
        Stream<Integer> parallelStream = intList.parallelStream();
 
        parallelStream.forEach(value -> System.out.println(value));
    }
}

Output:

[30
40
50
20
10]

You can observe the output that printed the values randomly by different cores.

Internally, it uses SplitIterator and StreamSupport classes to make it run parallelly.

The default processing is done with ForkJoinPool.commonPool() which is shared by the entire application. If you lots of parallel streams that are running at the same time then you may see performance and delay in processing time.

3. Using Custom Thread Pool


As a result of the above approach will use a common ForkJoinPool for all the parallel Streams.

If you have many parallel streams running at the same time and some of them take time longer than expected due to network slowness and those tasks may be blocking the threads from the common pool. Hence, it causes to slow down the tasks and take a longer time to complete.

In these cases, It is good to go with the custom thread pools with the parallel streams combination.

Look at the below program, that runs with 5 threads using ForkJoinPool and inside creating a new parallel stream to find the sum of all numbers for the given range.

package com.oraclejavacertified.java8.streams.parallel.streams;
 
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ForkJoinPool;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
 
public class CustomPoolParallelStreams {
 
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        parallelStreamProcess();
    }
 
    private static void parallelStreamProcess() throws ExecutionException, InterruptedException {
 
        int start = 1;
        int end = 10000;
 
        List<Integer> intList = IntStream.rangeClosed(start, end).boxed()
                .collect(Collectors.toList());
        System.out.println(intList.size());
 
        ForkJoinPool newCustomThreadPool = new ForkJoinPool(5);
        int actualTotal = newCustomThreadPool.submit(
                () -> {
                     int a = intList.stream().parallel().reduce(0, Integer::sum).intValue();
                     return a;
                }).get();
 
        System.out.println("actualTotal " + actualTotal);
 
    }
 
}

Output:

[10000

actualTotal 50005000]

Java 8 Parallel Streams, Core Java, Java 8, Oracle Java Tutorial and Material, Oracle Java Learning, Oracle Java Preparation, Java Career
Actually, The above program does not come up with the efficient but I have seen the many websites talking about this solution. In fact, this also creating a parallel stream inside ForkJoinPool which again internally consumes threads from a common pool of ForkJoinPool area.

So, If you are running multiple parallel streams then do not use this Steam api parallel method as this might slow other streams give the results in more time.

Here, we have taken the pool count as 5 but you can change it as per your CPU configuration. If you have more then you can fine-tune based on the other tasks.

If you have only one parallel stream then you can use it with a limited pool count.

But, Wait for a java update that parallel stream can take ForkJoinPool as input to limit the number of parallel processes.

Source: javacodegeeks.com

Tuesday, May 4, 2021

Java 8 – How To Read A File?

Java 8, Core Java, Oracle Java Tutorial and Material, Oracle Java Career, Oracle Java Preparation, Oracle Java Certification

A quick guide on how to read the file in older java and new JDK 8 version with example programs.

1. Overview

In this tutorial, We’ll learn how to read a file line by line in java and print the files content onto console with example program.

Read More: 1Z0-900: Java EE 7 Application Developer

First, let us use the older java version for example demonstration and next will learn how to do the same in the newer java 8 api.

2. Java Read File Example

First, Use BufferedReader.readLine() method to get the each line from the file.

Example:

package com.oraclejavacertified.files.read;

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.IOException;

/**

 * Example to read the file in java

 * 

 * @author oraclejavacertified.blogspot.com

 *

 */

public class ReadFileBeforeJava8 {

    public static void main(String[] args) throws IOException {

        String fileLocation = "/Users/workspace/CoreJava/src/main/java/com/oraclejavacertified/files/read/student.txt";

        FileReader fileReader = new FileReader(fileLocation);

        BufferedReader bufferedReader = new BufferedReader(fileReader);

        String line;

        int index = 1;

        while ((line = bufferedReader.readLine()) != null) {

            System.out.println("line " + index + " : " + line);

            index++;

        }

    }

}

Output:

line 1 : student name - Java Learner

line 2 : Location - India

3. Java Example To Read CSV File

Next, Use the same concept to read the csv file in java but first line will be the csv header and the remaining lines will be holding the actual values.

package com.oraclejavacertified.files.read;

import java.io.BufferedReader;

import java.io.FileReader;

import java.io.IOException;

/**

 * Example to read the CSV file in java

 * 

 * @author oraclejavacertified.blogspot.com

 *

 */

public class ReadCSVFileBeforeJava8 {

    public static void main(String[] args) throws IOException {

        String fileLocation = "/Users/workspace/CoreJava/src/main/java/com/oraclejavacertified/files/read/student.csv";

        FileReader fileReader = new FileReader(fileLocation);

        BufferedReader bufferedReader = new BufferedReader(fileReader);

        String csvLine;

        int index = 1;

        String header = bufferedReader.readLine();

        System.out.println("CSV header : "+header);

        while ((csvLine = bufferedReader.readLine()) != null) {

            System.out.println("csv line " + index + " : " + csvLine);

            index++;

        }

    }

}

Output:

CSV header : student id,name,age

csv line 1 : 100,Jhon,30

csv line 2 : 101,Shella,35

csv line 3 : 102,Dhon,40

4. Java 8 Streams – Read File Example – Files.readLines()

Further more, Use method Files.readLines() method to get the all the lines in the form of java 8 Stream. Next, use forEach() method to get the each line of file and print into the console.

package com.oraclejavacertified.files.read;

import java.io.IOException;

import java.nio.file.Files;

import java.nio.file.Path;

import java.util.stream.Stream;

/**

 * Java 8 example to read the file using Streams.

 * 

 * @author oraclejavacertified.blogspot.com

 *

 */

public class Java8ReadFileExample1 {

    public static void main(String[] args) {

        Path filePath = Path.of(

                "/Users/workspace/CoreJava/src/main/java/com/oraclejavacertified/files/read/student.csv");

        Stream<String> stream = null;

        try {

            stream = Files.lines(filePath);

        } catch (IOException e) {

            e.printStackTrace();

        }

        stream.forEach(System.out::println);

    }

}

Output:

student id,name,age

100,Jhon,30

101,Shella,35

102,Dhon,40

5. Java 8 Streams + BufferedReader.lines()

Java 8, Core Java, Oracle Java Tutorial and Material, Oracle Java Career, Oracle Java Preparation, Oracle Java Certification
Finally, learn another new method of java 8 api is BufferedReader.lines() method which returns the Stream<String>.

package com.oraclejavacertified.files.read;

import java.io.BufferedReader;

import java.io.IOException;

import java.nio.file.Files;

import java.nio.file.Path;

import java.nio.file.Paths;

import java.util.List;

import java.util.stream.Collectors;

/**

 * Java 8 example to read the file using Streams + BufferedReader.lines().

 * 

 * @author oraclejavacertified.blogspot.com

 *

 */

public class Java8ReadFileExample2 {

    public static void main(String[] args) throws IOException {

        Path filePath = Path.of(

                "/Users/workspace/CoreJava/src/main/java/com/oraclejavacertified/files/read/student.csv");

        BufferedReader br = Files.newBufferedReader(filePath);

        List<String> list = br.lines().collect(Collectors.toList());

        list.forEach(System.out::println);

    }

}

Source: javacodegeeks.com