Java, a programming language created by James Gosling in 1991 was meant to write a program that could run on multiple operating systems. Oracle has now the steermanship for Java and continues the project in the name of OpenJDK. Over the time several new enhanced versions of Java have been released out of which the current one is 1.8 popularly known as Java 8.
- Read this=> How to Install Java 8 on CentOS, Red Hat & Fedora
- Read this=> How to Install Java 8 on Ubuntu & Linuxmint
The language was designed incorporating these properties:
- Platform independent- The Program makes use of the Java virtual machine as abstraction and do not access the operating system on the direct basis. Which makes Java programs highly portable.
- Object-oriented programming- Apart from primitive data types, all elements in Java can be considered as objects.
- Strongly-typed programming language- Yes! Java is a strongly-typed programming language. For example, the types of used variables must be pre-defined and conversion to other objects becomes pretty much strict. This must be done in the case of a programmer.
- Interpreted and compiled language- Java source code requires to be transferred into the bytecode format, one that does not depend on the target platform. The instructions are interpreted by the Java Virtual Machine (JVM). The JVM containing so called Hotspot-compiler has the potential to translate performance critical bytecode instructions into native code instructions.
- Automatic memory management- Java is such a platform that successfully manages memory allocation and de-allocation for creating new objects. The program does not have any direct access to the memory. And as a result, garbage collector automatically deletes objects to which no active pointer exists.
Being a JQuery developer, I have been working a lot with Java 8 over the past few years, be it new applications or migrating existing ones. And I guess it’s the right time to jot down some of the best practices that I have found pretty much useful. This blog post discusses the streams, i.e. the most important operations which can be performed in your code. Default methods, lambdas and streams and using Optional and so on to represent absent values.
Default Methods in Interfaces
The ability to specify default method implementations in interfaces was added by JDK 8 so that collections could evolve without breaking backward compatibility. In the previous versions, we were not able to add any method to interface without all the implementing subclasses. With the help of version 1.8, we can mark a method with the default keyword and provide the body of the method right in the interface.
Down below mentioned is an example of an interface called Debuggable. It is meant to show you that how the reflection API is used to get the access to the object’s fields and provides a decent toString() implementation for the object that prints the fields values.
Lambdas In Streams
Unfortunately, till now Java was considered as an appropriate programming language for functional programming techniques. The only reason was that the functions were not the first class citizens in the language. In fact, there wasn’t any neat and accepted way to refer to a code block by a name and pass it around. As a result, Lambdas brings a drastic change. Today, method references can be used for better or worse, to refer to a specific method, assign the functions into variables, pass them around and enjoy all the perks the functional programming paradigm offers.
The basics are pretty much simple, a bunch of interfaces are created. For example:
The caveat mentioned here is the code used to manage in case if you let anonymous functions grow over a certain threshold. The code specifies the data flow. All you need to do is just plug in the specific functionality especially the one which you want to run into the framework.
In a nutshell
When working with streams, always remember you need to transform the values contained in the stream with the functions you provide for example using the lambda syntax. A few takeaways:
- In case, if the code doesn’t specify the framework for the data flow into which you plug your functions, then it’s worth considering to avoid multiplying lambdas. A proper class might be more readable.
- If your lambda grows above 3 lines of code – split it: either into several map() invocations that process the data in steps or extract a method and use the method reference syntax to refer to it.
- Don’t assign lambdas and functions to the fields of the objects. Lambdas represent functions and those are best served pure.