Casting variables in Java

Casting a varibale in java is indicating to the compiler that a variable of type A will be used as an other type B. There are two types of casting, implicit and explicit.

Implicit casting

Implicit casting in Java is when you assign a variable of a lower (or child) type to a greater (or parent) type.

Examples of implicit casting:

// example 1 : a was implicitly casted from int to double
int a = 10;
double d=a;

// example 2 : student was implicitly casted from Student to Person
// we suppose that Student is a subclass of Person
Student student= new Student();
Person person = student;

Explicit casting

Explicit casting in Java is when you explicitly indicate to the compiler the target type you want to convert the value of your variable to (otherwise your code will not compile).

It is like if you tell the compiler : Trust me, my varibale can be cast to the target type !

The source data type must be compatible with the target data type at runtime (when you execute the program). If not, you will get a ClassCastException.

Examples of explicit casting:

// 256.1234f will be converted to int and the 
// digits after the period (.) will be lost
float f = 256.1234f;
int i = (int)f;

// p is converted to Student datatype
// Student must be a sub-type of Person 
Person p= new Person();
Student s = p;

Casting primitives

Java  allows primitive types to be cast implictly from lower to higher data types . For explicit cast of primitives, you have to be careful with the loss of precision and varibale truncating when you cast higher to lower datatypes (Example : from  double to int).

The following is a summary of what are the implicit and explicit casts allowed for primitive types in Java.

Primitives casting in Java

Primitives casting in Java

 

 

 

Java 8 Lambda expressions tutorial

What are Lambda expressions

Lambda expressions are a new feature of Java 8 that can be seen as replacement of anonymous inner classes using expressions, allowing to pass functionality as method arguments. They can also be seen as anonymous methods (nameless) implementing a method defined by a functional interface.
Before going further, I will describe what a functional interface is in the next section.

Functional Interfaces

A functional interface (FI) is any interface that contains :

  1. One single abstract method;
  2. Zero or more static methods;
  3. Zero or more default methods.

To be able to write a Lambda expression you must have a corresponding functional interface. Lambda expressions implement the method defined by that interface. The signature of it’s abstract method must match the lambda expression in terms of parameters and return type.

It is preferable to add the annotation @FunctionalInterface to your FI but it’s not mandatory. However, doing so will make your code more readable and allows the EDI (ie: eclipse) to give you some refactoring suggestions like replacing anonymous inner classes by lambda expressions. Functional interfaces are also called Single Abstract Methods (SAM).

Th package java.util.function includes a lot functional interfaces that can be used in specific situation. An example with Predicate and Consumer functional interfaces will be discussed later in this tutorial. You can check the Javadoc for the complete list of these functional interfaces. Before you define your own FIs, you may want to verify the existence of an FI that satisfies your specific need.

Why lambda expressions

The following simple example will help you to better understand the use of lambda expressions.

Consider the Operation interface, representing an abstract arithmetic operation. The interface contains the calculate() method representing the calculating functionality. Since the interface offers only and only one abstract method, we can consider that the interface Operation itself represents the calculate functionality:

interface Operation {
  int calculate(int a,int b);
}

Please note that the Operation interface contains one and only one abstract method which is calculate(), such interfaces are called Functional Interfaces.

The Test class contains the displayResult() method that calls the method calculate of Operation and displays the result. It takes three parameters:

  1. The first parameter of the calculation;
  2. The second parameter of the calculation;
  3. The Operation we want to execute.
public class Test {

 public static void main(String[] args) {
   // calculations to be added later ...
 }

 static void displayResult(Operation operation, int a, int b){
   System.out.println(operation.calculate(a, b));
 }

}

In other words, the displayMethod() will receive the calculation functionality as parameter, execute it and display the result.

In Java 7 and earlier, we can implement a calculation by implementing the interface Operation. In the following example, I will define an addition and multiplication operations :

// Addition
public class PlusOperation implements Operation {

 @Override
 public int calculate(int a, int b) {
  return a+b;
 }

}

