Home  >>

Tuesday, 2 April 2013

Introduction to JSR 310 Part 2 : Overview of Joda Time API



Hi Friends, 
In continution with our discussion about JSR 310 (the New Java Date and Time API), we will now move further to understand the JODA time API in brief and then we will have a detailed overview of JSR 310. If you have not read the first part of this discussion, please go and check out Introduction to JSR 310 Part 1 : Overview of existing Date and Time API .

Till now, we have seen that Java's existing Date and Time API has lot of issues and shortcomings. This has helped Joda Time API to gain popularity in the Java developers. Joda Time API is a set of API that addresses most of the shortcomings of the Java's own Date and Time API. 


The Joda Time API, drastically changes the Date and Time handling in java with the help its uniform structure. The Joda Time API supports eight different  Calendars like Gregorian, Julian, Buddhist, Islamic etc. This API is really famous not only because of the weaknesses of Java Date and Time API but also because of its easy to use, extensible and simplified design. This API has set of various Date and Time classes which are immutable by nature and can be used safely within multithreaded environments. Lets have a quick overview of the key concepts of Joda Time API


Instant:

As per the Joda Time documentation the instant can be defined as below.
An Instant is a moment in date-time continuum specified as a number of milliseconds from the start of 1970-01-01.

The Instant is represented in the form of an interface ReadableInstant and implemented by the mostly used class DateTime. This implementation is immutable and hence thread safe. The fields on this class instance can't be changed once it is created. The API also has MutableDateTime - a mutable implementation of ReadableInstant.
The other major implementation of the ReadableInstant are Instant and DateMidnight.
The Instant represents exact point in a time line irrespective of Chronology or Time Zone in the form of milliseconds.The DateMidnight represents a date whose time component is set at Midnight (start of the date). This class instance is a representation of midnight in the form of milliseconds and doesn't represent the whole day.



Interval:

As the name suggests the it represents interval of time from once instant to the other instant where the start instant is inclusive and the end instant is exclusive, the end instant is always greater than the start instant, and both of the instants belong to the same Chronology and Time zone. 

The interval in Joda time is represented in the form of an interface ReadableInterval along with a Interval (immutable interval) and MutableInterval  implementations.



Duration:

This is a duration of time measured in milliseconds. This doesn't have any restrictions of Chronology or Time zone and it is just represents the time duration between two instants. It is also used to compare two intervals. Intervals give us duration and durations can be compared to each other. 
In the API duration is represented in an interface ReadableDuration. the Duration implementation is also available in mutable and immutable versions. Duration doesn't contain fields like day or seconds, but it can be converted to Period to obtain the fields. 



Period:

It is a time Period defined in terms of fields like year, month, week, day, hour etc. This is really useful feature as it gives us flexibility to divide things into year, months, days etc. When we say add a period of 1 month to 1st April and the answer will be 1 May (added 30 days) the same thing when tried with 1st May the answer will be 1 June (added 31 days). As a programmer we don't need to bother about such things as long as the Chronology and the Time Zone is correct. Adding 1 Day when DST changes may correctly add only 23 hours but if we added 24 hours explicitly the results will be wrong.

Similar to other features the Period is also represented in the form of an interface ReadablePeriod and is available in mutable and immutable implementations. 




Chronology:

This is the most important part of the Joda time system as it handles the complex rules for a Calendar. Many different Chronologies are supported by the means of subclassing e.g. ISO, Gregorian, Coptic etc. To setup any Chronology, we should use factory methods provided on each subclasses. 


GregorianChronology.getInstance();


All of the specific Chronology implementations are immutable and thread safe. This class is really great on the design side but a kind of overhead. That is mainly because, for most of the times users will be interested in using the ISO chronology but the Chronology and field classes are maintained as Singletons and there will there will be a cost of creation and garbage collection. 




TimeZone:

in the Joda Time API the time zone is represented as DateTimezone. Time zone has a set of rules that converts a time of one geographical location to the other. Usually all of the time zones are represented relative to Greenwich Mean Time (GMT), but the Joda Time library refers to the Universal Coordinated Time (UTC). 

The DateTimeZone class has factory methods to create a specific TimeZone instance. 
DateTimeZone tz = DateTimeZone.forID("America/Los_Angeles");


It is also capable of giving a DateTimeZone based on the offset hours.
DateTimeZone tz = DateTimeZone.forOffsetHours(offset_hours);


Similar to Java Date and Time API, the Joda Time API also supports a default time zone that is when the time zone is not specified. API also has a method to set a default time zone.
DateTimeZone tz = DateTimeZone.getDefault();
DateTimeZone.setDefault(default_time_zone);


Just like the many of the Joda Time classes the DateTimeZone is also immutable and hence thread safe. 




The Joda Time API addresses most of the drawbacks of the existing Java Date and Time API, and it is the best and the most powerful Date and Time library available as of the now. But the Joda time API also has few design flaws.


Interfaces: 

In the Object Oriented paradigm the interfaces play a vital role in providing flexibly and reusability. Mostly we create a reference of the class Type and make is refer to instance of a specific implementation. So that we can anytime change the implementation instance while keeping the code same. 

In Joda Time API this flexibility is lacking. For an example, have a look at ReadableInstant interface. This interface has implementations like Instant and MutableInstant and hence this interface cannot contain the setters implemented by MutableInstant

We cannot have ReadableInstant reference along with MutableInstant instance and utilize it's mutability. We have to use the reference of a concrete type MutableInstant. Joda Time documentation encourages developers to use concrete references and Type references. 

The API still manage to provide some sort of implementation flexibility by providing conversion methods as shown below. 


DateTime dateTime = dateTimeInterfaceReference.toDateTime();

This can be used inside methods where the method accepts a parameter of an interface type and the method converts it to the desired implementation. 


Handling Nulls:

The the Joda Time library the handling of nulls is not uniform throughout the API and most of the methods accepts it as a valid value. The date time classes when set to null represents the epoch time (i.e. 1970-01-01T00:00Z) while the duration or period considers null as zero. 

This may cause number of issues when a program accidentally and unexpectedly sets null. As the API doesn't throw exception for the null values system may produce unexpected outputs and that is hard to debug. 



Pluggability: 

One of the major design strength of the Joda Time API is its pluggable Chronology. No doubts this pluggability gives lot of flexibility and reusability but it can result into serious issues. 

