Friday, October 30, 2020

Differences between HashMap and HashTable in Java

Oracle Java Tutorial and Material, Oracle Java Exam Prep, Oracle Java Certification

HashMap and Hashtable store key/value pairs in a hash table. When using a Hashtable or HashMap, we specify an object that is used as a key, and the value that you want linked to that key. The key is then hashed, and the resulting hash code is used as the index at which the value is stored within the table.

Sample Java code.

// A sample Java program to demonstrate HashMap and HashTable 

import java.util.*; 

import java.lang.*; 

import java.io.*; 

/* Name of the class has to be "Main" only if the class is public. */

class Ideone 

public static void main(String args[]) 

//----------hashtable ------------------------- 

Hashtable<Integer,String> ht=new Hashtable<Integer,String>(); 

ht.put(101," ajay"); 

ht.put(101,"Vijay"); 

ht.put(102,"Ravi"); 

ht.put(103,"Rahul"); 

System.out.println("-------------Hash table--------------"); 

for (Map.Entry m:ht.entrySet()) { 

System.out.println(m.getKey()+" "+m.getValue()); 


//----------------hashmap-------------------------------- 

HashMap<Integer,String> hm=new HashMap<Integer,String>(); 

hm.put(100,"Amit"); 

hm.put(104,"Amit"); 

hm.put(101,"Vijay"); 

hm.put(102,"Rahul"); 

System.out.println("-----------Hash map-----------"); 

for (Map.Entry m:hm.entrySet()) { 

System.out.println(m.getKey()+" "+m.getValue()); 

Output:

-------------Hash table--------------
103 Rahul
102 Ravi
101 Vijay
-----------Hash map-----------
100 Amit
101 Vijay
102 Rahul
104 Amit

Hashmap vs Hashtable


Oracle Java Tutorial and Material, Oracle Java Exam Prep, Oracle Java Certification
1. HashMap is non synchronized. It is not-thread safe and can’t be shared between many threads without proper synchronization code whereas Hashtable is synchronized. It is thread-safe and can be shared with many threads.
2. HashMap allows one null key and multiple null values whereas Hashtable doesn’t allow any null key or value.
3. HashMap is generally preferred over HashTable if thread synchronization is not needed

Why HashTable doesn’t allow null and HashMap does?


To successfully store and retrieve objects from a HashTable, the objects used as keys must implement the hashCode method and the equals method. Since null is not an object, it can’t implement these methods. HashMap is an advanced version and improvement on the Hashtable. HashMap was created later.

Wednesday, October 28, 2020

Comparator Interface in Java with Examples

Oracle Java Tutorial and Material, Java Certification, Oracle Java Exam Prep, Java Guides, Oracle Java Learning

Comparator interface is used to order the objects of user-defined classes. A comparator object is capable of comparing two objects of two different classes. Following function compare obj1 with obj2

Syntax: 

public int compare(Object obj1, Object obj2):

Suppose we have an array/arraylist of our own class type, containing fields like rollno, name, address, DOB etc and we need to sort the array based on Roll no or name?

Method 1: One obvious approach is to write our own sort() function using one of the standard algorithms. This solution requires rewriting the whole sorting code for different criterion like Roll No. and Name.

Method 2: Using comparator interface- Comparator interface is used to order the objects of user-defined class. This interface is present in java.util package and contains 2 methods compare(Object obj1, Object obj2) and equals(Object element). Using comparator, we can sort the elements based on data members. For instance it may be on rollno, name, age or anything else.

Method of Collections class for sorting List elements is used to sort the elements of List by the given comparator. 

// To sort a given list. ComparatorClass must implement 

// Comparator interface.

public void sort(List list, ComparatorClass c)

How does Collections.Sort() work? 


Internally the Sort method does call Compare method of the classes it is sorting. To compare two elements, it asks “Which is greater?” Compare method returns -1, 0 or 1 to say if it is less than, equal, or greater to the other. It uses this result to then determine if they should be swapped for its sort.

Working Program:

// Java program to demonstrate working of Comparator 
// interface 
import java.util.*; 
import java.lang.*; 
import java.io.*; 

// A class to represent a student. 
class Student 
int rollno; 
String name, address; 

// Constructor 
public Student(int rollno, String name, 
String address) 
this.rollno = rollno; 
this.name = name; 
this.address = address; 

// Used to print student details in main() 
public String toString() 
return this.rollno + " " + this.name + 
" " + this.address; 

class Sortbyroll implements Comparator<Student> 
// Used for sorting in ascending order of 
// roll number 
public int compare(Student a, Student b) 
return a.rollno - b.rollno; 

class Sortbyname implements Comparator<Student> 
// Used for sorting in ascending order of 
// roll name 
public int compare(Student a, Student b) 
return a.name.compareTo(b.name); 

// Driver class 
class Main 
public static void main (String[] args) 
ArrayList<Student> ar = new ArrayList<Student>(); 
ar.add(new Student(111, "bbbb", "london")); 
ar.add(new Student(131, "aaaa", "nyc")); 
ar.add(new Student(121, "cccc", "jaipur")); 

System.out.println("Unsorted"); 
for (int i=0; i<ar.size(); i++) 
System.out.println(ar.get(i)); 

Collections.sort(ar, new Sortbyroll()); 

System.out.println("\nSorted by rollno"); 
for (int i=0; i<ar.size(); i++) 
System.out.println(ar.get(i)); 

Collections.sort(ar, new Sortbyname()); 

System.out.println("\nSorted by name"); 
for (int i=0; i<ar.size(); i++) 
System.out.println(ar.get(i)); 

Output: 

Unsorted
111 bbbb london
131 aaaa nyc
121 cccc jaipur

Sorted by rollno
111 bbbb london
121 cccc jaipur
131 aaaa nyc

Sorted by name
131 aaaa nyc
111 bbbb london
121 cccc jaipur

By changing the return value in inside compare method you can sort in any order you want. eg.for descending order just change the positions of a and b in above compare method.

Sort collection by more than one field:


Oracle Java Tutorial and Material, Java Certification, Oracle Java Exam Prep, Java Guides, Oracle Java Learning
We have discussed how to sort list of objects on the basis of single field using Comparable and Comparator interface But, what if we have a requirement to sort ArrayList objects in accordance with more than one fields like firstly sort, according to the student name and secondly sort according to student age.

Below is the implementation of above approach:

// Java program to demonstrate working of Comparator 
// interface more than one field 

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

class Student { 

// instance member variables 
String Name; 
int Age; 

// parameterized constructor 
public Student(String Name, Integer Age) { 
this.Name = Name; 
this.Age = Age; 

public String getName() { 
return Name; 

public void setName(String Name) { 
this.Name = Name; 

public Integer getAge() { 
return Age; 

public void setAge(Integer Age) { 
this.Age = Age; 

// overriding toString() method 
@Override
public String toString() { 
return "Customer{" + "Name=" + Name + ", Age=" + Age + '}'; 

static class CustomerSortingComparator implements Comparator<Student> { 

@Override
public int compare(Student customer1, Student customer2) { 

// for comparison 
int NameCompare = customer1.getName().compareTo(customer2.getName()); 
int AgeCompare = customer1.getAge().compareTo(customer2.getAge()); 

// 2-level comparison using if-else block 
if (NameCompare == 0) { 
return ((AgeCompare == 0) ? NameCompare : AgeCompare); 
} else { 
return NameCompare; 

public static void main(String[] args) { 

// create ArrayList to store Student 
List<Student> al = new ArrayList<>(); 

// create customer objects using constructor initialization 
Student obj1 = new Student("Ajay", 27); 
Student obj2 = new Student("Sneha", 23); 
Student obj3 = new Student("Simran", 37); 
Student obj4 = new Student("Ajay", 22); 
Student obj5 = new Student("Ajay", 29); 
Student obj6 = new Student("Sneha", 22); 

// add customer objects to ArrayList 
al.add(obj1); 
al.add(obj2); 
al.add(obj3); 
al.add(obj4); 
al.add(obj5); 
al.add(obj6); 

// before Sorting arraylist: iterate using Iterator 
Iterator<Student> custIterator = al.iterator(); 

System.out.println("Before Sorting:\n"); 
while (custIterator.hasNext()) { 
System.out.println(custIterator.next()); 

// sorting using Collections.sort(al, comparator); 
Collections.sort(al, new CustomerSortingComparator()); 

// after Sorting arraylist: iterate using enhanced for-loop 
System.out.println("\n\nAfter Sorting:\n"); 
for (Student customer : al) { 
System.out.println(customer); 

Output:

Before Sorting:

Customer{Name=Ajay, Age=27}
Customer{Name=Sneha, Age=23}
Customer{Name=Simran, Age=37}
Customer{Name=Ajay, Age=22}
Customer{Name=Ajay, Age=29}
Customer{Name=Sneha, Age=22}

After Sorting:

Customer{Name=Ajay, Age=22}
Customer{Name=Ajay, Age=27}
Customer{Name=Ajay, Age=29}
Customer{Name=Simran, Age=37}
Customer{Name=Sneha, Age=22}
Customer{Name=Sneha, Age=23}

Tuesday, October 27, 2020

Scanner Class in Java

Scanner Class in Java, Oracle Java Tutorial and Material, Oracle Java Certification

Scanner is a class in java.util package used for obtaining the input of the primitive types like int, double, etc. and strings. It is the easiest way to read input in a Java program, though not very efficient if you want an input method for scenarios where time is a constraint like in competitive programming.

◉ To create an object of Scanner class, we usually pass the predefined object System.in, which represents the standard input stream. We may pass an object of class File if we want to read input from a file.

◉ To read numerical values of a certain data type XYZ, the function to use is nextXYZ(). For example, to read a value of type short, we can use nextShort()

◉ To read strings, we use nextLine().

◉ To read a single character, we use next().charAt(0). next() function returns the next token/word in the input as a string and charAt(0) function returns the first character in that string.

Let us look at the code snippet to read data of various data types.

// Java program to read data of various types using Scanner class. 

import java.util.Scanner; 

public class ScannerDemo1 

public static void main(String[] args) 

// Declare the object and initialize with 

// predefined standard input object 

Scanner sc = new Scanner(System.in); 


// String input 

String name = sc.nextLine(); 


// Character input 

char gender = sc.next().charAt(0); 


// Numerical data input 

// byte, short and float can be read 

// using similar-named functions. 

int age = sc.nextInt(); 

long mobileNo = sc.nextLong(); 

double cgpa = sc.nextDouble(); 


// Print the values to check if the input was correctly obtained. 

System.out.println("Name: "+name); 

System.out.println("Gender: "+gender); 

System.out.println("Age: "+age); 

System.out.println("Mobile Number: "+mobileNo); 

System.out.println("CGPA: "+cgpa); 

Input :

Oracle
F
40
9876543210
9.9

Output :

Name: Oracle
Gender: F
Age: 40
Mobile Number: 9876543210
CGPA: 9.9

Sometimes, we have to check if the next value we read is of a certain type or if the input has ended (EOF marker encountered).

Scanner Class in Java, Oracle Java Tutorial and Material, Oracle Java Certification
Then, we check if the scanner’s input is of the type we want with the help of hasNextXYZ() functions where XYZ is the type we are interested in. The function returns true if the scanner has a token of that type, otherwise false. For example, in the below code, we have used hasNextInt(). To check for a string, we use hasNextLine(). Similarly, to check for a single character, we use hasNext().charAt(0).

Let us look at the code snippet to read some numbers from console and print their mean.

// Java program to read some values using Scanner 
// class and print their mean. 
import java.util.Scanner; 

public class ScannerDemo2 
public static void main(String[] args) 
// Declare an object and initialize with 
// predefined standard input object 
Scanner sc = new Scanner(System.in); 

// Initialize sum and count of input elements 
int sum = 0, count = 0; 

// Check if an int value is available 
while (sc.hasNextInt()) 
// Read an int value 
int num = sc.nextInt(); 
sum += num; 
count++; 
int mean = sum / count; 
System.out.println("Mean: " + mean); 

Input:

101
223
238
892
99
500
728

Output:

Mean: 397

Monday, October 26, 2020

Start a Java app without installing it

Oracle Java Tutorial and Material, Oracle Java Learning, Oracle Java Guides, Oracle Java Exam Prep

This article describes how you can use JShell to download and execute a Java application. It will eliminate the need for the installation of the application.

Do not install, just run!

The first obstacle that you have to overcome to make people use your app is the installation.

You want people to use the app, try it out.

To do that, they first have to install it.

At least they have to download it and type in a command line to start it up.

If your program is excellent and valuable for the users, they will use it after this step.

They will see that it works and can do what it is supposed to do.

Before the installation, however, this is a bit different.

Users will install the program if they really, really need it.

Installation is undoubtedly an entry threshold.

Jamal as Example

My example is Jamal that you can download at https://github.com/verhas/jamal.

I wrote the first version twenty years ago, and I named it Jamal.

The name stands for Just Another Macro language, which I intended to be sarcastic.

I thought it was sarcastic because it was so much more different than any other text macro applications.

It seems the name was not interpreted as sarcastic but rather literally.

Users saw it really as “just another” and it did not become widespread.

A few people bothered to install it.

Now I have a Java version, which is even more versatile and powerful than the previous version.

However, if you wanted to use it, you had to install it and start it up with a relatively complex java -cp ... command line.

My first attempt to overcome this was to create a Maven plugin.

A maven plugin executes without installing it.

If you have installed Maven, all you need to run a plugin is a Maven command line.

A kind of complex one, though.

Or it would help if you had a pom.xml.

I also created the Maven plugin version because I used Jamal to maintain the pom.xml files with Jamal preprocessed.

That way, as you can see in an earlier article, I can write

{dependencyManagement|{dependencies|

    {@for MODULE in (testsupport,api,core,tools,engine,extensions)={dependency :com.javax0.jamal:jamal-MODULE:{VERSION}}}

    {@for MODULE in (api,engine,params)={dependency :org.junit.jupiter:junit-jupiter-MODULE:5.2.0:test}}

    }}

instead of a much longer and redundant XML fragment.

This source, pom.xml.jam is then converted to pom.xml, and Maven runs fine.

The solution can still be better because many people do not use Maven.

Jamal is not a Maven dependent tool.

I also use a different project to *.md.jam files to edit my next book.

A book, as a project, does not require Maven.

This book is not a Java book.

I happen to have Maven on my machine, but the project does not need that.

There is no reason to require installed Maven as a precondition.

There is one precondition that I have to require, and that is an installed Java JDK.

I cannot skip that because Jamal is written in Java.

You can also miss this precondition if you have docker, but then you need docker.

However, if you have the JDK installed (at least Java 9), you can quickly start a JShell.

JShell executes the Java code from some input file that you specify on the command line.

If you want to start Jamal, then the command is:

jshell https://raw.githubusercontent.com/verhas/jamal/master/jamal-cmd/jamal.jsh

The command file is on GitHub, and JShell can download it from there.

This command file downloads the JAR files needed to run Jamal, and then it starts Jamal in a separate process.

The actual script splits into separate parts, and the jamal.jsh content is

/open scripts/version.jsh

/open scripts/jarfetcher.jsh

/open scripts/executor.jsh

/open scripts/optionloader.jsh

/open scripts/defaultoptions.jsh

download("01engine/jamal-engine")

download("02api/jamal-api")

download("03tools/jamal-tools")

download("04core/jamal-core")

download("08cmd/jamal-cmd")

loadOptions()

for(String jarUrl:extraJars){

    LOCAL_CACHE.mkdirs();

    downloadUrl(jarUrl,LOCAL_CACHE);

    }

execute()

/exit

As you can see, the JShell commands and the Java snippets are mixed.
The script loads other scripts using the JShell /open command.
These snippets define the method download(), loadOption() and downloadUrl().

The script version.jsh defines the global variable VERSION:

String VERSION="1.2.0";

Downloading and Caching the Program


The next script, jarfetcher.jsh is a bit more complicated.
As of now, it is 100 lines.
If you want to look at the whole code, it is available on GitHub.
You can calculate the URL from the argument of the /open statement and from the URL above used to start Jamal.

The core functionality implemented in this script is the one that downloads the JAR files.
This is the following:

void downloadUrl(String urlString,File cacheRootDirectory) throws IOException {
    final URL url = new URL(urlString);
    File jar = new File(cacheRootDirectory.getAbsolutePath() + "/" + getFile(url));
    classPath.add(jar.getAbsolutePath());
    if (jar.exists()) {
        return;
    }
    System.out.println("downloading " + url);
    System.out.println("saving to file " + jar.getAbsolutePath());
    HttpURLConnection con = (HttpURLConnection) url.openConnection();
    con.setRequestMethod("GET");
    con.setConnectTimeout(CONNECT_TIMEOUT);
    con.setReadTimeout(READ_TIMEOUT);
    con.setInstanceFollowRedirects(true);
    final int status = con.getResponseCode();
    if (status != 200) {
        throw new IOException("GET url '" + url.toString() + "' returned " + status);
    }
    InputStream is = con.getInputStream();
    try (OutputStream outStream = new FileOutputStream(jar)) {
        byte[] buffer = new byte[8 * 1024];
        int bytesRead;
        while ((bytesRead = is.read(buffer)) != -1) {
            outStream.write(buffer, 0, bytesRead);
        }
    }
}

Oracle Java Tutorial and Material, Oracle Java Learning, Oracle Java Guides, Oracle Java Exam Prep
The method caches the downloaded files into a directory.
Environment variables can configure the directory.
The default location is ~/.jamal/cache/.jar/.

If the file exists, then it does not download it again.
The code assumes that the files we are using are released JAR files that do not ever change.
If this file was never downloaded before, it downloads the file and stores it in the cache directory.

Executing the macro processor


When all the files are there, then the script executed Jamal.
It is coded in the executor.jsh.
The method execute.jsh contains the following method:

void execute() throws IOException, InterruptedException {
    ProcessBuilder builder = new ProcessBuilder();
    String sep = System.getProperty("path.separator");
    String cp = String.join(sep,classPath);
    List<String> arguments = new ArrayList<>();
    arguments.addAll(List.of("java", "-cp", cp, "javax0.jamal.cmd.JamalMain"));
    arguments.addAll(commandLineOptions.entrySet().stream().map(e -> "" + e.getKey() + "=" + e.getValue()).collect( Collectors.toSet()));
    System.out.println("EXECUTING");
    for( String a : arguments){
        System.out.println(a);
    }
    builder.command(arguments.toArray(String[]::new))
        .directory(new File("."));
    Process process = builder.start();
    process.getInputStream().transferTo(System.out);
    int exitCode = process.waitFor();
}

As you can see, this script is using the standard Java ProcessBuilder to create a new process and then executes Jamal in it.

Extra details


The actual operation is a bit more complex.
Many options can control Jamal.
In the Maven plugin version, these options are in the pom.xml file.
The command-line version uses, eventually, command-line options.
JShell does not handle command-line options that would pass to the executing JShell engine.
There are some tricks, like using system properties or environment variables.
I find those cumbersome and tricky to use.
You usually execute Jamal using the same configuration in a single project.
The best way is to have the options in a file.
The Jamal startup JShell script reads the file ./jamal.options.
The file has a simple key value format.
It can contain values for the command line options as keys and extra jar and cp keys.
Jamal is extensible.
Extra classes on the classpath may contain macro implementations in Java, and they are used from the text files.
Every jar defines a URL from where a JAR file downloads.
The cp key defines local files to be added to the classpath.

These files are project specific; therefore, these will cache in the current working directory.
The cache directory will be ./.jamal/cache/.jar/.

If the jamal.options file does not exist, then the script’s first execution will create.
The auto-created file will contain the default values and also some documentation.

Sunday, October 25, 2020

Java String to String Array Conversion Examples

Oracle Java Exam Prep, Oracle Java Certification, Oracle Java Prep, Oracle Java Learning

A quick and practical guide on how to convert String to String Array in different ways in java.

1. Overview

In this article, you’ll learn how to convert String to String Array in java with example programs.

2.  Using the split() method

String api is added with split() method which takes the delimiter as input and the string will be split based on the given delimiter. Finally, it returns each split string as in the form of String[] array.

Look at the below program and passed the empty string “” to the split() method. 

package com.oraclejavacertified.programs.conversions.string;

public class StringtoStringArraySplit {

    public static void main(String[] args) {

        //  input string

        String input = "oraclejavacertified.blogspot.com";

        // spliting string into string array using  split() method.

        String[] stringArray = input.split("");

        // printing the values of string array

        for (String string : stringArray) {

            System.out.println(string);

        }

    }

}

Output:

j

a

v

a

p

r

o

g

r

a

m

t

o

.

c

o

m

input.split(“”) method returns the string “oraclejavacertified.blogspot.com” into string[] array and stores the result in the stringArray. Use the forEach loop to iterate and print the values of the String array.

Now, converted string array length and original string lengths should be the same. let us check now.

System.out.println(stringArray.length);

System.out.println(input.length());

Output:

17

17

3. Using Regular Expression

Next, Look at the second approach using regular expressions which simplifies the lots code for complexe validations such as validations of the email address and phone numbers.

Regular Expression Examples on removing the vowels from string and checking string is number.

Again need to use the split() method with the regular expression as below.

package com.oraclejavacertified.programs.conversions.string;

public class StringtoStringArraySplitRegularExpression {

    public static void main(String[] args) {

        //  input string

        String input = "hello geek";

        // splitting string into string array using  split() method with regular expression.

        String[] stringArray = input.split("(?!^)");

        // printing the values of string array

        for (String string : stringArray) {

            System.out.println(string);

        }

        System.out.println(stringArray.length);

        System.out.println(input.length()); 

    }

}

Output:

h

e

l

l

o

  

g

e

e

k

10

10

4. Using Guava

Guava API also has builtin support for string array conversions as below.

Oracle Java Exam Prep, Oracle Java Certification, Oracle Java Prep, Oracle Java Learning
But when you are working with Guava there are many steps involved here.

4.1 First converts string to char[] array using toCharArray() method.

4.2. Chars.asList() method to convert char array into List.

4.3 Finally, it transforms into String array with List.transform() and toArray() methods.

These procedure is little bit java 8 concepts are required to understand.

Here is the full code example.

package com.oraclejavacertified.programs.conversions.string;

import org.apache.commons.lang3.ArrayUtils;

import com.google.common.base.Functions;

import com.google.common.collect.Lists;

import com.google.common.primitives.Chars;

public class StringtoStringArrayGuava {

    public static void main(String[] args) {

        // input string

        String input = "Using Guava";

        // spliting string into string array using split() method.

        String[] stringArray = Lists.transform(Chars.asList(input.toCharArray()), Functions.toStringFunction())

                .toArray(ArrayUtils.EMPTY_STRING_ARRAY);

        // printing the values of string array

        for (String string : stringArray) {

            System.out.println(string);

        }

        System.out.println(stringArray.length);

        System.out.println(input.length());

    }

}

Output:

U

s

i

n

g

  

G

u

a

v

a

11

11

Friday, October 23, 2020

Java Program To Get Union Of Two Arrays

Oracle Java Tutorial and Material, Core Java, Oracle Java Certification, Oracle Java Learning

A quick and programming guide to how to get the union of two unsorted arrays in java with example programs.

1. Overview

In this article, you’ll learn how to get the union of two arrays in java. A union set is all the values of two sets or from all collection.

We can do the union function in java using HashSet with arrays. Use the addAll() method to add all the values of each array into HashSet.

This is a simple solution. As well as this solution will work with both numbers and string values.

2. Union of two Integer arrays with numbers

Let us write the java program to print the union of two integer arrays.

import java.util.Arrays;

import java.util.HashSet;

import java.util.Set;

public class UnionTwoArraysNumbers {

    public static void main(String[] args) {

        // Integer array 1

        Integer[] array1 = { 1, 2, 3, 4, 5, 6, 7, 8 };

        System.out.println("Array 1 : " + Arrays.toString(array1));

        // Integer array 2

        Integer[] array2 = { 2, 4, 6, 8, 10, 12, 14 };

        System.out.println("Array 2 : " + Arrays.toString(array2));

        // creating a new Set

        Set<Integer> unionOfArrays = new HashSet<>();

        // adding the first array to set

        unionOfArrays.addAll(Arrays.asList(array1));

        // adding the second array to set

        unionOfArrays.addAll(Arrays.asList(array2));

        // converting set to array.

        Integer[] unionArray = {};

        unionArray = unionOfArrays.toArray(unionArray);

        // printing the union of two arrays.

        System.out.println("Union of two arrays: " + Arrays.toString(unionArray));

    }

}

Output:

Array 1 : [1, 2, 3, 4, 5, 6, 7, 8]
Array 2 : [2, 4, 6, 8, 10, 12, 14]
Union of two arrays: [1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14]

3. Union of two String arrays


Oracle Java Tutorial and Material, Core Java, Oracle Java Certification, Oracle Java Learning
Let us write the java program to print the union of two String arrays.

public class UnionTwoArraysStrings {
 
    public static void main(String[] args) {
 
        // Integer array 1
        String[] array1 = { "A", "B", "C", "D" };
        System.out.println("String Array 1 : " + Arrays.toString(array1));
 
        // Integer array 2
        String[] array2 = { "C", "D", "E", "F" };
        System.out.println("String  Array 2 : " + Arrays.toString(array2));
 
        // creating a new Set
        Set<String> unionOfArrays = new HashSet<>();
 
        // adding the first array to set
        unionOfArrays.addAll(Arrays.asList(array1));
 
        // adding the second array to set
        unionOfArrays.addAll(Arrays.asList(array2));
 
        // converting set to array.
        String[] unionArray = {};
        unionArray = unionOfArrays.toArray(unionArray);
 
        // printing the union of two arrays.
        System.out.println("Union of two String arrays: " + Arrays.toString(unionArray));
 
    }
 
}

Output:

String Array 1 : [A, B, C, D]
String Array 2 : [C, D, E, F]
Union of two String arrays: [A, B, C, D, E, F]

Wednesday, October 21, 2020

Locking for multiple nodes the easy way: GCS

It happens to all of us. We develop stateless applications that can scale horizontally without any effort.

However sometimes cases arise where you need to achieve some type of coordination.

You can go really advanced on this one. For example you can use a framework like Akka and it’s cluster capabilities. Or you can go really simple like rolling a mechanism on your own as long as it gives you the results needed. On another note you can just have different node groups based on the work you need them to do. The options and the solutions can change based on the problem.

If your problem can go with a simple option, one way to do so , provided you use Google Cloud Storage, is to use its lock capabilities.

Imagine for example a scenario of 4 nodes, they do scale dynamically but each time a new node registers you want to change its actions by acquiring a unique configuration which does not collide with a configuration another node might have received.

Oracle Java Exam Prep, Oracle Java Learning, Oracle Java Certification, Oracle Java Guides

The strategy can be to use a file on Google Cloud Storage for locking and a file that acts as a centralised configuration registry.

The lock file is nothing more that a file on cloud storage which shall be created and deleted. What will give us lock abilities is the option on GCS to create a file only if it not exists.

Thus a process from one node will try to create the `lock` file, this action would be equivalent to obtaining the lock.

Once the process is done will delete the file, this action would be equivalent to releasing the lock.
Other processes in the meantime will try to create the file (acquire the lock) and fail (file already exists) because other processes have created the file.

Meanwhile the process that has successfully created the file (acquired the lock) will change the centralised configuration registry and once done will delete the file (release the lock).

So let’s start with the lock object.

package com.gkatzioura.gcs.lock;
 
import java.util.Optional;
 
import com.google.cloud.storage.Blob;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageException;
 
public class GCSLock {
 
    public static final String LOCK_STRING = "_lock";
    private final Storage storage;
    private final String bucket;
    private final String keyName;
 
    private Optional<Blob> acquired = Optional.empty();
 
    GCSLock(Storage storage, String bucket, String keyName) {
        this.storage = storage;
        this.bucket = bucket;
        this.keyName = keyName;
    }
 
    public boolean acquire() {
        try {
            var blobInfo = BlobInfo.newBuilder(bucket, keyName).build();
            var blob = storage.create(blobInfo, LOCK_STRING.getBytes(), Storage.BlobTargetOption.doesNotExist());
            acquired = Optional.of(blob);
            return true;
        } catch (StorageException storageException) {
            return false;
        }
    }
 
    public void release() {
        if(!acquired.isPresent()) {
            throw new IllegalStateException("Lock was never acquired");
        }
        storage.delete(acquired.get().getBlobId());
    }
 
}

As you can see the write specifies to write an object only if it does not exist. This operation behind the scenes is using the x-goog-if-generation-match header which is used for concurrency.
Thus one node will be able to acquire the lock and change the configuration files.
Afterwards it can delete the lock. If an exception is raised probably the operation fails and the lock is already acquired.

To make the example more complete let’s make the configuration file. The configuration file would be a simple json file for key map actions.

package com.gkatzioura.gcs.lock;
 
import java.util.HashMap;
import java.util.Map;
 
import com.google.cloud.storage.BlobId;
import com.google.cloud.storage.BlobInfo;
import com.google.cloud.storage.Storage;
import org.json.JSONObject;
 
public class GCSConfiguration {
 
    private final Storage storage;
    private final String bucket;
    private final String keyName;
 
    GCSConfiguration(Storage storage, String bucket, String keyName) {
        this.storage = storage;
        this.bucket = bucket;
        this.keyName = keyName;
    }
 
    public void addProperty(String key, String value) {
        var blobId = BlobId.of(bucket, keyName);
        var blob = storage.get(blobId);
 
        final JSONObject configJson;
 
        if(blob==null) {
            configJson = new JSONObject();
        } else {
            configJson = new JSONObject(new String(blob.getContent()));
        }
 
        configJson.put(key, value);
 
        var blobInfo = BlobInfo.newBuilder(blobId).build();
        storage.create(blobInfo, configJson.toString().getBytes());
    }
 
    public Map<String,String> properties() {
 
        var blobId = BlobId.of(bucket, keyName);
        var blob = storage.get(blobId);
 
        var map = new HashMap<String,String>();
 
        if(blob!=null) {
            var jsonObject = new JSONObject(new String(blob.getContent()));
            for(var key: jsonObject.keySet()) {
                map.put(key, jsonObject.getString(key));
            }
        }
 
        return map;
    }
 
}

It is a simple config util backed by GCS. Eventually it can be changed and put the lock operating inside the addProperty operation, it’s up to the user and the code. For the purpose of this blog we shall just acquire the lock change the configuration and release the lock.
Our main class will look like this.

package com.gkatzioura.gcs.lock;
 
import com.google.cloud.storage.StorageOptions;
 
public class Application {
 
    public static void main(String[] args) {
        var storage = StorageOptions.getDefaultInstance().getService();
 
        final String bucketName = "bucketName";
        final String lockFileName = "lockFileName";
        final String configFileName = "configFileName";
 
        var lock = new GCSLock(storage, bucketName, lockFileName);
        var gcsConfig = new GCSConfiguration(storage, bucketName, configFileName);
 
        var lockAcquired = lock.acquire();
        if(lockAcquired) {
            gcsConfig.addProperty("testProperty", "testValue");
            lock.release();
        }
 
        var config = gcsConfig.properties();
 
        for(var key: config.keySet()) {
            System.out.println("Key "+key+" value "+config.get(key));
        }
 
    }
 
}

Oracle Java Exam Prep, Oracle Java Learning, Oracle Java Certification, Oracle Java Guides
Now let’s go for some multithreading. Ten threads will try to put values, it is expected that they have some failure.

package com.gkatzioura.gcs.lock;
 
import java.util.ArrayList;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
 
import com.google.cloud.storage.Storage;
import com.google.cloud.storage.StorageOptions;
 
public class ApplicationConcurrent {
 
    private static final String bucketName = "bucketName";
    private static final String lockFileName = "lockFileName";
    private static final String configFileName = "configFileName";
 
    public static void main(String[] args) throws ExecutionException, InterruptedException {
        var storage = StorageOptions.getDefaultInstance().getService();
 
        final int threads = 10;
        var service = Executors.newFixedThreadPool(threads);
        var futures = new ArrayList<Future>(threads);
 
        for (var i = 0; i < threads; i++) {
            futures.add(service.submit(update(storage, "property-"+i, "value-"+i)));
        }
 
        for (var f : futures) {
            f.get();
        }
 
        service.shutdown();
 
        var gcsConfig = new GCSConfiguration(storage, bucketName, configFileName);
        var properties = gcsConfig.properties();
 
        for(var i=0; i < threads; i++) { System.out.println(properties.get("property-"+i)); } } private static Runnable update(final Storage storage, String property, String value) { return () -> {
            var lock = new GCSLock(storage, bucketName, lockFileName);
            var gcsConfig = new GCSConfiguration(storage, bucketName, configFileName);
 
            boolean lockAcquired = false;
 
            while (!lockAcquired) {
                lockAcquired = lock.acquire();
                System.out.println("Could not acquire lock");
            }
 
            gcsConfig.addProperty(property, value);
            lock.release();
        };
    }
}

Obviously 10 threads are ok to display the capabilities. During the thread initialization and execution some threads will try to acquire the lock simultaneously and one will fails, while other threads will be late and will fail and wait until the lock is available.

In the end what is expected is all of them to have their values added to the configuration.

Monday, October 19, 2020

Java Program to Calculate Average Using Arrays

Oracle Java Certification, Oracle Java Learning, Oracle Java Tutorial and Material, Oracle Java Exam Prep

1. Overview

In this article, you’ll learn how to calculate the average of numbers using arrays. 

You should know the basic concepts of a java programming language such as Arrays and forEach loops.

We’ll see the two programs on this. The first one is to iterate the arrays using for each loop and find the average.

In the second approach, you will read array values from the user.

Let us jump into the example programs.

2. Example 1 to calculate the average using arrays

First, create an array with values and run. the for loop to find the sum of all the elements of the array.

Finally, divide the sum with the length of the array to get the average of numbers.

package com.oraclejavacertified.programs.arrays.average;

public class ArrayAverage {

    public static void main(String[] args) {

        // create an array

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

        // getting array length

        int length = array.length;

        // default sium value.

        int sum = 0;

        // sum of all values in array using for loop

        for (int i = 0; i < array.length; i++) {

            sum += array[i];

        }

        double average = sum / length;

        System.out.println("Average of array : "+average);

    }

}

Output:

Average of array : 6.0

3. Example 2 to find the average from user inputted numbers

Next, let us read the input array numbers from the user using the Scanner class.

import java.util.Scanner;

public class ArrayAverageUserInput {

    public static void main(String[] args) {

        // reading the array size.

        Scanner s = new Scanner(System.in);

        System.out.println("Enter array size: ");

        int size = s.nextInt();

        // create an array

        int[] array = new int[size];

        // reading values from user keyboard

        System.out.println("Enter array values :  ");

        for (int i = 0; i < size; i++) {

            int value = s.nextInt();

            array[i] = value;

        }

        // getting array length

        int length = array.length;

        // default sium value.

        int sum = 0;

        // sum of all values in array using for loop

        for (int i = 0; i < array.length; i++) {

            sum += array[i];

        }

        double average = sum / length;

        System.out.println("Average of array : " + average);

    }

}

Oracle Java Certification, Oracle Java Learning, Oracle Java Tutorial and Material, Oracle Java Exam Prep
Output:

Enter array size: 

5

Enter array values :  

12

23

34

45

56

Average of array : 34.0

Friday, October 16, 2020

Lifecycle and States of a Thread in Java

A thread in Java at any point of time exists in any one of the following states. A thread lies only in one of the shown states at any instant:

1. New

2. Runnable

3. Blocked

4. Waiting

5. Timed Waiting

6. Terminated

The diagram shown below represent various states of a thread at any instant of time.

Oracle Java Exam Prep, Oracle Java Learning, Oracle Java Tutorial and Material, Oracle Java Guides

Life Cycle of a thread


1. New Thread: When a new thread is created, it is in the new state. The thread has not yet started to run when thread is in this state. When a thread lies in the new state, it’s code is yet to be run and hasn’t started to execute.

2. Runnable State: A thread that is ready to run is moved to runnable state. In this state, a thread might actually be running or it might be ready run at any instant of time. It is the responsibility of the thread scheduler to give the thread, time to run.
A multi-threaded program allocates a fixed amount of time to each individual thread. Each and every thread runs for a short while and then pauses and relinquishes the CPU to another thread, so that other threads can get a chance to run. When this happens, all such threads that are ready to run, waiting for the CPU and the currently running thread lies in runnable state.

3. Blocked/Waiting state: When a thread is temporarily inactive, then it’s in one of the following states:

◉ Blocked
◉ Waiting

For example, when a thread is waiting for I/O to complete, it lies in the blocked state. It’s the responsibility of the thread scheduler to reactivate and schedule a blocked/waiting thread. A thread in this state cannot continue its execution any further until it is moved to runnable state. Any thread in these states does not consume any CPU cycle.

A thread is in the blocked state when it tries to access a protected section of code that is currently locked by some other thread. When the protected section is unlocked, the schedule picks one of the thread which is blocked for that section and moves it to the runnable state. Whereas, a thread is in the waiting state when it waits for another thread on a condition. When this condition is fulfilled, the scheduler is notified and the waiting thread is moved to runnable state.

If a currently running thread is moved to blocked/waiting state, another thread in the runnable state is scheduled by the thread scheduler to run. It is the responsibility of thread scheduler to determine which thread to run.

4. Timed Waiting: A thread lies in timed waiting state when it calls a method with a time out parameter. A thread lies in this state until the timeout is completed or until a notification is received. For example, when a thread calls sleep or a conditional wait, it is moved to a timed waiting state.

5. Terminated State: A thread terminates because of either of the following reasons:

◉ Because it exists normally. This happens when the code of thread has entirely executed by the program.
◉ Because there occurred some unusual erroneous event, like segmentation fault or an unhandled exception.

A thread that lies in a terminated state does no longer consumes any cycles of CPU.

Implementing Thread States in Java


In Java, to get the current state of the thread, use Thread.getState() method to get the current state of the thread. Java provides java.lang.Thread.State class that defines the ENUM constants for the state of a thread, as summary of which is given below:

1. Constant type: New

Declaration: public static final Thread.State NEW

Description: Thread state for a thread which has not yet started.

2. Constant type: Runnable

Declaration: public static final Thread.State RUNNABLE

Description: Thread state for a runnable thread. A thread in the runnable state is executing in the Java virtual machine but it may be waiting for other resources from the operating system such as processor.

3. Constant type: Blocked

Declaration: public static final Thread.State BLOCKED

Description: Thread state for a thread blocked waiting for a monitor lock. A thread in the blocked state is waiting for a monitor lock to enter a synchronized block/method or reenter a synchronized block/method after calling Object.wait().

4. Constant type: Waiting

Declaration: public static final Thread.State WAITING

Description: Thread state for a waiting thread. Thread state for a waiting thread. A thread is in the waiting state due to calling one of the following methods:

◉ Object.wait with no timeout
◉ Thread.join with no timeout
◉ LockSupport.park

A thread in the waiting state is waiting for another thread to perform a particular action.

5. Constant type: Timed Waiting

Declaration: public static final Thread.State TIMED_WAITING

Description: Thread state for a waiting thread with a specified waiting time. A thread is in the timed waiting state due to calling one of the following methods with a specified positive waiting time:

◉ Thread.sleep
◉ Object.wait with timeout
◉ Thread.join with timeout
◉ LockSupport.parkNanos
◉ LockSupport.parkUntil

6. Constant type: Terminated

Declaration: public static final Thread.State TERMINATED

Description: Thread state for a terminated thread. The thread has completed execution.

// Java program to demonstrate thread states 
class thread implements Runnable 
public void run() 
// moving thread2 to timed waiting state 
try
Thread.sleep(1500); 
catch (InterruptedException e) 
e.printStackTrace(); 
System.out.println("State of thread1 while it called join() method on thread2 -"+ 
Test.thread1.getState()); 
try
Thread.sleep(200); 
catch (InterruptedException e) 
e.printStackTrace(); 
}  

public class Test implements Runnable 
public static Thread thread1; 
public static Test obj; 
public static void main(String[] args) 
obj = new Test(); 
thread1 = new Thread(obj); 
// thread1 created and is currently in the NEW state. 
System.out.println("State of thread1 after creating it - " + thread1.getState()); 
thread1.start(); 
// thread1 moved to Runnable state 
System.out.println("State of thread1 after calling .start() method on it - " + 
thread1.getState()); 
public void run() 
thread myThread = new thread(); 
Thread thread2 = new Thread(myThread); 
// thread1 created and is currently in the NEW state. 
System.out.println("State of thread2 after creating it - "+ thread2.getState()); 
thread2.start(); 
// thread2 moved to Runnable state 
System.out.println("State of thread2 after calling .start() method on it - " + 
thread2.getState()); 
// moving thread1 to timed waiting state 
try
//moving thread1 to timed waiting state 
Thread.sleep(200); 
catch (InterruptedException e) 
e.printStackTrace(); 
System.out.println("State of thread2 after calling .sleep() method on it - "+ 
thread2.getState() ); 
try
// waiting for thread2 to die 
thread2.join(); 
catch (InterruptedException e) 
e.printStackTrace(); 
System.out.println("State of thread2 when it has finished it's execution - " + 
thread2.getState()); 

Oracle Java Exam Prep, Oracle Java Learning, Oracle Java Tutorial and Material, Oracle Java Guides

Output:

State of thread1 after creating it - NEW
State of thread1 after calling .start() method on it - RUNNABLE
State of thread2 after creating it - NEW
State of thread2 after calling .start() method on it - RUNNABLE
State of thread2 after calling .sleep() method on it - TIMED_WAITING
State of thread1 while it called join() method on thread2 -WAITING
State of thread2 when it has finished it's execution - TERMINATED

Explanation: When a new thread is created, the thread is in the NEW state. When .start() method is called on a thread, the thread scheduler moves it to Runnable state. Whenever join() method is called on a thread instance, the current thread executing that statement will wait for this thread to move to Terminated state. So, before the final statement is printed on the console, the program calls join() on thread2 making the thread1 wait while thread2 completes its execution and is moved to Terminated state. thread1 goes to Waiting state because it is waiting for thread2 to complete it’s execution as it has called join on thread2.