Monday, November 29, 2021

Java Stream boxed() With Examples

The boxed() method in Java Stream is used to wrap the primitive value (int, long or double) to its respective wrapper class object.

There are primitive specializations of Stream named IntStream, LongStream and DoubleStream each of these interfaces have a boxed() method that returns a Stream consisting of the elements of this stream, each boxed to an Integer, Long or Double respectively. Note that boxed() is an intermediate operation.

boxed stream Java examples

Let’s see few examples how to box a primitive value into its wrapper class using boxed() method.

1. boxed() in IntStream which is used to get a Stream consisting of the elements of this stream, each boxed to an Integer.

import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.Stream;

public class BoxedIntStream {
  public static void main(String[] args) {    
    Stream<Integer> wrappedInts = IntStream.of(1, 2, 3, 4, 5).boxed();
    List<Integer> numList = wrappedInts.collect(Collectors.toList());
    System.out.println(numList);
  }
}
Output
[1, 2, 3, 4, 5]

Here IntStream having int elements first uses boxed() method to wrap these primitive ints into an object of Integer class and then use the Stream consisting of those Integer objects to convert into a List. Doing it directly won’t work, so the following statement results in compile time error.

List<Integer> numList = IntStream.of(1,2,3,4,5).collect(Collectors.toList());

2. boxed() in LongStream which is used to get a Stream consisting of the elements of this stream, each boxed to a Long.

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

public class BoxedLongStream {
  public static void main(String[] args) {
    List<Long> numList = LongStream.of(6, 7, 8, 9, 10)
          .boxed()
          .collect(Collectors.toList());
    System.out.println(numList);
  }
}
Output
[6, 7, 8, 9, 10]

3. boxed() in DoubleStream which is used to get a Stream consisting of the elements of this stream, each boxed to a Double.

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

public class BoxedDoubleStream {
  public static void main(String[] args) {
    List<Double> numList = DoubleStream.of(6, 7, 8, 9, 10)
                               .boxed()
                               .collect(Collectors.toList());
    System.out.println(numList);

  }
}
Output
[6.0, 7.0, 8.0, 9.0, 10.0]

That's all for the topic Java Stream boxed() With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Java Stream concat() With Examples

If you want to merge two streams you can use concat() method in Java Stream API.

Syntax of concat() method

concat(Stream<? extends T> a, Stream<? extends T> b)

Here a represents the first stream and b represents the second stream. Method returns a stream consisting all the elements of the first stream followed by all the elements of the second stream.

The resulting stream is ordered if both of the input streams are ordered, and parallel if either of the input streams is parallel.

concat() method Java examples

1. Using concat() method to merge streams of Strings.

public class ConcatDemo {
  public static void main(String[] args) {
    Stream<String> stream1 = Stream.of("A", "B", "C");
    Stream<String> stream2 = Stream.of("D", "E", "F");
    Stream<String> mergedStream = Stream.concat(stream1, stream2);
    mergedStream.forEach(System.out::println);
  }
}
Output
A
B
C
D
E
F

2. Using concat method to merge more than 2 streams. You can also layer the concat() method to merge more than two streams, in the following example 4 streams are concatenated.

public class ConcatDemo {
  public static void main(String[] args) {
    Stream<Integer> stream1 = Stream.of(1, 2, 3);
    Stream<Integer> stream2 = Stream.of(4, 5, 6);
    Stream<Integer> stream3 = Stream.of(7, 8, 9);
    Stream<Integer> stream4 = Stream.of(10, 11, 12);
    Stream<Integer> mergedStream = Stream.concat(stream1, 
            Stream.concat(Stream.concat(stream2, stream3), stream4));
    mergedStream.forEach(e -> System.out.print(e + " "));
  }
}
Output
1 2 3 4 5 6 7 8 9 10 11 12 

3. Using concat() with other stream operations. A very common scenario is to merge two streams and get only the distinct elements, that can be done by using distinct() in Java stream.