Suppose you call getMonthOfDay method on the Joda Time and what if it returns 13. December is still the 13th month and January is still the 1st. This can happen if the Chronology is set for Coptic Chronology which has 13 months in a year. You have no clue, before calling the method, to know the Chronology the instance is set for. Hence it would have been better if they had not supported pluggable Chronology.



The Joda Time API is also has architectural complexities and even smaller functional changes results in big design changes. The major issues are with pluggable chronologies, improper differentiation of machine and the human aspects of the timeline and the complexity of DST overlap behaviors.

There was a thought of including the Joda Time API as a part of JDK, but because of the design flaws in the system, the author decided to develop a completely new API from scratch and include it in JDK. This API is known as JSR 310 (new Java Date and Time API).


In this part we have gone through the brief of the famous Joda Time API and tried to understood the cons. In the next section we will touch the JSR 310 (new Java Date and Time API) in detail with the help of examples.


<<   Part 1 : Overview of existing Date and Time API




Tuesday, 26 March 2013

Introduction to JSR 310 Part 1 : Overview of existing Date and Time API



Greetings everyone!


It has been a long time since my last post. So far, we have emphasized more on the Introduction of some of the very cool Java 8 features. We also tried to understand the concepts with the help of example code. Moving ahead in the same train, in this Java Tutorial we will check out a yet another exciting Java 8 Feature and that is JSR 310 a new Java Date and Time API. 



The New Java Date and Time API (a. k. a JSR 310 or ThreeTen) was originally planed to ship with Java SE 7. But because of the delays in the progress of the project ThreeTen (project JSR 310), the plan changed to Java SE 8 and further changed to Java SE 9. Very recently, it has been officially declared that, the Java Date and Time API progress is in a good shape and it will be able to safely catch the Java SE 8 train. 



A Date and Time mechanism is very critical in any programing language. The existing Java Date and Time API has lot of problems and a non-unified structure. The JSR 310 aims to enhance the current Java Date and Time support by introducing a new package called as ‘java.time’.  Before we move ahead, we will have a look at the problems with existing API.


Existing Java Date and Time API:



The Java Date and Time support exists since the beginning of Java. It has been evolved during this time with the addition of new classes and modification of the existing ones. Because of this, many classes have their own constructs and they do not follow a common structure with the other Date and Time classes. This ends up giving a bunch of classes with their independent behavior and set of their own limitations. 

The very basic problem with the Date class is that, it is mutable. 

  
    private Date dateOfJoining;
    public Date getDateOfJoining() {
        return dateOfJoining;
    }


The getDateOfJoining method above returns a Date object. But the client is still able to call a setter method on dateOfJoining. This makes it very unsafe to be used in the multithreaded environments. If we print the dateOfJoining it returns.

Mon Mar 25 11:21:45 GMT+05:30 2013



The intention is to capture the date when the student actually joined the institute, but the Date class unnecessarily captures the time as well, which we do not need and can be misleading when the Date is shared along with the clients. In Java Date and Time Mechanism, there is no possibility of storing only Date without Time and Only time without Date. To represent only Date, we usually put default time of 12 mid-night. This may introduce a new problem, as in some regions there is no mid-night once in a year, because of DST changes. 




In Java’s date class the epoch is considered as 1st January 1900, which too far, and hence results in larger calculation. Also it is not able to deal with a time unit smaller than millisecond. Java is a faster language and it is impossible to calculate statement execution times with the help of milliseconds. 




Another interesting problem with the existing Java Date and Time mechanism is its month calculation begins with a zero. January is a 0th month and December is 11th. This makes it error prone when a month is set from outside with the help of integer. It was very complicated with Java Date class to develop a system that can works in different time zones across the world, as Java Date class doesn't support Timezones.


The lately introduced Calendar class is little smarter and also supports TimeZone, but it also has its own set of problems. The Calendar considers the epoch from 1 January 1970. As the respective methods in Java Date have been deprecated, this is the class which we need to use when we want to set Months, Day, Year separately. The Java Calendar is also mutable, and hence unsafe in multithreaded environments.  


When we want formatted Date, we can use SimpleDateFormat. Calendar dates can not be formatted with the help of SimpleDateFormat. To format a Calendar date we first need to convert it to Date and then format it. Calendar has lots of performance issues as it calculates time difference in milliseconds since the epoch multiple times for internal processing. 


Another big problem with the Java Date and Time is, it break the rule of equality. See the following code. 

    Date date = new Date();
    Timestamp timeStamp = new Timestamp(date.getTime());
    System.out.println("date.equals(timeStamp) => "+date.equals(timeStamp));
    System.out.println("timeStamp.equals(date) => "+timeStamp.equals(date));

The output is:

date.equals(timeStamp) => true
timeStamp.equals(date) => false


According to the symmetric rule of equality, both the of answers should have been true. But this is not true in this case. 
Also the Java Date and Time mechanism doesn't have a control over the Day Light Saving. It can't be turned OFF or ON depending upon the need. 




So far we have seen the problems with the traditional Java Date and Time mechanism. In the next section, we will have a brief look at the JODA Time API, which is used as an alternative to overcome the shortcomings of the default Java Date and Time API and then we will move in detail with the new Java Date and Time API (JSR 310) in the next section.



Part 2 : Overview of Joda Time API   >>






Friday, 26 October 2012

Java Preferences API - An Introduction



In this Java Tutorial we are going to discuss about a somewhat old but not so famous API of the Java Programing Language. It has been a long time since the Java Preferences API has been introduced to Java SE (JDK). Java Preferences API is extremely lightweight and a cross platform persistent API. Being a persistent API, it does not deal with the database engines but uses OS specific backend to store and retrieve data. 

Many a times our programs are required to store/access smaller amount of data, something like user preferences, or system preferences. The preferences data is so small that it is too expensive to use something like a Database driven persistence layer or any other registry services. Making use of the properties file along with the Java Properties API could have been a better solution, but the problem with the properties files is that they don’t have any standards about where the files should be stored on a disk and what should be the naming strategy for multiple properties files. This makes it difficult to use properties API as a standard and cross platform 


In JDK 1.4, java.util.prefs package was introduced, which has a simple API for storing the preferences to the OS specific backend. The Java Preferences API doesn’t talk about how the API should be implemented. The different implementations of JRE can implement the API specific to its targeted OS. On the operating systems like Windows the preferences are stored on the OS level registries, and for non-Windows environments, they can be stored into other registry like storages, may be on a simple XML file as well.