// Multiplication
public class MultiplicationOperation implements Operation {

 @Override
 public int calculate(int a, int b) {
  return a*b;
 }

}

We can now instantiate the concrete operations (Addition and Multiplication) inside the Test class, and pass them as argument to the Test.displayResult() method:

// Addition of 1 and 2
Operation plusOperation = new PlusOperation();
displayResult(1, 2, plusOperation);

// Multiplication of 4 by 4
Operation multiplicationOperation = new MultiplicationOperation();
displayResult(4, 4, multiplicationOperation);

An other option to implement a custom calculation is to create an anonymous inner class in place, and pass it directly to the displayResult() method as parameter. Let’s say we want to implement the exponent of 10 in 20 :

// other operation, 10 exponent 20
displayResult( 10, 20,
 new Operation() {
  @Override
  public int calculate(int a, int b) {
   return a^b;
  }
 }
);

 

All the examples above can be implemented in less lines of code using Lambda expressions. We will see in the next section how to write a lambda expression, but remember that a lambda expression represents a behavior, a functionality we can pass as a method argument:

// the above operations using lambda expressions
displayResult(1,2, (a,b)->a+b); // addition
displayResult(4,4, (a,b)->a*b); // multiplication
displayResult(10,20, (a,b)-> a^b); // exponent

The final code of the Test class looks like this :

public class Test {

 public static void main(String[] args) {

  // Addition of 1 and 2
  Operation plusOperation = new PlusOperation();
  displayResult(1, 2, plusOperation);

  // Multiplication of 4 by 4
  Operation multiplicationOperation = new MultiplicationOperation();
  displayResult(4, 4, multiplicationOperation);

  // other operatio, 10 exponent 20
  displayResult( 10, 20,
  new Operation() {

   @Override
   public int calculate(int a, int b) {
    return a^b;
   }
  }
  );

  // all the above operations using lambda expressions

  displayResult(1,2, (a,b)->a+b); // addition
  displayResult(4,4, (a,b)->a*b); // multiplication
  displayResult(10,20, (a,b)-> { // exponent
   return a^b;
   }
  );

 }

 static void displayResult( int a, int b, Operation operation){
  System.out.println(operation.calculate(a, b));
 }

}

 

And the output of the program is the same using lambda expressions or the old way:

3 ⇐ Using the old way
16
30
3 ⇐ Using lambda expressions
16
30

How to write a Lambda Expression

Lambda expressions are composed of two statements, linked by an arrow (->):

  1. The left statement: Represents the parameters statement;
  2. The right statement : Represents the body statement .
// general syntax
(parameters) -> (Body)

Lambda’s left statement

The left statement of a lambda expression is similar to the parameters statement in a method definition, with the difference that you can choose to indicate or not the data types of the parameters. If there are no parameters, you can simply use empty parentheses.
The parentheses become optional if the left statement contains one single parameter.

Lambda’s right statement

The right statement of a lambda expression is similar to the body of a method definition, with the difference that the curly braces ( { } ) and the return keyword are optional if the body contains one single expression. However, this becomes necessary when the body statement is composed of more than one expression;

 

Examples of valid lambda expressions

The following is a list of valid lambda expressions:

// Full syntax
(Double x, Double y) -> {return x * y;}

// Omitting curly braces
(Double x, Double y) -> return x * y

// Omitting curly braces and return keyword
(Double x, Double y) -> x * y

// Omitting the data types
(x, y) -> {return x * y;}

// The parentheses become optional if the left side
// contains only one parameter
x -> System.out.print(x)

// Lambda expression including many
// statements in the body
(x,y) -> {
 if(x>y){
  System.out.println("x is greater than y");
  return true;
 }else{
  System.out.println("y is greater or equal to x")
 }
 return false;
}

// Lambda expression with no parameters
() -> 99

 

Use case of lambda with the Collections framework

Streams have been introduced in Java 8 to support the Collections framework.
A Stream is a sequence of elements supporting sequential and parallel aggregate operations.
Some of these operations are simply methods that can take lambda expressions as parameter, allowing the programmer to process data in a simpler way compared to previous versions of Java.