public class ConcatDemo {
  public static void main(String[] args) {
    Stream<Integer> stream1 = Stream.of(1, 2, 3, 4, 5, 6);
    Stream<Integer> stream2 = Stream.of(4, 4, 3, 1, 8, 6);

    Stream<Integer> mergedStream = Stream.concat(stream1, stream2).distinct();
    mergedStream.forEach(e -> System.out.print(e + " "));
  }
}
Output
1 2 3 4 5 6 8 

That's all for the topic Java Stream concat() With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Friday, November 26, 2021

Java HashMap compute() With Examples

The Java HashMap compute() method is used to compute a new value for the specified key.

Syntax of compute() method

compute(K key, BiFunction<? super K,? super V,? extends V> remappingFunction)

The parameters are-

  1. key- Key with which the computed value has to be mapped.
  2. remappingFunction- It is an expression of type BiFunction functional interface used to compute a value.

Method returns a new value associated with the specified key or null if there is no new values. If the remapping function returns null, the mapping is removed (or remains absent if initially absent).

compute() method Java examples

1. In this example a new value is computed for the specified key. For the example a HashMap is created with product name as key and price as value. Then compute() is used to change the price (value) for the specified key.

import java.util.HashMap;
import java.util.Map;

public class MapComputeDemo {
  public static void main(String[] args) {
    Map<String, Double> products = new HashMap<>();
    products.put("Laptop", 1200.0);
    products.put("RAM", 60.50);
    products.put("USB", 10.45);
    products.put("Mouse", 15.0);
    System.out.println("*** Initial Values ***");
    System.out.println(products);
    // Laptop at 20% discount
    products.compute("Laptop", (k, v)-> v- (v*20/100));
    System.out.println("*** After Compute ***");
    System.out.println(products);
    
  }
}
Output
*** Initial Values ***
{Laptop=1200.0, Mouse=15.0, USB=10.45, RAM=60.5}
*** After Compute ***
{Laptop=960.0, Mouse=15.0, USB=10.45, RAM=60.5}

2. In this example we’ll see what happens if the remappingFunction returns null. In that case the (key, value) pair should be removed. To verify that the function explicitly returns null in the code.

public class MapComputeDemo {
  public static void main(String[] args) {
    Map<String, Double> products = new HashMap<>();
    products.put("Laptop", 1200.0);
    products.put("RAM", 60.50);
    products.put("USB", 10.45);
    products.put("Mouse", 15.0);
    System.out.println("*** Initial Values ***");
    System.out.println(products);
    // remappingFunction returns null
    products.compute("Laptop", (k, v)-> null);
    System.out.println("*** After Compute ***");
    System.out.println(products);
  }
}
Output
*** Initial Values ***
{Laptop=1200.0, Mouse=15.0, USB=10.45, RAM=60.5}
*** After Compute ***
{Mouse=15.0, USB=10.45, RAM=60.5}

As you can see the product “Laptop” is removed.

3. Using compute() method to compute all values in the HashMap. In the products HashMap if you want to increase price by 10% for all the products.

public class MapComputeDemo {
  public static void main(String[] args) {
    Map<String, Double> products = new HashMap<>();
    products.put("Laptop", 1200.0);
    products.put("RAM", 60.50);
    products.put("USB", 10.45);
    products.put("Mouse", 15.0);
    System.out.println("*** Initial Values ***");
    System.out.println(products);
    products.forEach((k,v) -> products.compute(k, (key, value)-> value + (value*10/100)));
    System.out.println("*** After Compute ***");
    System.out.println(products);
    
  }
}
Output
*** Initial Values ***
{Laptop=1200.0, Mouse=15.0, USB=10.45, RAM=60.5}
*** After Compute ***
{Laptop=1320.0, Mouse=16.5, USB=11.495, RAM=66.55}

That's all for the topic Java HashMap compute() With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Tuesday, November 23, 2021

Map#putIfAbsent() in Java With Examples

In this tutorial you will see how to use putIfAbsent() method in Java HashMap. The putIfAbsent() method inserts the specified value if the passed key is not already present in the HashMap or the key is null. Using this method gives you an option to check if key is already present or not, before associating a value with the key. What this method does in a single statement can be explained as-

 V v = map.get(key);
 if (v == null)
     v = map.put(key, value);

 return v;

