How can use HashSet to solve Array related Problems

Today I was solving some array related problems on GeeksForGeeks,

Came across with solution How Hashset helped me to solve these problems for large amount of input within given time complexity.

Here is the problem statements I have solved:-

Problem Statement:- Pair with given sum in a sorted array

Solution :-
import java.util.*;
import java.lang.*;
import java.io.*;

class GFG {
    public static void main (String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
        while(T --> 0){
            int N = Integer.parseInt(br.readLine());
           
            String str = br.readLine();
            String[] inputArr = str.trim().split("\\s+");
            int A[] = new int[N];
            for(int i=0;i<N;i++){
                A[i] = Integer.parseInt(inputArr[i]);
            }
            int K = Integer.parseInt(br.readLine());
           
            int low = 0;
            int high = N-1;
            boolean flag = true;
            while(low<high){
                if(A[low]+A[high] > K){
                    high--;
                }else if(A[low]+A[high] < K){
                    low++;
                }else{
                    System.out.println(A[low]+" "+A[high] + " "+ K);
                    low++;
                    flag = false;
                }
            }
            if(flag){
                System.out.println(-1);
            }           
        }
    }
}


Problem Statement:- Triplet Sum in Array

Solution :-
import java.util.*;
import java.lang.*;
import java.io.*;

class GFG {
    public static void main (String[] args) throws IOException{
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        int T = Integer.parseInt(br.readLine());
        while(T --> 0){
            String input = br.readLine();
            String[] inputArry = input.trim().split("\\s+");
            int N = Integer.parseInt(inputArry[0]);
            int X = Integer.parseInt(inputArry[1]);
            String arrInp = br.readLine();
            String[] arr = arrInp.trim().split("\\s+");
            int[] A = new int[N];
            for(int i=0;i<N;i++){
                A[i] = Integer.parseInt(arr[i]);
            }
            Set<Integer> sumSet = new HashSet<>();
            boolean flag= true;
            for(int i=0;i<N;i++){
                if(sumSet.contains(X-A[i])){
                    System.out.println("1");
                    flag = false;
                    break;
                }else{
                    for(int j=0;j<=i;j++){
                        sumSet.add(A[i]+A[j]);
                    }
                }
            }
            if(flag){
                System.out.println("0");
            }
        }
    }
}

First non repeating word in string.

public String firstNonRepeatingword(String string) {
        if(string == null || string.isEmpty()) {
            return "No unique word found";
        }else {
            StringTokenizer tokens = new StringTokenizer(string);
            LinkedList<String> list = new LinkedList<>();
            while(tokens.hasMoreTokens()) {
                list.add(tokens.nextToken());
            }
            for(int i=0;i<list.size();i++) {
                if (Collections.frequency(list,list.get(i)) == 1) {
                    return list.get(i);
                }
            }
        }
        return "No unique word found";
    }

It's up to you how are you spliting the string there are many ways, If you have small string tokenizer is fast.

Performance of StringTokenizer class vs. String.split method vs indexOf 

Difference between final and effectively final


final variable: A variable or parameter is declared as final and whose value is never changed after it is initialized is final.

effectively final variable: A variable or parameter is not declared as final and still the whose value is never changed after it is initialized is effectively final.
public class Demo {
 public static void main(String[] args) {
 int count = 0;
 List list = new ArrayList() {{
    add("employee1"); 
    add("employee2"); 
    add("employee3"); 
    add("employee4"); 
 }}; 
 list.stream().forEach(str -> { count++; });
 } 
}
here the error on count++ :-
Local variable count defined in an enclosing scope must be final or effectively final.

here the variable count is not declared as final but it is still a final variable and its value will not be changed, the count varibale here is effectively final variable

Prefer to return empty Object instead of null


There are many cases in which we can return an empty object instead of null. This is usually preferable since it helps to eliminate one of the most common problem: NullPointerException

Following qualify as empty object :
  • Empty String
  • zero-length Array
  • empty collection

Examples for empty object:-
  • String str = "";
  • int[] values = new int[0];
  • List<Integer> list = new ArrayList<>();

Collections class contains several type-safe methods which return an empty collection

Collections.emptyList();
Collections.emptySet();
Collections.emptyMap();

by default, these methods are also immutable and serializable.

Double Brace initialization

It creates an anonymous class derived from the specified class (the outer braces), and provide an initializer block within that class (the inner braces). e.g.

new ArrayList() { { 
   add("you"); 
   add("me"); 
} }

Bill Pugh Singleton Implementation

We all know different flavors of singleton design pattern and we are using one of them in our daily life.

Eager Initialization
Static Block initialization (type of eager initialization but we initialize the object in static block with exception handling)
Lazy Initialization
Thread Safe Singleton
Double checked locking (to overcome the race condition)
Enum Singleton (Enums are lazily initialized by JVM and enums are thread safe too)

Here I will discuss one approach which I didn't Include in above approaches

Bill Pugh Singleton Implementation

Prior to Java, 1.5  Java Memory Model had a lot of Issues and the above Approaches used to fail in certain scenarios where too many threads try to get the instance of singleton class simultaneously.

So this Implementation comes with a different approach where it creates singleton class using the inner static helper class.

Implementation will be like : -
public class BillPughSingleton {
    private BillPughSingleton(){ }
    private static class SingletonBuilder {
           private static final BillPughSingleton INSTANCE = new BillPughSingleton();
    }
    public static BillPughSingleton getInstance(){
           return SingletonBuilder.INSTANCE;
    }
}


The best thing about this approach is when the Singleton class is loaded, SingletonBuilder will not be loaded and only loaded when someone will call getInstance() method, and it doesn't require synchronization too.

Functional programming with Java - Part 1

 Recently I was reviewing one PR raised by team memeber and going through one utitlity method and found out there are too many muatable vari...