It’s spring. A time of changes and hope Oracle contributes to all that with a new version of the standard Java platform. I am talking about version 8, released in March 2014.

Previously published on Today Software Magazine.

Beginning with the current issue of Today Software Magazine, I wish to change the type of articles that I write. I cannot say I abandon the idea of book reviews, which represent an important way of putting forth some valuable books from the IT library, but I will also add some articles of a higher technical degree. By doing this, I hope the readers of the magazine will be incited to discover what is new and performing in the world of software applications development.

I am very glad this issue is launched in Brasov as well, and, though it is the first launching here, I hope it to be followed by many others. Brasov has an enormous potential, and I love this city very much.

Java SE8 is considered to be revolutionary, due to some of the newly introduced features. Initially scheduled for September 2013, the release was postponed to March 2014. The reasons are manifold, but they are basically related to debugging and security improvement, especially on the client side, having JavaFX as the main reason.

There are many changes and additions in the language, but probably the most spectacular one is the introduction of lambda capabilities. They are seen as an important benefit in parallel programming. Actually, the efforts for increasing the performance in parallel programming were seen even from version 7, the introduction of the Fork-Join framework is only an example.

In the first part of the article I will focus mainly on lambda expressions; in the final part I will discuss a bit about a brand-new JavaScript engine, and in the following articles I will talk about other Java SE8 related topics.

A lambda function (anonymous function) is a function that is defined and called without being connected to an identifier. Lambda functions are a form of nested functions, meaning that they allow access to the variables from the domain of the function where they are contained.

The anonymous functions were introduced by Alonzo Church in 1936, in his theory on the lambda calculations. In the programming languages, the anonymous functions were implemented in the year 1958, as part of the Lisp language. In some Aspect Oriented Languages such as Java, there are similar concepts, such as the anonymous classes. It is only in the ٨th version of Java language that the anonymous functions are added. Other languages, such as C#, JavaScript, Perl, Python, Ruby had been offering support for this concept for a long time.

Lambda expressions allow us to create instances of classes with one single method in a much more compact manner.

A lambda expression is made of:

  • a list of formal parameters, separated by a comma and maybe contained within round brackets
  • the directional arrow ->
  • a body consisting of an expression or a set of instructions.

A functional interface is any interface containing only one abstract method. For this reason, we can omit the name of the method when we are implementing the interface and we can eliminate the usage of anonymous classes. Instead, we will have lambda expressions. A functional interface is annotated with @FunctionalInterface.

In order to understand the way of working with lambda expressions, I have built a little example in which I have created collections of objects sorted out according to different criteria. The implementation of the Comparator interface was done in an anonymous class, by using lambda expressions. The implementation with lambda expressions was possible because in version ٨, Comparator is annotated with @FunctionalInterface.

The basic item of the collection is the Product class, which is a POJO class with getters and setters. The class contains two anonymous implementations of the comparator, determining the ascending or decreasing classification of the collection items.

package model;

import java.util.Comparator;

public class Product {
	private String name;
	private int price;

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public int getPrice() {
		return price;
	}

	public void setPrice(int price) {
		this.price = price;
	}

	public void printProduct() {
		System.out.println(this.toString());
	}

	@Override
	public String toString() {
	 return “Product [name=” + name + “, price=” + 
	 price + “]”;
	}
	
	public static Comparator 
	 ascendingPrice = (p1, p2) -> {
	  return p1.getPrice() - p2.getPrice();
	};

	public static Comparator 
	 descendingPrice = (p1, p2) -> {
	  return p2.getPrice() - p1.getPrice();
	}
}

The test class will bring something in addition, compared to a class known until version 8. The collection processing will not be done with a classical foreach. As a part of the Collections API, we have the new java.util.stream API, which offers support for functional operations on streams of items. In our example, we will use a basic interface of this API, namely Consumer, which represents a procedure that accepts only one entrance argument and does not return anything. With Consumer, we will be able to use lambda expressions:

import java.util.Set;
import java.util.TreeSet;
import java.util.function.Consumer;

import model.Product;

public class TestLambda {

  public static void processProducts(
    Set products, Consumer block) {
      for (Product p : products) {
	 block.accept(p);
      }
  }

  public static void main(String[] args) {

    Product p1 = new Product();
    p1.setName(“onion”);
    p1.setPrice(10);
    Product p2 = new Product();
    p2.setName(“tomato”);
    p2.setPrice(20);

    Set ascendingPriceProducts = 
      new TreeSet<>(
    Product.ascendingPrice);
	
    ascendingPriceProducts.add(p1);
    ascendingPriceProducts.add(p2);

    System.out.println(“In ascending order:”);
    processProducts(ascendingPriceProducts,
      p -> p.printProduct());

    Set descendingPriceProducts = 
      new TreeSet<>(Product.descendingPrice);

    descendingPriceProducts.add(p1);
    descendingPriceProducts.add(p2);

    System.out.println(“
In descending order:”);
    processProducts(descendingPriceProducts, 
      p -> p.printProduct());

  }
}

As a consequence of using the stream API, the procedures carried out on a collection can be much more complex than the ones illustrated in the example, namely: filtering by a selection predicate, mapping the filtered object, respectively carrying out an action on every mapped object. I have only presented the last operation. They are called aggregate operations.

I would like to make an observation on the previous code: the implementation of the comparator stands for overwriting of the equals() function, fact that can be proved by the alteration, in the code, at equal values of the price.

Besides the lambda expressions, an important feature, obviously together with the syntactical changes and the introduction of new APIs, is in my opinion the development of the JavaScript Nashorn engine. Through it, one can integrate JavaScript scripts into the classical Java code. This engine is based on the ECMAScript 262 standard. It is an engine written completely from scratch, in view of increasing the performance. Thus, it is completely different from the already existing engine, Rhino.

I will only provide a short example of using this engine, with the promise that in the future I will present more details:

import javax.script.*;

public class EvalScript {
  public static void main(String[] args)
   throws Exception {
  // create a script engine manager

  ScriptEngineManager factory = 
    new ScriptEngineManager();

  // create a Nashorn script engine
  ScriptEngine engine = factory.
    getEngineByName(“nashorn”);
  
// evaluate JavaScript statement
  try {
    engine.eval(“print(‘Hello, World!’);”);
  } catch (final ScriptException se) {
    se.printStackTrace();
  }
 }
}

By running this example, we will get Hello, World! on the console.

As a last observation, I have used Eclipse Kepler for editing and from Marketplace I brought Eclipse Java 8 Support (for Kepler SR2) JDT, PDE 1.0.0. This is only till Eclipse Luna is released (probably in May). As a Java version, I used jdk 1.8.0_05.

Enhanced Hybris Commerce Competence: Accesa becomes SAP PE ...

news / May 14, 2019
SAP features various levels of recognition, and with this ...

Accesa and OutSystems, partners for fast delivery of enter ...

news / May 16, 2019 / 6 min read
Accesa and OutSystems sign a partnership agreement to deli ...

Accesa and UiPath partner to enable business transformatio ...

news / May 16, 2019
As of June 2018, Accesa is an official partner of UiPath – ...

Say hello

Frankfurt

Eschborner Landstr. 42-50
60489 Frankfurt, Germany
Phone: +49 89 2154 851 15

Munich

Walter-Gropius-Str. 17
80807 Munich, Germany
Phone: +49 89 2154 851 15

Zürich

Wallisellen, Zwirnereistr. 22
8304 Zürich, Switzerland
Phone: +41 44 830 92 30

Cluj-Napoca

Constanta 12, Platinia
400158 Cluj-Napoca, Romania
Phone: +40 364 115 115

Oradea

Cetatii Square 1, Oradea Plaza
410520 Oradea, Romania
Phone: +40 364 115 115

Whether you’re interested in our services or you would like to learn more about our company, we are happy to provide you with the information you need.