To obtain a stream from a collection you can use the stream() method to obtain a sequential stream, and parallelStream() to obtain a parallel stream. For more informations about streams check this page talking about streams in java 8.

In the following example I will show how to filter and display a List in two lines of code, using lambda expressions and streams. Here are the steps:

  1. Create a list of Integers ;
  2. Populate it with random integers;
  3. Filter the list and keep only the pair numbers;
  4. Display the list.

To Create the list, I will simply use an ArrayList of Integers :

List<Integer> list = new ArrayList<Integer>();

The populateList() method populates the list with 1000 random integers:

// Implementation of the populateList() method
public static void populateList(List<Integer> list){
 Random random = new Random();
 for(int i=0;i<1000;i++){
  list.add(random.nextInt());
 }
}


// calling the populateList() method
populateList(list);

I will then obtain a stream from the list using the stream() method, filter it using the filter() method and collect the results into a filtered new list.

List<Integer> filteredList = list.stream().filter(e -> e%2==0).collect(Collectors.toList());

I will explain every element in the above line of code:

  • The stream() method returns a sequential stream obtained from the list we created before;
  • The filter() method is obtained from the stream, as you can understand from it’s name, the filter() method allow to filter the stream using a lambda expression;
  • The filter() method takes an object of type Predicat as parameter, it’s a functional Interface, that means we can use a lambda expression;
  • The Predicate functional interface is included in the package java.util.function (as well as other useful FIs). According to the signature of it’s abstract method ( boolean test(T t) ) It represents a boolean-valued function of one argument.
  • Finally, we must convert the stream to a List again, we will use the collect() method with the parameter (Collectors.toList()) .

Please note that the chaining the methods above is called a Pipeline, and all the operations of that pipeline are executed only after the method collect() is called.

Once we got a filteredList, we can display it. The method forEach( ) is a new facility added to the Collections framework allowing to iterate through the elements of a list. It takes an object of type Consumer (an other functional interface of the package java.util.function).

The consumer functional interface represents an operation that takes a single input argument and returns no value, this is similar to the behavior we want : displaying a value. Here is how to display the filteredList in Java 8 :

filteredList.forEach(e -> System.out.println(e));

To recapitulate, our code will look like this :

// Create the list
List<Integer> list = new ArrayList<Integer>();
    
// Populate the list
populateList(list);

// Filter the list
List<Integer> filteredList = list.stream().filter(e -> e%2==0).collect(Collectors.toList());

// Display the elements of the list
filteredList.forEach(e -> System.out.println(e));

Conclusion

In this tutorial we saw what are lambda expressions, why and how to use them. Using Lambda expressions allows to write less code and helps manipulation data withing the Collections framework, streams and pipelines  (iteration, filtering, sorting, etc) beside other things.  However, lambda expressions come with some limitations, for example, if there are problems in your code debugging may be harder with lambda expressions.

 

Java Expressions, Statements and Blocks

In java, Statements are composed of one or many expressions. They may also be grouped into blocks.

Expressions

Expressions in java are made of variables, operators and method invocations. An expression always evaluates to a single value.

//Examples of valid expressions
a =0;
"Hello "+firstName + " "+ lastName
d = a + b;

 

Statements

A statement in java is a complete unit of execution. Assignment expressions, pre-increment operators, pre-decrement operators, post-increment operators, post-decrement operators, method invocation and object instantiation expressions can compose a statement by terminating the expression with a semicolon (;) .

// using the Examples to create valid statements
int a =0;
System.out.println("Hello "+firstName + " "+ lastName);
double d = a + b;

 

Blocks

A block in Java is composed of zero or more statements enclosed inside curly braces { }. Blockes are allowed wherever statements are allowed. Blocks can be nested.

// Example of two blocks
if(condition)
{ // block 1 beginning
  int x=0;
  System.out.println("Block 1 is executed");
} // block 1 ending
else
{ // block 2 beginning
  System.out.println("Block 2 is executed");
} // block 2 ending

 

 