Syntax of putIfAbsent() method

V putIfAbsent(K key, V value)

Here the parameters are-

  • key- key with which the specified value is to be associated
  • value- value to be associated with the specified key

This method returns the previous value if key is already associated with a value or null if there was no existing mapping for the key. Method also returns null if key was previously inserted as null in the HashMap.

Note that the default implementation of the putIfAbsent() method in the Map interface makes no guarantees about synchronization or atomicity properties of this method. Implementation of putIfAbsent() in the ConcurrentHashMap guarantees atomicity.

putIfAbsent() Java examples

1. In the following example we’ll try to insert a new value with an existing key.

import java.util.HashMap;
import java.util.Map;

public class MapPutIfAbsent {

  public static void main(String[] args) {
      Map<String, String> carMap = new HashMap<String, String>();
      // Storing elements
      carMap.put("1", "Audi");
      carMap.put("2", "BMW");
      carMap.put("3", "Jaguar");
      String val = carMap.putIfAbsent("3", "Mini Cooper");
      System.out.println("Value is- " + val);
      System.out.println(carMap);
  }
}
Output
Value is- Jaguar
{1=Audi, 2=BMW, 3=Jaguar}

As you can see since the key is already present in the HashMap so the value is not rewritten. Also note that the putIfAbsent() is returning the already associated value.

2. In the following example we’ll try to insert a value with a key that doesn’t already exist.

public class MapPutIfAbsent {
  public static void main(String[] args) {
    Map<String, String> carMap = new HashMap<String, String>();
    // Storing elements
    carMap.put("1", "Audi");
    carMap.put("2", "BMW");
    carMap.put("3", "Jaguar");
    String val = carMap.putIfAbsent("4", "Mini Cooper");
    System.out.println("Value is- " + val);
    System.out.println(carMap);
  }
}
Output
Value is- null
{1=Audi, 2=BMW, 3=Jaguar, 4=Mini Cooper}

As you can see from the output value is added to the HashMap along with the new key. putIfAbsent() method returns null because there was no existing mapping for the key.

3. In the following example we’ll try to insert a value with a key as null when there is already a value with null key.

public class MapPutIfAbsent {

  public static void main(String[] args) {
    Map<String, String> carMap = new HashMap<String, String>();
      // Storing elements
      carMap.put("1", "Audi");
      carMap.put("2", "BMW");
      carMap.put("3", "Jaguar");
      carMap.put(null, "Volks Wagon");
      String val = carMap.putIfAbsent(null, "Mini Cooper");
      System.out.println("Value is- " + val);
      System.out.println(carMap);
  }
}
Output
Value is- Volks Wagon
{null=Volks Wagon, 1=Audi, 2=BMW, 3=Jaguar}

As you can see new value is inserted now since the previous value was mapped to null. Return value of the putIfAbsent() method is the previous value.

That's all for the topic Map#putIfAbsent() in Java With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Java Stream count() With Examples

In Java Stream API there is a count() method that returns the count of elements in the stream. In this tutorial you’ll learn about count() method with the help of some examples.

Java Stream count() method

Syntax of the count() method is as follows-

long count()

count method is a special case of a reduction operation as it takes a sequence of input elements and combines them into a single summary result. This method is a terminal operation meaning it produces a result and stream pipeline is considered consumed, and can no longer be used after count operation.

count() method Java examples

1. Using count() to get the number of elements in a List by using list as a Stream source.

import java.util.Arrays;
import java.util.List;

public class CountDemo {

  public static void main(String[] args) {
    List<Integer> numList = Arrays.asList(3, 5, 4, 12, 16, 0, 7, 6);
    long result = numList.stream().count();
    System.out.println("Number of elements- " + result);
  }
}
Output
Number of elements- 8

2. You can also use count() method along with other operations to get the count of stream elements after applying other operations. In the following example first filter() method is used to filter out elements as per the given condition (elements should be greater than 10) then count() is used to get the count of elements in the stream after applying filter operation.

public class CountDemo {