How To:


The API is designed to work with almost all of the Java Basic data types like numbers, Booleans, characters and strings. The data is stored in a form of key-value pairs, which makes it very simple to use. As per the usual programming needs the API specifies to have two different nodes/storages of preferences one for User Preferences and other for System Preferences. Below lines show how simple it is to get access to these preferences. Though the node storages and the ways to access it are different on different environments, the below code works everywhere. 

Preferences userPreferences = Preferences.userRoot();
Preferences systemPreferences = Preferences.systemRoot();



In below example we will try to put an integer to the user preferences and on the next line retrieve it with a get method. The get method takes an extra parameter that specifies a default value, which will be returned if the key is not found within the user node or the node is not accessible. 

//Store an int to User Preferences with String key
userPreferences.putInt("NUMBER_OF_ROWS", 25);
  
//Retrive an entry from User Preferences, 
//the number sent as a second parameter will be returned if the key doesnt exist
int numberOfRows = userPreferences.getInt("NUMBER_OF_ROWS", 10);



The API also provides us with a way to remove any preference: shown below. 

userPreferences.remove("NUMBER_OF_ROWS ");

The remove method doesn’t throw any exception even if doesn’t find the given preference in a node.




Package Specific Preference Roots:  


As the preferences are stored directly on the OS level storages, they do not have any dependency on the program or the JRE accessing it. A preference set by a program can be accessed by another program, which is running under a totally different JRE on the same machine. This leads to a problem as different programs to store different values can use the same ‘key’. When each program calls put for a same key, the preference value is actually being overwritten. 

To overcome this problem, the Java Preferences API has come up with different subsets of the preference roots. The preferences stored within a specific sub root will only be accessible within the sub root. Different sub roots can now have their own preferences with the same key. The Java Preferences API supports package level sub roots and any class within the package can access the same set of preferences. 

Preferences userPreferences = Preferences.userNodeForPackage(getClass());  
userPreferences.put("LANGUAGE_I_SPEAK", "ENGLISH");

In this example the preference is created as “User Preference Node: /com” where the ‘/com’ is the package of my class (getClass()). Now below is a code from another class of the same package.


Preferences userPrefsFromAnotherClass = Preferences.userNodeForPackage(getClass()); 
String language = userPreferences.get("LANGUAGE_I_SPEAK", "JAVA");



The package specific preferences are created as a separate sub-root. But the sub-roots are not aware of name of the project containing the package. Hence, if two different projects have packages with same name, the preferences create by one package will be accessible to the other package of different project. We need to take care in this scenario.




Custom Preference Nodes:


In the above example the sub-roots are created specific to the package names. But we can also create our own sub-roots with custom logical root names. In the below example I am creating a user preference with a logical root name. The same preferences can be accessed from any program and package on the same machine. 

Preferences userPreferences = Preferences.userRoot().node("/my/custom/root");
userPreferences.put("LANGUAGE_I_SPEAK", "ENGLISH");


Now the above preference can also be accessed by another program.


Preferences userPrefsFromAnotherClass = Preferences.userRoot().node("/my/custom/root"); 
String language = userPrefsFromAnotherClass.get("LANGUAGE_I_SPEAK", "JAVA");




We have seen the examples of user preferences but the system preferences works exactly the same way. In any application we can have a dedicated class to deal with the system preferences, and the other parts of the programs will access the preferences through the static methods of the class. But this is not that safe in case of user preferences, as there could be multiples uses logged into the system with different preferences. 









Wednesday, 3 October 2012

Java Collections API Enhancements: Thanks to Closures – Lambda Expressions



Friends, in the last tutorial we had a detailed introduction to Java 8’s Feature of Closures – Lambda Expressions. During the discussion, we understood the issues with the plain old Anonymous Inner Classes, learnt the Java Closures (Lamba Expressions) Syntax, and also practiced some of our own Java Lambda Expression examples along with the conceptual and practical understanding of Functional Interfaces, Method References, Constructor References and Default Methods.

In this Java Tutorial we are going to discuss about Java 8’s modification to the Java Collections API. The Java Collections Framework is being enhanced in order to get the benefits out of the latest Java 8 Feature that is Closures. If you are new to the concept of Java Closures or Lambda Expressions, I recommend you to go through my previous post: Introduction to Java Closures – Lambda Expressions.

Java Lambda Expressions would surely change some of our programming habits and also the way we look at the language, including the various Java APIs. When a feature like Lambda Expression is added to a programming language, it becomes extremely important to utilize the new feature to empower the overall programming model along with the existing set of libraries. With addition of Closures to Java, the existing Java Collection Framework will start looking weaker and outdated. The Java Collections framework was introduced in Java 1.2, and since then its core interfaces have never been changed. This is because, the Java Collections framework is so widely used, that any changes to it will surely broke many existing functionalities, and that’s why it is not easy to completely rewrite the Java Collections API. There was another option to keep the existing Collections API as is, and add an additional Lambda Expression friendly version of the API, but that would lead to tremendous amount of changes in the existing code, which depends upon the Collections API. Also applications will have to maintain two different versions of the library, and what if somebody wants to use a mix of old and new features? To overcome these challenges, Java 8 has added new set of methods to the existing collection classes and interfaces. Having these methods under the belt, the Java Collections framework will work as it used to be; and will also have an additional potential to support Java’s Lambda Expressions or Closures.



The Existing Behavior: 

No doubt, the existing Java Collections API is nice and we are very much habitual to use it. But as stated above, having Lambda Expressions in the toolbox we can naturally start noticing the some of the shortcoming of the exiting framework. Lets have a look at below problem.

We want to print scores of all the students with name as “Tom” and print their respective scores. To model this, I will iterate through the list of Student and create a new List of Student who have name as “Tom”, which will be iterated over to print scores of individual students.

List<Student> studentsNamedAsTom = new ArrayList<>();
for (Student student : students) {
 if (student.getName().equals("Tom")) {
  studentsNamedAsTom.add(student);
 }
}
  
for (Student student : studentsNamedAsTom) {
 System.out.println("name: " + student.getName() + " -> Score: "+ 
                           student.getScore());
}


I know, I could have combined the functionality in a single for loop, but I intentionally wanted to keep them split across the loops, so that I can anytime change any loop without affecting the other and possibly you may consider, both the for loops belong to two different methods. Now, lets try to identify the problems associated with this code. 