How to get the root exception of any exception

Sometimes, the root exception causing your code to fail is hidden behind an other exception or a set of nested exceptions.

Nested Exceptions

Nested Exceptions

 

The following code (function) searches for the root exception of any exception and returns it :

public static Throwable getRootException(Throwable exception){
 Throwable rootException=exception;
 while(rootException.getCause()!=null){
  rootException = rootException.getCause();
 }
 return rootException;
}

Example of usage :

catch(MyException e){
  System.out.println(getRootException(e).getLocalizedMessage());
}

 

 

JDBC Connection example

JDBC (Java Database Connectivity) is an API provided by Oracle offering a standard for communication between java code and a wide range of databases based on SQL or files (flat files, spreadsheets).

You need a driver for each type of database. That driver is often developed and offered by the company or the open source project maintaining the DBMS (Database Management System) . It comes usually as jar archive that you include manually in your classpath or dynamically using a dependency management system like maven.

The following is a basic example of connection and interrogation of a MySQL database, the same code (with some changes) apply to other databases like Oracle DB,  MariaDB and Postgresql. These changes may include at least the driver name and in some cases  the SQL syntax.

(The explanation of the different steps will follow the code example )

package tutoref;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Statement;

public class JDBCMySQLExample {
 
 // Database URL and Driver
 static final String JDBC_DRIVER = "com.mysql.jdbc.Driver";  
 static final String DB_URL = "jdbc:mysql://localhost/TUTOREFDB";
 
 //  Database username and password
 static final String DB_USERNAME ="username";
 static final String DB_PASSWORD ="password";

 public static void main(String[] args) {
  
  try {
   
   // registering the driver
   Class.forName(JDBC_DRIVER);
   
   // creating a connection
   Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD);
   
   // creating a normal statement
   Statement statement = connection.createStatement();
   
   // execute a SELECT query and create a ResultSet that holds the results
   String query="SELECT * from USERS";
   ResultSet resultSet = statement.executeQuery(query);
   
   // iterating through the ResultSet (Display results)
   while(resultSet.next()){
    System.out.println(resultSet.getString("username"));
   }
   
   // create a prepared INSERT query
   String preparedQuery="INSERT INTO USERS(username, password, email, first_name, last_name) VALUES(?,?,?,?,?)";
   PreparedStatement preparedStatement = connection.prepareStatement(preparedQuery);
   
   // fill the values
   preparedStatement.setString(1, "john.doe"); // username, the 1st index=1 and not 0
   preparedStatement.setString(2, "123demo"); // password
   preparedStatement.setString(2, "john.doe@tutoref.com"); // email
   preparedStatement.setString(2, "John"); // first name
   preparedStatement.setString(2, "Doe"); // last name
   
   // execute the query
   boolean success=preparedStatement.execute();

   // free the resources
   if(resultSet != null){
    resultSet.close();
   }
   if(statement!=null){
       statement.close();
   }
   if(preparedStatement!=null){
    preparedStatement.close();
   }
   if(connection != null){
    connection.close();
   }
   
  } catch (ClassNotFoundException | SQLException e) {
   e.printStackTrace();
  }
 }

}

 

Explanation

Registering the driver

Most of the database specific classes are included in the provided driver. You need to register the driver in order to be able to create a connection.

Class.forName("com.mysql.jdbc.Driver");

Creating a connection

The connection object is the link ensuring the communication between the code and the database, you must get a connection to be able to interrogate the database.

The connection object is obtained via the static method getConnection() of the class DriverManager.

Connection connection = DriverManager.getConnection(DB_URL, DB_USERNAME, DB_PASSWORD);

Creating a Statement

A statement object is obtained from the connection object, it is used for executing a static SQL statement and returning the results it produces.

Statement statement = connection.createStatement();

CREATING a Prepared STATEMENT

In some cases it is more suitable to use a Prepared Statement in the place of a static Statement. A common example is when you want to protect your application against the SQL Injections.