  public static void main(String[] args) {
    List<Integer> numList = Arrays.asList(3, 5, 4, 12, 16, 0, 7, 6);
    long result = numList.stream().filter(e -> e > 10).count();
    System.out.println("Number of elements- " + result);
  }
}
Output
Number of elements- 2

3. In the following example count() is used to get the count of distinct elements.

public class CountDemo {

  public static void main(String[] args) {
    List<Integer> numList = Arrays.asList(3, 5, 5, 12, 16, 12, 3, 6);
    long result = numList.stream().distinct().count();
    System.out.println("Number of elements- " + result);
  }
}
Output
Number of elements- 5

That's all for the topic Java Stream count() With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Monday, November 22, 2021

Java Stream – Convert a Stream to Map

In this tutorial you’ll see how to convert a Stream to Map using collector method and utility methods like toMap() and groupingBy() of Collectors class in Java Stream API.

Syntax of toMap() method is as given below-

toMap(Function<? super T,? extends K> keyMapper, Function<? super T,? extends U> valueMapper)

This method returns a Collector that accumulates elements into a Map. Both of the arguments passed to the method are of type Function which is a functional interface. Using these mapping functions keyMapper and valueMapper, keys and values of the resulting Map are calculated.

1. Using Collectors.toMap() method

In the following example a list of students is collected to a Map where key is the student’s roll number and value is Student name.

Student class used is-

public class Student {
  private int rollNo;
  private String name;
  private String stream;
  private int marks;
  Student(int rollNo, String name, String stream, int marks){
    this.rollNo = rollNo;
    this.name = name;
    this.stream = stream;
    this.marks = marks;
  }
  public int getRollNo() {
    return rollNo;
  }
  public String getName() {
    return name;
  }

  public String getStream() {
    return stream;
  }

  public int getMarks() {
    return marks;
  }

  @Override
  public String toString() {
    return "Roll Number: " +  getRollNo() 
        + " Name: " + getName() + " Marks: " + getMarks();
  }
}
import java.util.Arrays;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

public class StreamToMap {

  public static void main(String[] args) {
    List<Student> studentList = Arrays.asList(new Student(1, "Mercy", "Science", 73),
              new Student(2, "Ram", "Science", 99),
              new Student(3, "Priscilla", "Art", 68),
              new Student(4, "Jacques", "Maths", 97),
              new Student(5, "Peter", "Science", 76));
    Map<Integer, String> studentMap = studentList.stream()
                          .collect(Collectors.toMap(Student::getRollNo, Student::getName));  
    System.out.println(studentMap);
  }
}
Output
{1=Mercy, 2=Ram, 3=Priscilla, 4=Jacques, 5=Peter}

If you want to collect to a Map where key is the student’s roll number and value is the student object then it can be done as. Here utility method Function.identity() is used which returns a function that always returns its input argument.

public class StreamToMap {

  public static void main(String[] args) {
    List<Student> studentList = Arrays.asList(new Student(1, "Mercy", "Science", 73),
              new Student(2, "Ram", "Science", 99),
              new Student(3, "Priscilla", "Art", 68),
              new Student(4, "Jacques", "Maths", 97),
              new Student(5, "Peter", "Science", 76));
    Map<Integer, Student> studentMap = studentList.stream()
                          .collect(Collectors.toMap(Student::getRollNo, Function.identity()));  
    System.out.println(studentMap);
  }
}
Output
{1=Roll Number: 1 Name: Mercy Marks: 73, 2=Roll Number: 2 Name: Ram Marks: 99, 3=Roll Number: 3 Name: Priscilla Marks: 68, 4=Roll Number: 4 Name: Jacques Marks: 97, 5=Roll Number: 5 Name: Peter Marks: 76}

2. Using Collectors.groupingBy() method

groupingBy() method also collects elements into a map by dividing elements into two lists of elements as per the passed grouping function. The collector produces a Map<K, List> where key specifies a group and List contains the elements which map to the associated key.

public class StreamToMap {

