Java 8 - Stream and Filter

 
Stream API:
A stream gives a set of elements of specific type in a sequential order and it gets/computes elements on demand. But never stores the elements one the stream is been processed. Same thing we see in the below example.

Filter:
Applying filter on stream while computing and geting only the elements on specified conditions satisfied.

Java 8 - Stream and Filter

Before Java 8 if we need to filter some values on List, then only the option is to iterate on each element by External Iterator (for each loop). But in Java 8 we can use filter on top of stream to get those filtered elements from the given List. Lets see simple example as how to stream and then using filter on it to collect the final elements which we need from the list.


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

public class StreamFilter {

 public static void main(String[] args) {
  
  Stream<String> language = Stream.of("java", ".net", "python", "nodejs","angular");
  
  //List will contain all the elements from stream
  List<String> listAllLanguages = language.collect(Collectors.toList());
  System.out.println("**** All Elements ****");
  listAllLanguages.forEach(System.out::println);
  



  /* Here we can see stream getting empty and throwing IllegalStateException
  * if we didn't recreate stream again. Since all the elements are streamed already
  * and stream will be empty as of now. 
  */ 
  language = Stream.of("java", ".net", "python", "nodejs","angular");
  // Using filter as all elements except ".net"
  List<String> listFilterLanguage = language.filter(lang -> !".net".equals(lang)).collect(Collectors.toList());
  System.out.println("\n**** Using filter as all elements except \".net\" ****");
  listFilterLanguage.forEach(System.out::println);
 }
}


OUTPUT:


**** All Elements ****
java
.net
python
nodejs
angular

**** Using filter as all elements except ".net" ****
java
python
nodejs
angular

Java 8 - ForEach loop

Introduced in Java 8, the forEach loop provides programmers a new concise and interesting way for iterating over a list of elements. We will see how to use forEach with collections, what kind of argument it takes and how this loop differs from the enhanced for-loop. In java 8 with forEach, we can iterate over a collection and perform a given action on each element – by just passing a class that implements the Consumer interface

Java 8 ForEach


Consumer Interface

Consumer interface is a functional interface (an interface with a single abstract method). It accepts an input and returns no result

Both forEach and For Loop provide the same functionality. Looping through elements in a collection and only the main difference between the two of them is that they are different iterators – the enhanced for-loop is an external iterator whereas the new forEach method is an internal one.

Internal Iterator - iterator manage the iteration in the background and leaves the programmer to just code what is meant to be done with the elements of the collection, rather than managing the iteration and making sure that all the elements are processed one-by-one.

External Iterator - If need more control on the iterator and need to preform some checks and operation on each element then External Iterator can be used.

Lambda Expression - lambda expression is an anonymous representation of a function descriptor of a functional interface.

Method Reference - where a method already exists to perform an operation on the class, this syntax can be used instead of the normal lambda expression

All these types are listed in the below sample program and we can get to know about each of these implementation in Java 8



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

public class Java8For {

 public static void main(String[] args) {
  
  Stream<String> language = Stream.of("java", ".net", "python", "nodejs","angular");
  List<String> listLanguages = language.collect(Collectors.toList());

  
  // Consumer Interface
  System.out.println("\n**** Consumer Interface ****");
        Consumer<String> languages = lang -> {
            System.out.println(lang);
        };
        listLanguages.forEach(languages);
        
        
        
        // Internal iterator & Lambda Expression
  System.out.println("\n**** Internal iterator & Lambda Expression ****");
  listLanguages.forEach(results -> System.out.println(results));

        
        
        //External Iterator 
  System.out.println("\n**** External Iterator  ****");
        for (String string : listLanguages) {
   System.out.println(string);
  }
        
        
        
        //Method Reference
  System.out.println("\n**** Method Reference ****");
  listLanguages.forEach(System.out::println);
 }
}


OUTPUT:


**** Consumer Interface ****
java
.net
python
nodejs
angular

**** Internal iterator & Lambda Expression ****
java
.net
python
nodejs
angular

**** External Iterator  ****
java
.net
python
nodejs
angular

**** Method Reference ****
java
.net
python
nodejs
angular

Java 8 - StringJoiner with examples