To obtain a prepared statement you must use one of the prepareStatement(…) static methods of the class DriverManager, and specify a query containing interrogation symbols in the place of values.

You have to specify the values before you execute the query and get the results.

PreparedStatement preparedStatement=connection.prepareStatement(
"INSERT INTO USERS(username, password, email, first_name, last_name) VALUES(?,?,?,?,?)")
   
// fill the values
preparedStatement.setString(1, "john.doe"); // username, the 1st index=1 and not 0
preparedStatement.setString(2, "123demo"); // password
preparedStatement.setString(2, "john.doe@tutoref.com"); // email
preparedStatement.setString(2, "John"); // first name
preparedStatement.setString(2, "Doe"); // last name

Executing the query and getting the results

When your Statement or Prepared Statement is ready, you can execute the query and get the results.

If you execute a query of type SELECT, you must use the executeQuery method of the statement object, the results are returned inside an iterable object of type ResultSet.

ResultSet resultSet = statement.executeQuery(query);

while(resultSet.next()){
  System.out.println(resultSet.getString("username"));
}

The above code will print the usernames on the console.

If you execute a query of type UPDATE, DELETE or INSERT, you can use the execute() method, which returns true if the first result is a ResultSet object, and false if the first result is an update count or there is no result. You also have the possibility to use the executeUpdate() method, that returns either  the number of deleted, updated or inserted rows or 0 for SQL statements that return nothing.

Freeing the resources

When you work with databases, you have to close the resources manually, otherwise you can have problems with the DBMS limitations. Elements having to be closed include (in this order) , the ResultsSets, The statements and the connection.

Examples of lambda expressions used with forEach(), removeIf(), replaceAll() and sort() functions

In this tutorial I will cover the use of lambda expressions with the Collection’s functions forEach(), removeIf(), replaceAll() and sort() . The Lambda Expressions can replace a type of Functional Interface.

There are several Functional interfaces included in Java 8, located in the package java.util.function. The choice of any of these FIs depends on the situation. For example, in our tutorial, each of the mentioned functions takes a specific type type of Functional Interface (BiConsumer, Predicate, etc) .

forEach

Use case with java.util.Map

When used with a Map, the forEach() function takes in parameter an object of type BiConsumer, which is a specialization of the Consumer functional interface.

As a Map element is defined by a key and a value, the BiConsumer FI represents an operation that accepts two input arguments and returns no result.

So, for this example I will create a map that contains  the names of some of Real Madrid soccer team players as values, and their numbers as keys. Then, I will iterate through the players using the forEach function and display each one prefixed by his number.

Map<Integer, String> players = new HashMap<Integer, String>();
players.put(2, "Dani Carvajal");
players.put(19, "Achraf Hakimi");
players.put(4, "Sergio Ramos");
players.put(12, "Marcelo");
players.put(8, "Toni Kroos");
players.put(7, "Christano Ronaldo");

Now I will call the forEach() function from the players Map. I will create a functional interface of type BiConsumer to hold the lambda expression that will print each player.

BiConsumer<Integer, String> consumer = (k,v)-> System.out.println(k + " : "+ v);
players.forEach(consumer);

This can be simplified to only one line like the following :

players.forEach((k,v)-> System.out.println(k + " : "+ v));

The execution will print the following list:

2 : Dani Carvajal
19 : Achraf Hakimi
4 : Sergio Ramos
7 : Christano Ronaldo
8 : Toni Kroos
12 : Marcelo

 

Use case with java.util.List

For this example, I will use the same list of players but without the keys (the numbers) as I will be using a List instead of a Map.

When used with a List, the method forEach() takes an object of type Consumer as parameter.

List<String> players = new ArrayList<String>();
players.add("Dani Carvajal");
players.add("Achraf Hakimi");
players.add("Sergio Ramos");
players.add("Marcelo");
players.add("Toni Kroos");
players.add("Christano Ronaldo");

Then I will create my lambda expression of type Consumer that will take a parameter of type String and print it on the Console. The Consumer object ( or the lambda expression) will be passed as parameter to the forEach() function in order to display the player names.