  public static void main(String[] args) {
    List<Student> studentList = Arrays.asList(new Student(1, "Peter", "Science", 75),
              new Student(2, "Ram", "Science", 99),
              new Student(3, "Priscilla", "Art", 68),
              new Student(4, "Mahesh", "Art", 62),
              new Student(5, "Scott", "Commerce", 72));
      Map<String, List<Student>> names = studentList.stream()
          .collect(Collectors.groupingBy(Student::getStream));
      // Iterating the returned Map
      names.entrySet().forEach(es->{System.out.println("Stream- " + es.getKey());
      System.out.println("**Students**");
      es.getValue().forEach(e->System.out.println(e.getName()));});
  }
}
Output
Stream- Art
**Students**
Priscilla
Mahesh
Stream- Science
**Students**
Peter
Ram
Stream- Commerce
**Students**
Scott

That's all for the topic Java Stream – Convert a Stream to Map. If something is missing or you have something to share about the topic please write a comment.


You may also like

Java Stream peek() With Examples

In this tutorial we’ll see how to use Java Stream peek() method with the help of few examples.

Syntax of peek() method in Java Stream API

Stream<T> peek(Consumer<? super T> action)

Argument passed to the peek method is of type Consumer functional interface which represents a non-interfering action to perform on the elements as they are consumed from the stream. Method returns a new Stream.

peek() is an intermediate operation which means using peek() without any terminal operation will do nothing.

Java 9 onward, if the number of elements in Stream source is known in advance then no source elements will be traversed and no intermediate operations like peek() will be evaluated. This is a performance optimization.

peek() method exists mainly to support debugging, where you want to see the elements as they flow from one operation to another with in the Stream pipeline.

Java Stream peek() examples

1. In this example peek() method is used to display the stream elements after each operation.

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

public class StreamPeek {

  public static void main(String[] args) {
     List<String> tempList = Stream.of("one", "two", "three", "four", "five")
         .filter(e -> e.length() > 3)
         .peek(e -> System.out.println("Filtered value: " + e))
         .map(String::toUpperCase)
         .peek(e -> System.out.println("Mapped value: " + e))
         .collect(Collectors.toList());
     
     System.out.println(tempList);
  }
}
Output
Mapped value: THREE
Filtered value: four
Mapped value: FOUR
Filtered value: five
Mapped value: FIVE
[THREE, FOUR, FIVE]

As you can see peek() method is a good way to debug your Stream and see the results of the operation on the Stream.

2. If you don’t have a terminal operation, intermediate operations like peek() are not executed. You can see that by removing the collect() operation from the previous example.

public class StreamPeek {

  public static void main(String[] args) {
    Stream.of("one", "two", "three", "four", "five")
           .filter(e -> e.length() > 3)
           .peek(e -> System.out.println("Filtered value: " + e))
           .map(String::toUpperCase)
           .peek(e -> System.out.println("Mapped value: " + e));
  }
}
On executing it you won’t get any output.

That's all for the topic Java Stream peek() With Examples. If something is missing or you have something to share about the topic please write a comment.


You may also like

Monday, November 15, 2021

Exception Propagation in Java

In the execution of the method code, if an exception condition occurs, normal flow of the method is disrupted. In order to handle the exceptional condition an exception object is created and thrown. That exception may be handled in the method where that exception is thrown or it may be passed on to be handled by other methods in the caller stack. This process of going through the method call stack to look for an exception handler that can handle the thrown exception is known as exception propagation in Java.

Exception propagation in Java

To reach to a certain method in the code, some other methods are called in between. This list of methods is known as the method call stack.

When an exception occurs in the current method, exception handling mechanism will look for an exception handler in the current method, if not found it will go to the previous method (caller method of the current method) in the call stack and so on looking for the exception handler that can handle the thrown exception.

If no exception handler is provided for the thrown exception, default exception handler will be called to handle that exception.

Exception Propagation flow

Suppose you have a call stack of three methods method1, method2 and method3. From method1 you call method2 and method3 is called from method2.

If an exception occurs in method 3 and the exception handler is in method1 then the exception propagation in Java can be shown as follows-

exception propagation in java

Exception Propagation in Java with checked and unchecked exceptions

In case of unchecked exception it is not enforced to handle the exception using try-catch block or throws clause so exception propagation happens by default.