StringJoiner is used to construct a sequence of characters separated by a delimiter and optionally starting with a supplied prefix and ending with a supplied suffix. Internally StringJoiner uses the String.join()

Java 8 - StringJoiner


Lets see simple examples with various uses of StringJoiner class.
  • Joning string by delimiter
  • Other way to join string with delimiter
  • List to string
  • Adding delimiter, prefix and suffix
  • Using setEmptyValue() method
  • Using setEmptyValue() method - Same after adding some value
  • Merging 2 string joiner 

public class StringJoiners {

 public static void main(String[] args) {
  
  //Joning string by delimiter
  StringJoiner sj = new StringJoiner(",");
  sj.add("Java");
  sj.add("Discover");
  sj.add("2018");
  System.out.println("Joning string by delimiter :: "+ sj.toString());
  
  
  
  //Other way to join string with delimiter
  String str = String.join(",", "JAVA", "DISCOVER", "2018");
  System.out.println("\nOther way : "+str);
  
  
  //List to string
  List<String> list = Arrays.asList("Java", "String", "Joiner");
  String str1 = String.join(", ", list);
  System.out.println("\nList to string : "+str1);
  
  
  //Adding delimiter, prefix and suffix
  StringJoiner sj1 = new StringJoiner(".","Hello "," :)");
  sj1.add("Java");
  sj1.add("Discover");
  sj1.add("2018");
  System.out.println("\nAdding delimiter, prefix and suffix :: "+ sj1.toString());
  
  
  
  /*
   * Using setEmptyValue() method - set default value of the string
   * if string is empty
   */
  StringJoiner sj2 = new StringJoiner("*");   
  sj2.setEmptyValue("DEFUALT EMPTY STRING");
  System.out.println("\nUsing setEmptyValue() method-1 :: "+ sj2.toString() + " ---- LENGTH : "+sj2.toString().length());
  

  // Same after adding some value
  sj2.add("ORACLE");
  sj2.add("LAMBDA");
  System.out.println("\nUsing setEmptyValue() method-2 :: "+ sj2.toString() + " ---- LENGTH : "+sj2.toString().length());
  
  
  
  //Merging 2 string joiner 
  StringJoiner sj3 = sj1.merge(sj2);
  System.out.println("\nMerging 2 string joiner :: "+sj3.toString());
 }
}

OUTPUT:


Joning string by delimiter :: Java,Discover,2018

Other way : JAVA,DISCOVER,2018

List to string : Java, String, Joiner

Adding delimiter, prefix and suffix :: Hello Java.Discover.2018 :)

Using setEmptyValue() method-1 :: DEFUALT EMPTY STRING ---- LENGTH : 20

Using setEmptyValue() method-2 :: ORACLE*LAMBDA ---- LENGTH : 13

Merging 2 string joiner :: Hello Java.Discover.2018.ORACLE*LAMBDA :)

Selection sort

 
Selection sort is conceptually the most simplest sorting algorithm. This algorithm will first find the smallest element in the array and swap it with the element in the first position, then it will find the second smallest element and swap it with the element in the second position, and it will keep on doing this until the entire array is sorted. It is called selection sort because it repeatedly selects the next-smallest element and swaps it into the right place.
Selection Sort


public class SelectionSort {

 public static void main(String[] args) {

  int[] arr = { 4, 14, 6, 15, 8, 0, 313, 80, 21, 67, 81, 142 };

  printArray(arr, "BEFORE SORTING : ");

  selectionSort(arr);

  printArray(arr, "AFTER SORTING : ");
 }

 public static void selectionSort(int[] arr) {

  for (int i = 0; i < arr.length; i++) {
   int minIndex = i;
   for (int j = i + 1; j < arr.length; j++) {
    if (arr[j] < arr[minIndex]) {
     minIndex = j;
    }
   }
   if (minIndex != i) {
    int tmp = arr[i];
    arr[i] = arr[minIndex];
    arr[minIndex] = tmp;
   }
  }
 }

 public static void printArray(int[] arr, String msg) {
  System.out.print(msg);
  for (int i : arr) {
   System.out.print(i + ", ");
  }
  System.out.println();
 }
}


OUTPUT:


BEFORE SORTING : 4, 14, 6, 15, 8, 0, 313, 80, 21, 67, 81, 142, 
AFTER SORTING : 0, 4, 6, 8, 14, 15, 21, 67, 80, 81, 142, 313, 

Convert a Binary Tree into its Mirror Tree

Mirror of a Tree: Mirror of a Binary Tree T is another Binary Tree M(T) with left and right children of all non-leaf nodes interchanged as given below example.


Mirroring Binary Tree


public class MirroringBinaryTree {

 class NODE {

  int data;
  NODE left;
  NODE right;

  public NODE(int data) {
   this.data = data;
   left = right = null;
  }
 }

 public static void main(String[] args) {

  MirroringBinaryTree obj = new MirroringBinaryTree();

  int val[] = new int[] { 23, 34, 12, 10, 36, 35, 40, 55 };

  NODE root = obj.createBinaryTree(val);

  System.out.print("\n\n INORDER ::::::: ");
  obj.inOrderTraversal(root);

  root = obj.mirror(root);

  System.out.print("\n\n INORDER AFTER MIRROR::::::: ");
  obj.inOrderTraversal(root);
 }

 /*
  * Mirror the binary tree
  */
 public NODE mirror(NODE node) {
  if (node == null)
   return node;

  NODE left = mirror(node.left);
  NODE right = mirror(node.right);

  /* swap left and right pointers */
  node.left = right;
  node.right = left;

  return node;
 }

 /*
  *  BST in-order traversal
  */
 public void inOrderTraversal(NODE root) {

  if (root.left != null) {
   inOrderTraversal(root.left);
  }

  System.out.print(root.data + ", ");

  if (root.right != null) {
   inOrderTraversal(root.right);
  }
 }

 /*
  * Create binary tree by given array
  */
 public NODE createBinaryTree(int val[]) {
  NODE root = null;
  for (int i : val) {
   NODE tmp = new NODE(i);
   if (root == null) {
    root = tmp;
   } else {
    NODE lastNode = getLastNode(root, i);
    if (i > lastNode.data) {
     lastNode.right = tmp;
    } else {
     lastNode.left = tmp;
    }
   }
  }
  return root;
 }

 /*
  * Get parent node the join current node
  */
 public NODE getLastNode(NODE root, int val) {

  if (val > root.data) {

   if (root.right == null) {
    return root;
   } else
    return getLastNode(root.right, val);
  } else {

   if (root.left == null) {
    return root;
   } else
    return getLastNode(root.left, val);
  }
 }
}


OUTPUT:


 INORDER ::::::: 10, 12, 23, 34, 35, 36, 40, 55, 

 INORDER AFTER MIRROR::::::: 55, 40, 36, 35, 34, 23, 12, 10, 

Find the middle node of a given linked list

Given a singly linked list, find the middle NODE of the linked list. For example, if given linked list is 1->2->3->4->5 then output should be 3.
If there are even nodes, then there would be two middle nodes, we need to print second middle element. For example, if given linked list is 1->2->3->4->5->6 then output should be 4.
CONDITION:
  • Need to traverse the linked list only once. 


Find middle node of a given linked list



public class MiddleNode {

 class NODE {
  
  int data;
  NODE next;

  public NODE(int data) {
   this.data = data;
   this.next = null;
  }
 }
 
 public static void main(String[] args) {

  MiddleNode obj = new MiddleNode();

  int val[] = new int[] { 3, 6, 7, 8, 9, 11, 13, 15, 17, 22, 24, 25, 28};
  
  /* Create linked list */
  NODE start = obj.createLinkedList(val);
  
  /* Get middle NODE */
  NODE middleNode = obj.getMiddleNode(start);
  
  System.out.println("MIDDLE NODE : "+middleNode.data);
 }
 
 /*
  * Create linked base based on given array
  */
 public NODE createLinkedList(int val[]) {
  NODE start = null;
  for (int i : val) {
   NODE tmp = new NODE(i);
   if (start == null) {
    start = tmp;
   } else {
    NODE mover = start;
    while (mover.next != null) {
     mover = mover.next;
    }
    mover.next = tmp;
   }
  }
  return start;
 }
 