Consumer<String> consumer = (player)-> System.out.println(player);
players.forEach(consumer);

This will print the following :

Dani Carvajal
Achraf Hakimi
Sergio Ramos
Marcelo
Toni Kroos
Christano Ronaldo

Of course, I could use only one line to simplify the code:

players.forEach((player)-> System.out.println(player));

 

removeIf

The remove if function takes an object of type java.util.function.Predicate as parameter.

A Predicate is a Functional Interface that represents a boolean-valued function of one argument. It means that the Lambda Expression I will create will take a parameter and return a boolean.

To show the use of the removeIf() function, I will create the same list but I will do an intentional mistake : I will add Messi the list of Real Madrid players, so I will use the removeIf function to delete the players with a name equal to Messi, then I will print the List.

// create the list
List<String> players = new ArrayList<String>();
players.add("Dani Carvajal");
players.add("Achraf Hakimi");
players.add("Sergio Ramos");
players.add("Marcelo");
players.add("Toni Kroos");
players.add("Christano Ronaldo");
players.add("Messi");

// create the lambda expression of type Predicate
Predicate<String> predicate = player -> player.equals("Messi");
players.removeIf(predicate);

// display the players
players.forEach((player)-> System.out.println(player));

The result of execution will be a list without Messi !

Dani Carvajal
Achraf Hakimi
Sergio Ramos
Marcelo
Toni Kroos
Christano Ronaldo

replaceAll

The replaceAll() function takes as parameter a Functional Interface of type UnaryOperator when used with a List. A UnaryOperator represents an operation on a single operand that produces a result of the same type as its operand.

In this example, and for a reason I don’t know, I will replace all the name of Christiano Ronaldo by ********* . Practicality, My Lambda Expression will take a parameter of type String  and return a value of the same time but after the replacement by ******** is done.

// create the list
List<String> players = new ArrayList<String>();
players.add("Dani Carvajal");
players.add("Achraf Hakimi");
players.add("Sergio Ramos");
players.add("Marcelo");
players.add("Toni Kroos");
players.add("Christano Ronaldo");

// create the lambda expression
UnaryOperator<String> unaryOperator = 
  s->{
   if(s.equals("Christano Ronaldo")){
    return "******";
   }else{
    return s;
   }
  };

// do the replacement 
players.replaceAll(unaryOperator);

// display the list
players.forEach((player)-> System.out.println(player));

The result will be as follow :

Dani Carvajal
Achraf Hakimi
Sergio Ramos
Marcelo
Toni Kroos
******

sort

The Collection’s sort() method takes two objects as parameter :

  1. The list being sorted;
  2. A Functional Interface of type Comparable (say an Interface of type Comparable for java 7 and bellow).

In previous versions of Java, we had to implement the Interface Comparable and override the compare() method in order to implement the way in which we want the comparison to be done.

In Java 8 however, All we have to do is to pass a Lambda Expression as second parameter, defining how the comparison is done.

in this example I will sort a list of players based on their score.

I will first create a Player class .

class Player {
   
   private String name;
   private Integer score;

   // 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() {
    return "[name : "+this.name+", score : "+this.score+"]";
   }
   
}

Then I will create a list of players with their scores, and passing  two parameters to the sort( ) function :

  1. The list to sort;
  2. a Lambda Expression determining how the comparison is done.
// Create a list of players
List<Player> playerList = new ArrayList<Player>();

// add some players, and their scores
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));

// 1-Define how the sorting will be done in the Lambda Expression (Second parameter)
// 2-sort
Collections.sort(playerList, (p1, p2) -> p1.getScore().compareTo(p2.getScore()) );

// display the sorted list of players (ascendent order)
System.out.println(playerList);

The result of the execution will be as follow :

[[name : Albert, score : 450], [name : Messi, score : 500], [name : Ronaldo, score : 750], [name : Michel, score : 750], [name : Mario, score : 750], [name : Roberto, score : 900]]

 

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

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.