First of all, as a client to the Collection (list of Student), I have to ask for an iterator (through the for-each loop) and iterate through it. I will have to take care of iteration logic and putting conditions between iterations. Ideally a client should only be concerned about What To do with the collection and not about How To do.

The studentsNamedAsTom is just a temporary object and it is only concerned about to pass values from one for loop to the other, or possibly from one method to other.  These temporary objects are overhead for the memory and mostly referred as Garbage Objects. For complex programs we end up creating bunch of such a garbage object, which are just meant to temporarily hold the values.

Now think of a scenario, the student list contains thousands of records, that mens the first for loop will iterate those many number of times. But assume, only 40th and 55th number students are “Tom”. There is no point in iterating the list after 55 elements. Suppose in the second loop, I want to print only those “Tom”s who have scores more than 80, and there might be only one student matching this. As a client I have no control to avoid such an unwanted iterations.

All of these operations take place sequentially (one after the other). If we want to optimize the behavior by creating multiple threads, we will have to take of the concurrency along with the logic of iterations and operation and it will surely make the code look complex.

Now its time to discuss the Java 8’s Collections Framework Features, and how they solve the above mentioned issues.



Mode of Iterations:

As discussed above, when a client wants to operate on a collection, it has to access the iterator, manually iterate through it, and also has to put the functional logic in the iterations. This approach is basically simple and straight, as the operations are sequential and the elements are processed in the order in which they appear in the collection. This kind of iterations is called as External Iterations.


The upcoming additions to the Java 8’s Collections API will make it to support Internal Iterations. In the Internal Iterations, the client abstracts the functional behavior and passes it directly to a method on collections in order to get it applied to all the elements of a collection. The library will be responsible for applying the behavior to the elements of collections. Hence client has to bother about ‘what’ and not about ‘how’. Lets have a look at the below example.


List<Student> studentsNamedAsTom =
           students.filter (student -> student.getName.equals("Tom"))
           .into (new ArrayList<>());

This is just a single statement, but its capable of doing a lot more than what our first for loop did. Before we get into these details, first understand what’s exactly happening here. Client provides the filter method with an implementation of Predicate (a functional interface). Instead providing anonymous inner class, we provide a Lambda Expression implementation for Predicate and pass it to the method. The library will internally iterate through the Collection and apply Predicate on it. This keeps the client from the iteration details and client can only concentrate on the ‘What’ and not ‘How’.

In case of internal iterations the library has full control over the iterations and it becomes possible for the libraries to use parallelism or optimize the memory usage in order to process the elements more efficiently. The client and the library can share the control on behaviors amongst each other and make the operation more efficient. Apart from this, the Internal Iteration makes the program very simple and readable. Below is a set of examples, which shows how easy it is to alter the program behavior without increasing any kind of iterative complexity.


//Set grade = “A” for students with score > 80
students.filter(s -> s.getScore() > 80)
         .forEach(s -> {
               s.setGrade(“A”);
               System.out.println("name: " + s.getName()+" -> Grade:"+s.getGrade());       
          });

//Create sublist of students having grade "A" and name starts with "N"
List <Student> sublist =
                 students.filter(student -> student.getGrade().equals("A") 
         && student.getName().startsWith("N"))
         .into(new ArrayList<>());

Now, in the subsequent sections, we will discuss the potentials of the Java Collection Frameworks internal iteration mechanism.



Benefits of Laziness:

We have seen in the plain collections example, that both of the for loops iterates through the entire collection they have, no matter what exactly we are looking for. When we put conditional statements in the iterations, naturally the condition will be applied from first through last elements in the collection. The condition may holds good only for first few elements and will not be matched for the rest of the iterations. This kind of operations is called as Eagar Processing and often results in a big performance toll for the programs. Following quote is the only solution for this.


Laziness can be a big Performance Advantage - Brian Goetz"

Brian Goetz (Oracle’s Java Language Architect) believes in this and his Java 8’s Project Lambda will surely make us too believe it. (Sometimes I feel proud of myself. No really!! It took 15 years for Java Collections to acquire this property, which I have been successfully holding since my birth). Eagar processing may sometimes sound expensive, because in simple words, when we put a condition the program doesn’t know about how the matched elements are going to be used by next block of the code. In such cases Lazy Processing is quite helpful, where we can process only what we need. In case of our plain collection example the first for loop iterates through the entire list of students and before the ‘for’ loop ends the second list of students is completely ready with all the matching elements populated in it. Below program does the same thing with a newer approach.


List<Student> studentsNamedAsTom = 
        students.filter (student -> student.getName.equals("Tom"))
 .into (new ArrayList<>());


What happens when we simply run the above code?
The answer is NOTHING. 
Because like many of the developers, some of the new methods on the Collections API are ‘Lazy’ and they don’t complete their tasks until the last minute. These developers and methods both are actually smarter, because at the last minute they have the most concrete requirements, and they can do what exactly is required unlike those who work a lot before the requirements are final. 


Now, the serious answer is also, NOTHING.

When we run the above statement, neither the collection is filtered nor the studentsNamedAsTo has anything in it. These things will actually trigger when we start iterating the studentsNamedAsTom. When the first iteration on studentsNamedAsTom is processed the Student collection is actually iterated for those many numbers of iterations, which are sufficient to provide studentsNamedAsTom with its first element. For second iteration of studentsNamedAsTom, the student collection will further be iterated until it gives second element to studentsNamedAsTom. If we decide to stop here, there wont be any extra iteration on Students. This behavior improves the performance significantly. 


This is possible because the studentsNamedAsTom is not actually a concrete collection object but it is a stream of data values, which are Itarable. When an iterator asks for a next element on stream, the stream will request it to the source collection. All the ‘lazy’ methods returns a stream, instead of concrete collection objects, this also reduces number of garbage objects created by the program and improves the memory performance.



With the help of stream, we can actually form pipeline lazy methods, one after the other. Each method takes stream as a kind of input and delivers processed stream as an output, which is taken by next method in the pipeline. This helps us plug-in and out any operation anytime, without affecting the code complexity. The advantage of the pipeline is that the code becomes more compact and readable.




More About Streams and Laziness:


As discussed above, the lazy operating methods produce steams of data values. The most important thing with streams is that, they don’t require storage. When a method returns a stream and next method takes that stream to process further, object is added on the memory. Streams just carry data from source through a pipeline of operations. Streams cannot modify the original source collection.