 /*
  * Getting middle NODE just by traversing only once
  */
 public NODE getMiddleNode(NODE start) {
  NODE slow = start, fast = start;
  while(fast.next != null && fast.next.next != null) {
   slow = slow.next;
   fast = fast.next.next;
  }
  if(fast.next != null) {
   slow = slow.next;
  }
  return slow;
 }
}

OUTPUT:


MIDDLE NODE : 13

Remove all consecutive duplicates from the string

Given a string S, remove all the consecutive duplicates and note that this problem is different from Recursively remove all adjacent duplicates. Here we keep one character and remove all subsequent same characters.
For Example:
Input  : aaaaabbbbbb
Output : ab

Input : sweetinsweet
Output : swetinswet

Input : aabccba
Output : abcba

public class RemoveDuplicate {

 public static void main(String[] args) {

  String str = "aabccba";
  char[] cStr = new char[str.length()];
  int i, k = 0;
  for (i = 0; i < str.length(); i++) {

   if (i == 0) {
    cStr[k++] = str.charAt(i);
   } else {
    if (str.charAt(i) != cStr[k - 1]) {
     cStr[k++] = str.charAt(i);
    }
   }
  }
  str = String.valueOf(cStr, 0, k);
  System.out.println(str);
 }
}
OUTPUT:

abcba


Rotate array by N elements

Given an array, cyclically rotate the array clockwise by N elements. The conditions are 

  • Should NOT use temporary array to store values
  • N should be > 0 and <= given array size
Sample:

Array Rotate

We will see how to rotate the array by two ways.

  • 1st lets see simple solution that takes 1st element and swap with last element for N times and each time array values will be moved 1 position front like arr[i] = arr[i+1]
  • 2nd lets see swapping 0th to xth all elements, next swapping all from xth to last element and finally swapping all elements from 0th to last element with 3 for loops independently. 


METHOD-1:

public class ArrayRotate {

 public static void main(String[] args) {

  int array[] = { 1, 2, 3, 4, 5, 6, 7, 8, 9, 10 };

  printArray("BEFORE ROTATE :::: ", array);

  rotate(array, 5);

  printArray("AFTER ROTATE ::::: ", array);

 }

 private static void printArray(String txt, int array[]) {
  System.out.print(txt + " ::: ");
  for (int i : array) {
   System.out.print(i + ", ");
  }
  System.out.println();
 }

 private static void rotate(int[] array, int startLoc) {

  if (startLoc < 0 || startLoc > array.length) {
   System.out.println("Out of array index !!!");
   return;
  }

  for (int i = 0; i < startLoc - 1; i++) {
   int tmp = array[0];
   for (int j = 0; j < array.length - 1; j++) {
    array[j] = array[j + 1];
   }
   array[array.length - 1] = tmp;
  }
 }
}

OUTPUT:

BEFORE ROTATE ::::  ::: 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 
AFTER ROTATE :::::  ::: 5, 6, 7, 8, 9, 10, 1, 2, 3, 4, 



METHOD-2:


public class RotateArray {

 public static void main(String[] args) {

  int array[] = { 11, 12, 13, 14, 15, 16, 17, 18, 19, 20 };

  printArray("BEFORE ROTATE :::: ", array);

  rotate(array, 5);

  printArray("AFTER ROTATE ::::: ", array);

 }

 private static void printArray(String txt, int array[]) {
  System.out.print(txt + " ::: ");
  for (int i : array) {
   System.out.print(i + ", ");
  }
  System.out.println();
 }

 private static void rotate(int[] array, int startLoc) {
  
  if (startLoc < 0 || startLoc > array.length) {
      System.out.println("Out of array index !!!");
      return;
  }
  
  for(int i=0,j=startLoc-2;i<j;i++,j--) {
   int tmp = array[i];
   array[i] = array[j];
   array[j] = tmp;
  }
  
  for(int i=startLoc-1,j=array.length-1;i<j;i++,j--) {
   int tmp = array[i];
   array[i] = array[j];
   array[j] = tmp;
  }

  for(int i=0,j=array.length-1;i<j;i++,j--) {
   int tmp = array[i];
   array[i] = array[j];
   array[j] = tmp;
  }
 }
}


OUTPUT:


BEFORE ROTATE ::::  ::: 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 
AFTER ROTATE :::::  ::: 15, 16, 17, 18, 19, 20, 11, 12, 13, 14,