What is the order of initialization in a Java class

The order of initialization of a Java class is the following:

  1. Static constants, variables and blocks are first initialized in the order in which they appear in the code;
  2. Then non-static constants, variables and blocks are first initialized in the order in which they appear in the code;

Consider the following code :

public class Sample{
 
 static Sample2 a = new Sample2();
 
 
 Sample2 b = new Sample2("Instance variable");
 
 public Sample(){
 System.out.println("Constructor");
 }
 
 static{
 System.out.println("Static block");
 }
 
 public static void main(String[] args) {
 new Sample();
 }
}

class Sample2{
 
 public Sample2(){
 System.out.println("Sample2 Constructor");
 }
 
 public Sample2(String str){
 System.out.println(str);
 }

}

Accoding the above points 1 and 2, the displayed result will be :

Sample2 Constructor
Static block
Instance variable
Constructor

 

 

Labeled statements in Java 8

Labeled statements are transfer of control statements used to give a statement a prefixed label.

Referred statements can be loops, switch statements or blocks {statements enclosed in curly braces}. Example :

loop1: for(int i=0;i<10<i++){
          System.out.println(i);
       }

 

Labeled statements are used in conjunction with break and continue statements.

To understand better, lets take the following example of two nested for loops and a break statement. The use of the break statement inside of the inner loop will cause the program to interrupt the innermost for loop when j become equal to 5  . It will not interrupt the outer loop.

 

for(int i=0;i<=10;i++){
 for(int j=0;j<=10;j++){
  System.out.println(i + " - " + j);
  if(j>=5){
   break;
  }
 }
}

 

Now we will label the outer for loop, and add the same label to the innermost break statement. This will cause the program to interrupt the outer loop (the labeled one) .

label1:
for(int i=0;i<=10;i++){
 for(int j=0;j<=10;j++){
  System.out.println(i + " - " + j);
  if(j>=5){
   break label1;
  }
 }
}

 

As mentioned earlier, labeled statements can be used in conjunction with a break statement inside a loop or a switch statement. or with a continue statement inside a loop.

The following example will interrupt the outer for loop when j == 5 which is the labelled for loop.

label1:
for(int i=0;i<=10;i++){
 for(int j=0;j<=10;j++){
  System.out.println(i + " - " + j);
  switch(j){
   case 5:
    break label1;
   default:
    // do nothing
  }
 }
}

 

Access modifiers in java : public, protected, default, private

In Java, access modifiers are keywords that help setting the accessibility of classes, methods or members. There are four access modifiers in Java language, they are exposed in the following from the least restrictive (public) to the most restrictive (private).

 

Public

Means that the class or the member variable or method can be accessed from anywhere in the code, from the same package or from a different one.

Protected

Can be used with inner variables, methods or inner classes. This access modifier means that the member can be accessed only from the same class or a subclass.

Default (or package private)

This is the default access modifier that will be applied when we don’t specify any. It can be used with a class or member variable or method.
It means that the member can be accessed only from the same package. Please note that a default member cannot be accessed from a subclass in an other package as well.

Private