There are many stream operations, which can be applied lazily, which means we don’t need to iterate through the entire stream. We can just iterate through what we need, this saves the further processing which is required to generate further data in the stream. Also, as the streams are continuous flow of data, there are no bounds applied to it. Streams can hold infinite data. We can even have a stream of infinitely long numbers, which was never possible by the older Collections API. Lets have a look at a example program below, we are calculating sum of the scores of Classroom “A” students.




int sum = students.getFilter(s -> s.getClassRoom.equals("A"))
    .map(s -> s.getScore())
    .sum();

As the filter and map methods are lazy, the source will not be read until the call to sum method and there is no need to maintain intermediate objects.


When normally, we iterate through collections, we cannot change the source collections. While doing so we get ConcurrentModificationException. The same rule applies for the new set of methods. Hence when we pass lambda expressions to the collections methods, we should ensure that the lambda expressions are not modifying the source collection.



Support for Parallelism:

Normal operations on collections – such as Iterating a collection with Iterator, accessing each element, applying some filter and setting a new value to an element or creating sub collection of those elements - are sequential operations. That means all these operations are carried out in series (one-after-other). And for the same, there is a huge scope of performance improvements, if they same operations are carried out in parallel. We can perform the same operations by creating multiple threads, but then it adds complexity to the program. An extra care is required to be taken when we create multiple threads to process a single collection, because there is always a possibility of Concurrent Modification.

The new modification on the Java 8 Collections API makes it quite easier for developers. It has operations that have in-built support for parallelism, it gives control to the client, whether it wants to use parallelism, but most importantly, it keeps client far away from the internal complexities of the implementation of parallelism.

Java SE 7 had introduced a very exciting feature of Fork Join Framework, which works on the Work Stealing Algorithm. It divides a task into multiple subtasks and each subtask to further fine-grained subtasks until it is no more divisible. Then the fine-grained subtasks are performed sequentially and their results are combined to generate the outcome of the task. For more information on the fork join framework, please visit Introduction To Fork Join Framework with examples. The implementation details of division of tasks, subtask operations, and aggregation of the subtasks results are no doubt very complex, but the collection framework hides that behind the ‘parallel’ method. This method is simply a kind of parallelism switch, which you can put, and remove anywhere in the pipeline. Below is the modified, total score calculator program, where you can see, it takes nothing more than a single method call to plug-in parallelism in your operations.

int sum = students.getFilter(s -> s.getClassRoom.equals("A"))
    .parallel()
    .map(s -> s.score)
    .sum();

We have come to the end of this article. We emphasized more on the conceptual understandings than the implementation details of the features, because the Java 8 Collection Framework modification is still under the development and there are chances of changes to the information we have at this point. As the development progresses further, the detailed information of various methods, and Interfaces will be open, and then we can have a much-detailed overview of the Java Collections Framework. 



Tuesday, 14 August 2012

‘At First Sight’ With Closures in Java



The intent of this Online Tutorial on Java is to give a high level overview of the upcoming Lambda Project, which is being developed upon JSR-335 (Second Early Draft Review of JSR-335 is closed in June, 2012). The Lambda Project is going to be a part of Java SE 8 (Java 1.8), which is set to be released in 2013.

The JSR-335 introduces Closures in Java. The Closures are quite common in most of the popular languages like C++ and C#. Closures let us create function pointers and pass them as parameters; also the methods will be able to enclose the surrounding context as a snapshot so that it can be passed along with the method. In this article we will go through the Java 8 features, and introduce ourselves with the Lambda Expressions. I have tried to put some sample example programs codes to explain the concept and the syntax, better.

Java Programming Language provides us with the concepts of Interfaces that are capable of defining abstract methods only. Interfaces define an API and they expect users or vendors to provide implementations for their methods.
Many a times, we do not create separate implementation classes for a given interface. Instead of that we write inline interface implementations, which are also called as Anonymous Inner Classes.

Anonymous classes are used widely. In our day-to-day life we can see their presence in number of libraries. Anonymous classes are majorly used to specify event handlers within the components that generate events. Second major use of Anonymous classes can be seen in multithreaded programs. Many a times, instead of creating dedicated Runnable/Callable implementation, we write Anonymous classes.

As we discussed, an Anonymous class is nothing but an inline implementation of a given interface. Usually, we pass such implementation classes as an argument to a method and then the method will internally invoke methods on the passed implementation class. Hence such interfaces are called as Callback interfaces and their methods are called as Callback methods.

Though, the Anonymous classes are being used everywhere, they have number of problems. First and major issue is with the complexity. These classes make the code bulky and complex. Sometimes, it is also called as a Vertical Problem, because these classes will increase the vertical length of a program. Secondly, they cannot access the non-final members of the enclosing class. They sound confusing in terms of shadow variables and with the behavior the ‘this’ keyword. If an Anonymous class has variable with a name same as that of any member of the enclosing class then the inner variable will shadow the outer member variable. In that case the outer member will be invisible to the anonymous class and it can't even be accessed by mean of the 'this' keyword. The ‘this’ keyword in Anonymous class points to itself and not to the enclosing class.


public void anonymousExample() {
    String nonFinalVariable = "Non Final Example";
    String variable = "Outer Method Variable";
    new Thread(new Runnable() {
        String variable = "Runnable Class Member";

        public void run() {
            String variable = "Run Method Variable";

            //Below line gives compilation error.
            //System.out.println("->" + nonFinalVariable);
            System.out.println("->" + variable);
            System.out.println("->" + this.variable);
       }
    }).start();
}

The output is:

->Run Method Variable 
->Runnable Class Member

The output of this programs shows, how the inner variable has shadowed the outer one and the 'this' keyword refers to the Anonymous class scope only.

Though, they are not meant for this, but the Lambda expressions address almost all of the issues caused by an Anonymous inner class. Before we proceed further to the Lambda expressions, let's have a look at Functional Interfaces.



Functional Interfaces: 

Functional Interface is an interface that has just one method and thus represents a single function contract.

The word ‘single’ occurred in the definition is actually not that simple. The ‘Single’ method can exist in the form of multiple abstract methods that are inherited from superinterfaces. But in that case the inherited methods should logically represent a single method or it might redundantly declare a method that is provided by classes like Object, e.g. toString.

Below examples will help you to understand the concept of functional interfaces clearly.

interface Runnable { void run(); }
// Functional