In case of checked exception you will have to declare the exception that are not handled with in a method by using throws keyword. That is an indication that exception has to be propagated to the caller method. If caller method wishes to propagate it further then it can also declare the thrown exceptions using the throws keyword.

Exception propagation Java example with unchecked exception

Let’s take the same method hierarchy of three methods as depicted above. Where exception occurs in method3 and propagates to method1 in search of an appropriate exception handler.

public class ExceptionPropagationDemo {
  public static void main(String[] args) {
    ExceptionPropagationDemo ep = new ExceptionPropagationDemo();
    ep.method1();
  }
  // This method forwards the exception
  void method3(){
    System.out.println("In method3");
    int[] numArr = {4,5,6};
    int number = numArr[5];
  }

  // This method forwards the exception
  void method2(){
    System.out.println("In method2");
    method3();
  }
	
  // Exception is handled in this method
  void method1(){
    try{
      System.out.println("In method1");
      method2();
    } catch(Exception e){
      System.out.println("Exception handled");
      e.printStackTrace();
    }
  }
}
Output
In method1
In method2
In method3
Exception handled
java.lang.ArrayIndexOutOfBoundsException: 5
	at com.knpcode.ExceptionPropagationDemo.method3(ExceptionPropagationDemo.java:14)
	at com.knpcode.ExceptionPropagationDemo.method2(ExceptionPropagationDemo.java:20)
	at com.knpcode.ExceptionPropagationDemo.method1(ExceptionPropagationDemo.java:27)
	at com.knpcode.ExceptionPropagationDemo.main(ExceptionPropagationDemo.java:7)

In the above code exception occurs in method3 as there is an attempt to get the value at the index 5 of an array whose length is 3. This will result in ArrayIndexOutOfBoundsException being thrown. Since method3 does not provide any exception handling mechanism so next method (method 2) is searched, there also no exception handling mechanism is found so exception propagates to method1 where it is handled. You can see the same flow in the exception trace where exception originates in method3 and propagates to method1.

Exception propagation Java example with checked exception

In case of checked exception you need to explicitly specify the exceptions using throws clause if you are not providing exception handling with in the method.

Let’s see an example of exception propagation with checked exceptions. Here in method 3 there is a code to read a file and stream is also closed both of these activities may result in checked exception. Since you are forced to handle that exception so you specify it using throws clause. Notice that method2 is not providing exception handling so there also it is specified using throws clause. That way exception propagates to method1 where it is handled.

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStreamReader;

public class ExceptionPropagationDemo {
  public static void main(String[] args) {
    ExceptionPropagationDemo ep = new ExceptionPropagationDemo();
    ep.method1();
  }
  // This method forwards the exception
  void method3() throws IOException{
    System.out.println("In method3");
    BufferedReader br = null;
    try{
      br = new BufferedReader(new
          InputStreamReader(new FileInputStream(new 
              File("D:\\test1.txt"))));
    }finally{
      if(br != null)
        br.close();
    }		
  }
	
  // This method forwards the exception
  void method2() throws IOException{
    System.out.println("In method2");
    method3();
  }
	
  // Exception is handled in this method
  void method1(){
    try{
      System.out.println("In method1");
      method2();
    } catch(IOException e){
      System.out.println("Exception handled");
      e.printStackTrace();
    }
  }
}
Output
In method1
In method2
In method3
Exception handled
java.io.FileNotFoundException: D:\test1.txt (The system cannot find the file specified)
	at java.io.FileInputStream.open0(Native Method)
	at java.io.FileInputStream.open(Unknown Source)
	at java.io.FileInputStream.(Unknown Source)
	at com.knpcode.ExceptionPropagationDemo.method3(ExceptionPropagationDemo.java:22)
	at com.knpcode.ExceptionPropagationDemo.method2(ExceptionPropagationDemo.java:34)
	at com.knpcode.ExceptionPropagationDemo.method1(ExceptionPropagationDemo.java:41)
	at com.knpcode.ExceptionPropagationDemo.main(ExceptionPropagationDemo.java:13)

That's all for the topic Exception Propagation in Java. If something is missing or you have something to share about the topic please write a comment.


You may also like