The private keyword can be used for members (variables, methods or inner classes , when used it limits access to members to only the same class only.

Note

The native keyword in java is not considered as an access modifier.

Summary

class package Sub-class

(same package)

Sub-class

(other package)

World
public  ✔  ✔  ✔  ✔
Protected  ✔  ✔  ✔  ✔  x
default  ✔  ✔  ✔  x  x
private  ✔  x  x  x  x

How to create directories in Java

In java you can create a directory (or directories) using the standard IO package or using the java NIO package.

Create directories using the java IO package

// create a single directory
new File("c:\\myDir").mkdir();

// create a directory and all its sub-directories
new File("c:\\myRootDir\\Subdir1\\SubDir2").mkdirs();

 

Create directories using the java NIO package

This will work only on Java 7 and above.

Path path = Paths.get("C:\\Mydir");
Files.createDirectories(path);

You have to import the classes java.nio.file.Paths and java.nio.file.Files .

 

 

 

Streams in java 8

A Stream is a sequence of elements supporting sequential and parallel aggregate operations. Streams have been introduced to Java starting from version 8.

Example of the use of Streams

Consider the following example:

// create a collection of Products
List<Product> products= new ArrayList<Product>();

// calculate the sum of prices of the products whose 
// made locally
// and the price is greater or equal to 10
int sumOfPrices = products.stream()
                      .filter(p -> p.isMadeLocally() == true)
                      .filter(p -> p.getPrice() >=10 )
                      .mapToInt(p -> p.getPrice())
                      .sum();

In the above example we create a stream of products using products.stream() .  Then we filter the products by using the filter() function that takes an object of type Predicate as parameter (in other words, a Functional Interface), meaning that we can use a Lamba expression like in this example.

The mapToInt() function takes a parameter of type ToIntFunction which is also a functional interface, this is why we used the lambda expression p-> p.getPrice() . The mapToInt() function returns an object of type IntStream . And finally the sum() function calculates the sum of all the prices of the products.

Convert a Collection into Stream and vice-versa

filter() functions are sometimes combined with collect() function that converts a stream into a Collection. Example :

// In this example, the products List is converted to a stream, and then to a List
List<Product> listOfProducts = products.stream().filter(p-> p.getPrice()>10).collect(Collectors.toList());

 

Streams Vs Collections

Streams and Collections seem to be similar, but in reality they have different goals: Collections are mainly concerned with the efficient management of, and access to, their elements. However Streams do not give a direct access to their elements or manipulate them, but are instead concerned with declaratively describing their source and the computational operations which will be performed in aggregate on that source.

The BaseStream.iterator() and BaseStream.spliterator() operations can be used to perform a controlled traversal.

Sequential and parallel streams

Stream pipelines can be sequential or parallel. Using the Collection.stream() function will create a sequential stream, and the use of Collection.parallelStream() will create a stream with a parallel mode of execution.

 

What is new in Java 9

Java 9 is a major feature release. The following summarizes features and enhancements in Java  language version 9.

  • Allow @SafeVargs annotation on private instance methods
  • Allow final variables to be used as resources in the try-with-resources statement
  • Allow the use of diamond with anonymous classes if the type of the inferred type is denotable.
  • Complete the removal of underscore from the set of legal identifier names. This was started in java version 8.
  • Add support for private interface methods.

Reference : https://docs.oracle.com/javase/9/language/toc.htm#JSLAN-GUID-16A5183A-DC0D-4A96-B9D8-AAC9671222DD

Example of replacing anonymous inner class by a Lambda expression in Java 8

One  of the facilities that Java 8 offers is the reduction of the numbers of lines of code in some situations. In this example, we will replace an anonymous inner class by a Lamba Expression. Reducing the code used to compare two players to almost one single line.

First of all, we will need a Player object. A player has a name and a score. Please note that we will use the Integer wrapper type instead of the primitive int type, in order to benefit from the compareTo method offered by the Integer object.

package com.tutoref;

public class Player {
 
 private String name;
 private Integer score;
 
 // Default constructor to allow instanciation without parameters
 public Player(){}
 
 // Constructor with parameters
 public Player(String name, int score){
  this.name = name;
  this.score = score;
 }
 
 public String getName() {
  return name;
 }
 
 public void setName(String name) {
  this.name = name;
 }
 
 public Integer getScore() {
  return score;
 }
 
 public void setScore(Integer score) {
  this.score = score;
 }
 
 
 @Override
 public String toString() {
  // To customise the displaying of a player
  return "[name : "+this.name+", score : "+this.score+"]";
 }
}

 

Comparison using an anonymous inner class

The playerComparator inner class is used to tell the program how to compare two players, based on their score.

In this example we create the playerComparator of type Coparator<Player>, after that create and add some players to the ListArray collection, then we use the Collections.sort method ot sort the players based on their score.

package com.tutoref;

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

public class PlayerSort {

 public static void main(String[] args) {
  
  // Create a comparator object
  Comparator<Player> playerComparator = new Comparator<Player> () {
   @Override
   public int compare(Player player1, Player player2) {
    return player1.getScore().compareTo(player2.getScore());
   }
  };
  
  
  // Create a list of players
  List<Player> playerList = new ArrayList<Player>();
  
  // add some players
  playerList.add(new Player("Messi",500));
  playerList.add(new Player("Ronaldo",750));
  playerList.add(new Player("Roberto",900));
  playerList.add(new Player("Albert",450));
  playerList.add(new Player("Michel",750));
  playerList.add(new Player("Mario",750));
  
  // Sort the list based on the score 
  // using the comparator object
  Collections.sort(playerList,playerComparator);
  
  // display the sorted list of players (in ascendant order)
  System.out.println(playerList);
 }

}

 

COMPARISON Using Lambda Expression

This example will replace the  anonymous inner class, reducing it to one line of code.

package com.tutoref;

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

public class PlayerSortUsingLambdaExp {

 public static void main(String[] args) {
  
  // Create a list of players
  List<Player> playerList = new ArrayList<Player>();
  
  // add some players
  playerList.add(new Player("Messi",500));
  playerList.add(new Player("Ronaldo",750));
  playerList.add(new Player("Roberto",900));
  playerList.add(new Player("Albert",450));
  playerList.add(new Player("Michel",750));
  playerList.add(new Player("Mario",750));
  
  Collections.sort(playerList, (p1, p2) -> p1.getScore().compareTo(p2.getScore()) );
  
  // display the sorted list of players (ascendent order)
  System.out.println(playerList);
 }

}

The compactor interface is also a Functional Interface, this is why it can be replaced by a lambda expression. You can imagine that we passed the function making the comparison as parameter.

Example of a Functional Interface

Also called a SAM (Single Abstract Method). An FI is an interface containing :

  • One and only one abstract method;
  • Zero or many static methods
  • Zero or many default methods

There are many built-in functional interfaces included in Java 8. The Predicate FI is one of them.

Here is an example of a functional interface :

@FunctionalInterface
interface MostBasicFi{
   boolean test();

   // a static method
   public static void foo1(){
    // add some logic...
   }

   // a default method
   public static void foo2(){
    // add some logic...
   }
   
}

 

 

How to read and write files in Java 8

This tutorial presents the different options available to read and write files in Java .

Reading files

Using  FileInputStream and BufferedReader

In the following example we will create a BufferedReader from InputStreamReader. Use this option when you need to read byte streams and transform them into character streams. You can specify the encoding charset.  Examples : Reading a zip file, image, network resources, or simply text files etc.

File file = new File("myFile.zip");
try {
  FileInputStream fis = new FileInputStream(file);
  BufferedReader br = new BufferedReader(new InputStreamReader(fis));
  String line;
  while((line=br.readLine())!=null){
    System.out.println(line);
  }
  br.close();
} catch (FileNotFoundException e) {
  // File not found
  e.printStackTrace();
} catch (IOException e) {
  // Error when reading the file
  e.printStackTrace();
}

 

Using FileReader and BufferedReader

This example is similar the previous one, except the fact that we build the BufferedReader from a FileReader.

Use this option when you have to read character based content. You cannot specify the encoding charset for this method and it will use the platform encoding.

File file = new File("myFile.txt");
try {
  BufferedReader br = new BufferedReader(new FileReader(file));
  String line;
  while((line=br.readLine())!=null){
    System.out.println(line);
  }
  br.close();
} catch (FileNotFoundException e) {
  // File not found
  e.printStackTrace();
} catch (IOException e) {
  // Error when reading the file
  e.printStackTrace();
}

 

Using Files.newBufferedReader() in Java 7 and above

This example is similar to the first one (Using FileInputStreamAND BufferedReader) .  It uses the java.nio package and the try-with-resources exception management structure. It works starting from java 7.

The necessary imports

import java.io.BufferedReader;
import java.io.IOException;
import java.nio.charset.Charset;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;

The code

Path path = Paths.get("c:/tmp/myfile.csv");
Charset charset = Charset.forName("UTF-8");
try (BufferedReader reader = Files.newBufferedReader(path, charset)) {
  String line = null;
  while ((line = reader.readLine()) != null) {
    System.out.println(line);
  }
} catch (IOException e) {
  e.printStackTrace();
}

 

Using Lambda expression in Java 8

One of the benefits of Lambda Expression is the reduction of the number of lines of code. In this example, we will read and print the content of a file in one line using Lambda Expressions and java.nio.file.Files class :

Files.lines(new File("c:/myfile.txt").toPath()).forEach(System.out::println);

(for simplicity we didn’t include the exception management for the IOException exception)

Writing files

Using FileOutputStream

try {
  File fout = new File("myOutFile.txt");
  FileOutputStream fos = new FileOutputStream(fout);
  BufferedWriter bw = new BufferedWriter(new OutputStreamWriter(fos));
  bw.write("Write somthing to the file ...");
  bw.newLine();
  bw.close();
} catch (FileNotFoundException e){
  // File was not found
  e.printStackTrace();
} catch (IOException e) {
  // Problem when writing to the file
  e.printStackTrace();
}

 

Using FileWriter

You better use FileWriter or PrintWriter if you plan to write some character based content or a text file.

try {
  FileWriter fw = new FileWriter("myOutFile.txt");
  fw.write("Example of content");
  fw.close();
} catch (FileNotFoundException e) {
  // File not found
  e.printStackTrace();
} catch (IOException e) {
  // Error when writing to the file
  e.printStackTrace();
}

 

Using PrintWriter

Similar to FileWriter but with some specifities. Here is the Oracle’s PrintWriter definition:

Prints formatted representations of objects to a text-output stream. This class implements all of the print methods found in PrintStream. It does not contain methods for writing raw bytes, for which a program should use unencoded byte streams.

try {
  PrintWriter pw = new PrintWriter("myOutFile.txt");
  pw.write("Example of content");
  pw.close();
} catch (FileNotFoundException e) {
  // File not found
  e.printStackTrace();
} catch (IOException e) {
  // Error when writing to the file
  e.printStackTrace();
}

 

Using OutputStreamWriter

try {
  File fout = new File("myOutFile.txt");
  FileOutputStream fos = new FileOutputStream(fout);
  OutputStreamWriter osw = new OutputStreamWriter(fos);
  osw.write("Soe content ...");
  osw.close();
} catch (FileNotFoundException e) {
  // File not found
  e.printStackTrace();
} catch (IOException e) {
  // Error when writing to the file
  e.printStackTrace();
}