interface Foo { boolean equals(Object obj); }
// Not functional; equals is already an implicit member

interface Bar extends Foo {int compare(String o1, String o2); }
// Functional; Bar has one abstract non-Object method

interface Comparator {
 boolean equals(Object obj);
 int compare(T o1, T o2);
}
// Functional; Comparator has one abstract non-Object method

interface Foo {int m();   Object clone(); }
// Not functional; method Object.clone is not public

interface X { int m(Iterable arg); }
interface Y { int m(Iterable arg); }
interface Z extends X, Y {}
// Functional: two methods, but they have the same signature


Most of the common callback interfaces are Functional interfaces e.g. RunnableCallable, or Comparator etc. Previously the functional interfaces used to be called as SAM (Single Abstract Method) Types.



Lambda Expressions:

As we have discussed above, the major problem with the Anonymous classes is the Vertical Problem. The Lambda Expressions are nothing but Anonymous classes but their structure is more lightweight and shorter. The Lambda expressions are like methods. They have a list of formal parameters and a body-an expression block-expressed in terms of those parameters.


(String s)-> s.lengh;

() -> 43;

(int x, int y) -> x + y;


In the above examples of Lambda expressions, the first expression takes String variable as an argument and then returns length of the String. Second one doesn’t take any parameter and returns 43. Finally, the third one takes two integers x, and y and returns their addition.

After facing lots of issues, finally, I was able to run my very first Lambda expression example with the help of Java SE 8’s preview edition.

public class FirstLambdaExpression {
    public String variable = "Class Level Variable";

    public static void main(String[] arg) {
        new FirstLambdaExpression().lambdaExpression();
    }

    public void lambdaExpression(){
        String variable = "Method Local Variable";
        String nonFinalVariable = "This is non final variable";

        new Thread (() -> {
            //Below line gives compilation error
            //String variable = "Run Method Variable"

            System.out.println("->" + variable);
            System.out.println("->" + this.variable);
       }).start();
    }
}

The output is:

->Method Local Variable 
->Class Level Variable


Comparing the output of the Anonymous example (seen sometimes back) with the current one, we can clearly say that writing Anonymous classes in the form of lambda expressions solves the issues with the variable visibility and with the behavior of 'this' keyword. Look at the commented line in the program, the lambda expressions are not allowed to create shadowing variables.

The general syntax of Lambda expressions consists of an argument list, the arrow token ‘->’ and finally the body. The body can simply be an expression (single statement) or a block of multiple statements. If the body is an expression then it will be evaluated and returned and if it is a block then it will be evaluated similar to method blocks, and then ‘return’ statement is required to return a result. The break and continue are illegal at the top-level but permitted within the loops.

The particular syntax has been chosen because it is already made common by the languages like C# and Scala. The syntax is basically designed so that it addresses the complexity of Anonymous classes. For the same purpose it is also quite flexible, e.g. if the method body is a single expression then neither the blocks nor the return statement is required. The outcome of the expression is itself treated and returned as a response from that method. This kind of flexibility also helps in keeping the methods short and simple.

The Lambda expressions are used as anonymous classes and hence they can be flexibly used within other blocks or within other lambda expressions (nested lambda expressions).


//Lambda expression is enclosed within methods parameter block.
//Target interface type is the methods parameter type.
String user = doSomething(() -> list.getProperty(“propName”);

//Lambda expression is enclosed within a thread constructor
//target interface type is contructors paramter i.e. Runnable
new Thread (() -> {
    System.out.println("Running in different thread");
}).start();


If you look carefully at lambda expressions, you will see that the target interface type is not a part of the expression. The compiler infers the type of lambda expressions with the help of surrounding context.

The lambda expressions cannot exist without a target type, and they are compatible with every possible target type. Compiler performs a check whether the types used by the lambda expressions are compatible with the method signature of the target type. When a lambda expression is targeting an interface, below are the things that are required to make the compiler ‘happy’:
  • The interface should be a functional interface.
  • The number and the type of parameters should be the same as that of the target interface’s functional method.
  • The return type of the expressions should be compatible with that of the interface’s functional method.
  • The exceptions thrown by expressions should be compatible with the exceptions thrown by the interface’s functional method.
As the compiler is already aware of the Target type and its method parameters, the lambda expressions are allowed to skip the parameter types in the declaration.


Comparator c = (s1, s2) -> s1.compareToIgnoreCase(s2);



Moreover, if the target’s functional method accepts only one parameter (true in most of the cases), then the parenthesis surrounding the parameters becomes optional.


ActionListenr listenr = event -> event.getWhen();



This also answers one very obvious question: Why the Lambda expressions do not require the method name to be specified?

The answer is: lambda expression work only for functional interfaces, and the functional interfaces have only one method. When we target a lambda expression with a particular functional interface, the compiler is already aware of the signature of the functional method and it can easily check for the matching signature in the given expression. On the same lines the methods argument types can also be skipped. It would have been a redundancy, if we had to specify method names, and argument types in the expressions.

This kind of flexible syntax helps in avoiding the Vertical Problem without introducing a Horizontal Problem (lengthy statements).

The Lambda expressions are said to have context-dependent syntax, but these are not the first one to have that. The generic method invocations and the Java SE 7’s newly added diamond operators are also have this concept, where the type is inferred by the surrounding context.

Inferring the target type becomes complex in the case when lambda expressions are method parameter.


void invoke(Runnable r) {r.run()}
void  Future invoke(Callable r) {return c.compute()}
//above are two methods, both takes parameter of type functional interface

Future s = invoke(() ->"Done"); //Which invoke will be called?



The answer of above is the invoke method with a Callable argument. In such cases the compiler decides the target type with the help of overload resolution and type argument inference. When there are more than one applicable overloaded methods, the compiler also checks the compatibility of the lambda expressions with the corresponding target type. In simple words the above call to the invoke method expects a response and there is only one method returning a response.

A Lambda expression can be explicitly casted to a specific target type, provided that, it is compatible with the corresponding target. Have a look at the below program, where I have created three different Callable implementations and passed them as arguments to the 'asList' method. While doing so, I have added a cast for all of the three instances.


public class FirstSightWithLambdaExpressions {
    public static void main(String[] args) {
        List list = Arrays.asList(
            (Callable)()->"callable 1",
            (Callable) ()->"callable 2",
            (Callable) ()->"callable 3");
        ExecutorService e = Executors.newFixedThreadPool(2);
        List futures = null;
        try {
            futures = e.invokeAll(list);
            new FirstSightWithLambdaExpressions().dumpList(futures);
        } catch (InterruptedException | ExecutionException e1) {
            e1.printStackTrace();
        }
        e.shutdown();
    }

    public void dumpList(List list) throws InterruptedException,
              ExecutionException {
        for (Future future : list) {
            System.out.println(future.get());
        }
    }
}

As we have discussed before, the Anonymous classes could never access the non-final variables from the surrounding context. But the Lambda expressions bring a little relaxation in these limitations as they are allowed to access effectively final variables from the surrounding. A variable is effectively final if its initial value is never changed.

As of now, the definition of functional interfaces only applies to the interfaces. I tried creating a lambda expression targeting an abstract class with only one abstract method, but it thrown a compilation error.  As per the JSR-335, the future version of lambda expressions may support the Functional Classes.



Method References:

Method reference is used to refer to a method without invoking it.

The Lambda expressions allow us to define an anonymous method and treat it as an instance of functional interface. Method references allow us to do the same thing, but with the existing methods. Method References are similar to Lambda expressions, that they require a target type, but instead of providing implementation of a method, they refer to a method of an existing class or object.


System::getProperty
"abc"::length
String::length
super::toString
ArrayList::new


The above statements show the general syntax for Method and Constructor References. Here we see a new operator ‘::’ (double colon) has been introduced. I am not yet clear with the exact name for this operator, but the JSR refers it as a Method Reference Delimiter and Wikipedia page refers it as a Scope Resolution Operator. For our reference, within the scope of this tutorial we will simply refer it as a delimiter. 

The target reference (or a receiver) is placed before the delimiter and name of the method is provided after the delimiter. This forms an expression, which is able to refer a method.  In the last statement of the above code, the method name is ‘new'. This expression is referring to the constructor of ArrayList (the constructor references are discussed in the next section). The implicit lambda expression takes LHS of the delimiter as a Target Type and at the RHS side the actual implementation of the referred method or constructor is replaced at runtime.   

Before we go deeper into this, I want to show you the power of method references. I have created a simple sorting program for an array of type Employee.


import java.util.Arrays;
import java.util.List;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.Future;

public class MethodReference {
    public static void main (String[] ar){
        Employee[] employees = {new Employee("Nick"), new Employee("Robin"), new           Employee("Josh"), new Employee("Andy"), new Employee("Mark")};
        System.out.println("Before Sort:");
        dumpEmployee(employees);
        Arrays.sort(employees, Employee::myCompare);
        System.out.println("After Sort:");
        dumpEmployee(employees);
    }

    public static void dumpEmployee(Employee[] employees){
        for(Employee emp : Arrays.asList(employees)){
            System.out.print(emp.name+", ");
        }
        System.out.println();
    }
}

class Employee {
    String name;

    Employee(String name) {
      this.name = name;
    }

    public static int myCompare(Employee emp1, Employee emp2) {
        return emp1.name.compareTo(emp2.name);
    }
}

The output is:

Before Sort: Nick, Robin, Josh, Andy, Mark,  
After Sort: Andy, Josh, Mark, Nick, Robin,

Nothing special happened with the output, but the real crux is happening with the call to ‘Arrays.sort’ method. Employee is a very simple class with a single attribute as ‘name’ (I know my encapsulation is going for a toss, but to keep the code shorter, I take the excuse). The static method ‘myCompare’ takes two employees and returns the comparison of their names.

In the ‘main’ method I have created an Array of different employees and passed it as a first parameter to ‘Arrays.sort’ method. The second parameter to ‘sort’ is the method reference expression (Employee::myCompare). The Employee denotes the Class Type and after the delimiter is the name of the method.

Wait a minute; as per the Java-Doc the sort method takes Comparator as a second parameter, but we are passing a reference to Employee’s static method.  The most important thing to note here, is neither my Employee implements a Comparable nor I have written a separate Comparator class, but still the output is just perfect.

Let's see what happened here. The ‘Arrays.sort’ method expects an instance of Comparator, which is a functional interface that means it has only one method: ‘compare’. Here we can also pass a Lambda expression, which provide an implementation to its functional method. But in our example we already have a comparison method in the Employee class. Though, the name of the method is different, the list of parameters and the return type is the same. Hence, we can create a reference to this method and pass it as a parameter to the ‘sort’.

When there are multiple methods with the same name, the compiler looks at the target type and chooses the best match. To get this clear let's go through an example.

public static int myCompare(Employee emp1, Employee emp2) {
 return emp1.name.compareTo(emp2.name);
}

//Another method with the same name as of the above.
public static int myCompare(Integer int1, Integer int2) {
 return int1.compareTo(int2);
}

I have created two different arrays to be sorted. First is the same Employee array and second is a normal Integer array.

Employee[] employees = {new Employee("Nick"), new Employee("Robin"), 
          new Employee("Josh"), new Employee("Andy"), new Employee("Mark")};
Integer[] ints = {1 , 4, 8, 2, 3, 8, 6};



Now, I am sorting both of the arrays as below.

Arrays.sort(employees, Employee::myCompare);
Arrays.sort(ints, Employee::myCompare);


Here, both of the method reference statements are exactly the same, only the difference is with the arrays we are passing in. Instead of raising an ambiguity flag, the compiler intelligently checks the type of the first argument (Employee or Integer) and as a second parameter expects a method taking two parameters of the first parameter type and then calls the appropriate methods.

Don’t get mislead by the use of static methods. We can create references for instance methods as well. For static methods, we have used Class Name (Employee) before and the method name after the delimiter. In the case of an instance method, the class name will be replaced by an object (Employee Instance) and after the delimiter will be an instance method of that object.

Though, the last example was perfect for our demo context, we have had an overhead of writing a separate method for the Integer comparison. Integer is already a Comparable and provides implementation for the ‘compareTo’ method. Hence, only the below line could have served our purpose.


Arrays.sort(ints, Integer::compareTo);



Did you find something to get confused here?... If not, I will help you.
Here, Integer is name of a class (not an instance like new Integer()) and the ‘compareTo’ method is an instance (non-static) method of Integer. We all know, we cannot call a non-static method without specifying an instance of the class. Then why the above statement is valid?

The answer is: These kinds of statements are allowed for the arbitrary objects of a specific type. Integer is a data type and for data types this kind of expressions are allowed.
If we make the Employee's ‘myCompare’ method non-static and provide expression like Employee::myCompare then compilation will fail with a message: ‘No Suitable Method Found’.


-->

Constructor References:

Constructor Reference is used to refer to a constructor without instantiating the named class.

The newly added, Constructor reference mechanism is yet another game changing addition by Java SE 8. References to constructors can now be created and passed as an argument or assigned to a target type.

In the case of method references, instead of implementing the methods (like the plain lambda expressions), we refer to the existing methods and use them. Similarly, in case of constructor references we can create reference to existing constructors.

In the last section, we have seen the syntax for Constructor reference (ClassName::new), and it is similar to the method references. These constructor reference expressions can be assigned to the targeted functional interfaces.

In the constructor reference expressions, instead of specifying the exact constructor, we just write ‘new’, and a class may have multiple constructors. In that case the compiler checks the type of the functional interface with all of the constructors in the class, and finally chooses the best match.

It was not easy for me to write my first constructor reference program, because, though, I was aware of its syntax, I wasn’t sure about what to do with them and moreover, how to do. Finally, after trying lots of stupid things, there was the 'Eureka..!' time for me. Lets have a look at the below program.

public class ConstructorReference {
    public static void main(String[] ar){
        MyInterface in = MyClass::new;
        System.out.println("->"+in.getMeMyObject());
    }
}

interface MyInterface{
    MyClass getMeMyObject();
}

class MyClass{
    MyClass(){}
}

The output is:

->com.MyClass@34e5307e


-->
Isn’t it seems little strange? The interface and the class have absolutely no connection except that the interface method returns a type of the class.

This example must have sparked another question in your minds (just like it did for me): How to instantiate a class with parameterized constructor? Let’s have a look at the answer in below program.
 
public class ConstructorReference {
    public static void main(String[] ar){
        EmlpoyeeProvider provider = Employee::new;
        Employee emp = provider.getMeEmployee("John", 30);
        System.out.println("->Employee Name: "+emp.name);
        System.out.println("->Employee Age: "+emp.age);
   }
}

interface EmlpoyeeProvider{
    Employee getMeEmployee(String s, Integer i);
}

class Employee{
    String name;
    Integer age;
    Employee (String name, Integer age){
        this.name = name;
        this.age = age;
    }
}

The output is:

->Employee Name: John
->Employee Age: 30

-->
Now, before reaching to the end of this article, lets have a look at the most amazing feature of Java SE 8 and that is Default Methods.

 

Default Methods:

The Java SE 8 is going to introduce a concept of Default Methods. Earlier versions of Java have interfaces with very rigid kind of structures. The interfaces contain Abstract methods and all the non-abstract implementing classes have to provide implementation for those methods, even if the methods are not applicable in the case of any particular Implementing class.
The upcoming version of Java allows Interfaces to have default implementations for its methods. Yes, an interface can have methods with a body attached to it. The implementing classes are not compelled to implement such default methods.

public class DefaultMethods {
 public static void main(String[] ar){
  NormalInterface instance = new NormalInterfaceImpl();
  instance.myNormalMethod();
  instance.myDefaultMethod();
 }
}

interface NormalInterface{
 void myNormalMethod();
 void myDefaultMethod () default{
  System.out.println("-> myDefaultMethod");
 }

}

class NormalInterfaceImpl implements NormalInterface{

 @Override
 public void myNormalMethod() {
  System.out.println("-> myNormalMethod");
 }
}

The output is:

-> myNormalMethod
-> myDefaultMethod

The interface in above example declares two methods, but the implementing class implements only one because the ‘myDefaultMethod’ is marked with ‘default’ modifier and also provides a block of default implementation. Normal overriding rules are applied here, that if a implementing class is providing implementation for the default method then the class’s method would be called.

An interface extending other Interface can Add, Change, or Remove default implementations of the parent’s methods.

interface ParentInterface{
 void initiallyNormal();
 void initiallyDefault () default{
  System.out.println("-> myDefaultMethod");
 }

}
interface ChildInterface extends ParentInterface{
 void initiallyNormal() default{
  System.out.println("now default - > initiallyNormal");
 }
 void initiallyDefault (); //Now a normal method
}
In this example the ParentInterface defines two methods one is normal and other one is a default. The ChildInterface is simply reversing the parent’s method types by changing default method to normal and vice versa.

Let's have a look at the overriding scenarios where the default method behavior is little trickier.

Suppose a class extends a parent C and implements I; and C has a method, which is override-compatible with a default method provided by I. In this case the method in C will be preferred over I’s default method. This holds true even if C’s method is an abstract.

public class DefaultMethods {
 public static void main(String[] ar){
  Interfaxe impl = new NormalInterfaceImpl();
  impl.defaultMethod();
 }
}

class ParentClass{
 public void defaultMethod() {
  System.out.println("->ParentClass");
 }
}

interface Interfaxe{
 public void defaultMethod() default{
  System.out.println("->Interfaxe");
 }
}
class NormalInterfaceImpl extends ParentClass implements Interfaxe{}


The output is:

->ParentClass

In a second case, my class implements two different interfaces and both of them provide default implementation for override-compatible methods. In this case the compiler will shout for ambiguity and the implementing class will have to implement the method and choose between two default implementations. This can be done with the help of ‘super’ keyword as shown below.

public class DefaultMethods {
 public static void main(String[] ar){
  FirstInterface impl = new NormalInterfaceImpl();
  impl.defaultMethod();
 }
}

interface FirstInterface{
 public void defaultMethod() default{
  System.out.println("->FirstInterface");
 }
}

interface SecondInterface{
 public void defaultMethod() default{
  System.out.println("->SecondInterface");
 }
}
class NormalInterfaceImpl implements FirstInterface, SecondInterface{
 public void defaultMethod(){
  SecondInterface.super.defaultMethod();
 }
}


The output is:

->SecondInterface



So guys, we have come to an end of Java Closure Introduction. In this tutorial we have got familiar with the concept of Functional Interfaces and Java Closure; Understood the Java Lambda Expression syntax, the Method Reference and the Constructor Reference. Also, we wrote our First Lambda Expressions Program with other 'Hello World' examples. 

Java SE 8 (Java 1.8) will soon be knocking our doors and I am highly excited to welcome it, because of its really cool features. Though, these features seem to be confusing initially, as the time passes, they will surely become a part of our routine code.

All the best to all of you and please feel free to post your comments.