Core Java

What Is Stream Pipelining in Java 8?

Stream pipelining is the concept of chaining operations together. This is done by splitting the operations that can happen on a stream into two categories: intermediate operations and terminal operations.

Each intermediate operation returns an instance of Stream itself when it runs, an arbitrary number of intermediate operations can, therefore, be set up to process data forming a processing pipeline.

There must then be a terminal operation which returns a final value and terminates the pipeline.

What are the built-in functional interfaces in Java?

Some of the famous pre-defined functional interfaces from previous Java version (< 8) are Runnable, Callable, Comparator, and Comparable.

Runnable: used to execute the instances of a class over another thread with no arguments and no return value. Callable: used to execute the instances of a class over another thread with no arguments and it either returns a value or throws an exception. Comparator: used to sort different objects in a user-defined order Comparable: used to sort objects in the natural sort order

While Java 8 introduces functional interfaces like:

What is the difference between Intermediate and terminal operations on Stream APIs?

Intermediate operations returns the stream in response, but it will not executed until terminal operations mentioned at the end. So for example, filter and map operations will not executed until you add terminal operation at the end like collect, foreach, reduce etc.

What is the stateful intermediate operation? Give some examples of stateful intermediate operations.

To complete some of the intermediate operations, some state is to be maintained, and such intermediate operations are called stateful intermediate operations. Parallel execution of these types of operations is complex. For example: sorted() , distinct() , limit() , skip() etc. Sending data elements to further steps in the pipeline stops till all the data is sorted for sorted() and stream data elements are stored in temporary data structures.

Functionality of parallel stream in Java?

Please check tutorial on Parallelism in Java.

Difference between Parallel Stream and CompletableFuture?

Please check the tutorial on Difference between Parallel Stream and CompletableFuture.

Can we use String in the Switch Case in Java?

Yes

What Is the Difference Between Map and flatMap Stream Operation?

There is a difference in signature between map and flatMap. Generally speaking, a map operation wraps its return value inside its ordinal type while flatMap does not.

For example, in Optional, a map operation would return Optional type while flatMap would return String type.

So after mapping, one needs to unwrap (read “flatten”) the object to retrieve the value whereas, after flat mapping, there is no such need as the object is already flattened. The same concept is applied to mapping and flat mapping in Stream.

Both map and flatMap are intermediate stream operations that receive a function and apply this function to all elements of a stream.

The difference is that for the map, this function returns a value, but for flatMap, this function returns a stream. The flatMap operation “flattens” the streams into one.

Here’s an example where we take a map of users’ names and lists of phones and “flatten” it down to a list of phones of all the users using flatMap:

Map<String, List> people = new HashMap<>();
people.put("John", Arrays.asList("555-1123", "555-3389"));
people.put("Mary", Arrays.asList("555-2243", "555-5264"));
people.put("Steve", Arrays.asList("555-6654", "555-3242"));
 
List phones = people.values().stream()
  .flatMap(Collection::stream)
    .collect(Collectors.toList());

What Is a stream? How does it Differ from a Collection?

In simple terms, a stream is an iterator whose role is to accept a set of actions to apply on each of the elements it contains.

The stream represents a sequence of objects from a source such as a collection, which supports aggregate operations. They were designed to make collection processing simple and concise. Contrary to the collections, the logic of iteration is implemented inside the stream, so we can use methods like map and flatMap for performing a declarative processing.

Another difference is that the Stream API is fluent and allows pipelining:

int sum = Arrays.stream(new int[]{1, 2, 3})
  .filter(i -> i >= 2)
  .map(i -> i * 3)
  .sum();

And yet another important distinction from collections is that streams are inherently lazily loaded and processed.

Is it possible to execute Java main file using single command?

Yes. Since Java version 11, java command line tool has been able to run a single-file source-code directly. e.g.

java Hello.java

where Hello is the Java file name and has the main method.

Why PermGen space was removed from Java 8?

Static methods and variables were Stored in the PermGen space prior to Java version 8. But now in Java 8, a new memory space was introduced, called MetaSpace, where all fields of the class, methods of a class with the bytecode of the methods, constant pool, JIT optimizations etc are stored.

The main reason for removing PermGen in Java 8 is:

  • It is very hard to predict the required size of PermGen
  • It helps in improving Garbage Collection Performance by reclaiming the JVM memory

Tell me few best practices you apply while using Collections in Java?

Here are couple of best practices we should follow while using Collection classes from Java:

a) Always use the right collection e.g. if you need non-synchronized list then use ArrayList and not Vector.
b) Prefer concurrent collection over synchronized collection because they are more scalable.
c) Always use interface to a represent and access a collection e.g. use List to store ArrayList, Map to store HashMap and so on.
d) Use iterator to loop over collection.
e) Always use generics with collection.
f) Prefer isEmpty() over size().
g) Do not return null in a method that returns a collection.
h) Overriding equals() and hashCode() properly.
i) Using the Stream API on collections.
j) Using bounded wildcards to increase API flexibility.
k) Using third-party collections libraries like Fastutil, Guava, Eclipse Collections and JCTools.

What is Optional.get()?

Java 8 was a huge improvement to the platform and one of the new features was added Optional.get(). So using this feature you are telling that value may or may not be available in the variable used by Optional. So if value is not present then it will throw NullPointerException. To avoid such NullPointerException you can check whether value is present or not using isPresent() method.

For example,

Optional<String> name = Optional.of("Soumitra");
if (name.isPresent()) {
	System.out.println(name.get());
} else {
	System.out.println("value not present");
}

So when you run, you will get output: Soumitra.

Now change the code as follows:

name = Optional.empty();
if (name.isPresent()) {
	System.out.println(name.get());
} else {
	System.out.println("value not present");
}

Your output should be as value not present.

But when you change the value as empty and try to get value then you will get exception:

name = Optional.empty();
System.out.println(name.get());

You will get exception as java.util.NoSuchElementException: No value present.

You can also use Optional.orElse() method to provide other than default present value.

You can find an example on Optional.get() – Spring REST Optional Path variable

What is Refcursor in Java?

Support for REF CURSOR was added in Java 8/JDBC 4.2. Use the type Types.REF_CURSOR for cursor return types. They can be iterated through the ResultSet interface.

For example:

CallableStatement cstmt = conn.prepareCall("{callStoredProc(?)}");
cstmt.registerOutParameter(1, Types.REF_CURSOR);
cstmt.executeQuery();
ResultSet cursor = cstmt.getObject(1, ResultSet.class);
while(cursor.next()) {
    System.out.println("Name = " + cursor.getString(1));
}

String vs StringBuffer vs StringBuilder ?

String

It is an immutable object, i.e., once created cannot be changed.
String is a thread safe object as it is an immutable object, i.e., multiple threads cannot access String object simultaneously.
The String object is stored in constant pool area of the String.
Once assigned a value to String object cannot be changed

String s = "Hello, World!"; // The object s is stored in constant pool and its value can not be modified.
s = "Welcome to Hello World!" //new "Welcome to Hello World!" String object is created in constant pool and referenced by the s variable

“Hello, World!” still exists in constant pool area of the String but we lost the reference.

StringBuffer

It is a mutable object, i.e., we can change its value.
The object created through StringBuffer is stored in heap.
It provides synchronized methods and it provides thread safety; so multiple threads can access StringBuffer object simultaneously, though only one thread is allowed to access at a time.
As all methods in StringBuffer are synchronized, so it has drawback on performance and slower than StringBuilder and String object.
The object created through StringBuffer can be changed to String object using toString() method.

StringBuffer stringBuffer = new StringBuffer("Hello, World!");

StringBuilder

It is a mutable object, i.e., we can change its value.
The object created through StringBuilder is stored in heap.
It does not provide any synchronized method, that means it does not provide thread safety; so multiple threads cannot access StringBuilder object simultaneously.
No method in StringBuilder is synchronized, so it is faster that StringBuffer.
The object created through StringBuilder can be changed to String object using toString() method.

StringBuilder stringBuilder = new StringBuilder("Hello, World!");

An example:

package com.roytuts.java.string;
public class StringStringBufferStringBuilder {
	public static void main(String[] args) {
		String s = "Hello, World!";
		System.out.println(s);
		s = "Welcome to Hello World!";
		System.out.println(s); // we lost reference to "Hello, World!"
		System.out.println();
		StringBuffer stringBuffer = new StringBuffer("Hello, World!");
		System.out.println(stringBuffer);
		System.out.println(stringBuffer.toString()); // convert to String object
		stringBuffer = new StringBuffer("Welcome to Hello World!");
		System.out.println(stringBuffer);
		System.out.println();
		StringBuilder stringBuilder = new StringBuilder("Hello, World!");
		System.out.println(stringBuilder);
		System.out.println(stringBuilder.toString()); // convert to String
														// object
		stringBuilder = new StringBuilder("Welcome to Hello World!");
		System.out.println(stringBuilder);
	}
}

Output:

Hello, World!
Welcome to Hello World!
Hello, World!
Hello, World!
Welcome to Hello World!
Hello, World!
Hello, World!
Welcome to Hello World!

What is best way to store password in String variable or in a char[]? Why?

It is always better to store password in char[] (character array). The following explanation will clear your doubts why you need to store in char array.

Strings are immutable in Java and if a password is stored in string as a plain text then it will be available in memory until Garbage collection clears it. Being string immutable, the content of it will not be changed because any change to the existing string will introduce new string. Literal strings are stored in string pool and there is a high chance that the password will remain for long duration and it’s a security concern.

With an array data can be removed easily or overwritten once task is completed. So the password will not be available in the memory even if Garbage collection does run or not.

Storing password in string as a plain text would be visible clearly to anyone who has an access to memory dump. That’s why passwords are stored in encrypted format.

While logging, there could a possibility to log the plain text password but with char array the password would not be in a readable format.

What are the differences between Heap and Stack Memory in Java?

The major difference between Heap and Stack memory are:

Features

Stack memory is used only by one thread of execution. Heap memory is used by all the parts of the application.

Access

Stack memory can’t be accessed by other threads. Objects stored in the heap are globally accessible.

Memory Management

Stack follows LIFO manner to free memory. Memory management is based on the generation associated with each object.

Lifetime

Stack memory exists until the end of execution of the thread. Heap memory lives from the start till the end of application execution.

Usage

Stack memory only contains local primitive and reference variables to objects in heap space. Whenever an object is created, it’s always stored in the Heap space.

ClassNotFoundException vs NoClassDefinitionFoundException ?

ClassNotFoundException

Thrown when an application tries to load in a class through its string name using:

The forName method in class Class.
The findSystemClass method in class ClassLoader .
The loadClass method in class ClassLoader.

but no definition for the class with the specified name could be found.

For ClassNotFoundException, it appears that it may stem from trying to make reflective calls to classes at runtime, but classes the program is trying to call do not exist.

ClassNotFoundException is an Exception, so it is somewhat expected, and is something that is recoverable.

Example:

package com.roytuts.classexception;
public class ClassNotFoundExceptionTest {
	public static void main(String[] args) {
		try {
			Class.forName("ClassA"); //No definition for ClassA exists
		} catch (ClassNotFoundException e) {
			e.printStackTrace();
		}
	}
}
Output
java.lang.ClassNotFoundException: ClassA
	at java.net.URLClassLoader.findClass(URLClassLoader.java:381)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:424)
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:331)
	at java.lang.ClassLoader.loadClass(ClassLoader.java:357)
	at java.lang.Class.forName0(Native Method)
	at java.lang.Class.forName(Class.java:264)
	at com.roytuts.classexception.ClassNotFoundExceptionTest.main(ClassNotFoundExceptionTest.java:7)

NoClassDefinitionFoundException 

Thrown if the Java Virtual Machine or a ClassLoader instance tries to load in the definition of a class (as part of a normal method call or as part of creating a new instance using the new expression) and no definition of the class could be found.

The searched-for class definition exist when the currently executing class was compiled, but the definition can no longer be found.

So, it appears that the NoClassDefFoundError occurs when the source was successfully compiled, but at runtime, the required class files were not found. This may be something that can happen in the distribution or production of JAR files, where not all the required class files were included.

NoClassDefFoundError is an Error and it arises from the Java Virtual Machine having problems finding a class it expected to find.

Example:

package com.roytuts.classexception;
import javax.jms.ConnectionFactory;
import org.apache.activemq.ActiveMQConnection;
import org.apache.activemq.ActiveMQConnectionFactory;
public class NoClassDefinitionFoundExceptionTest {
	public static void main(String[] args) {
		ConnectionFactory connectionFactory = new ActiveMQConnectionFactory(
				ActiveMQConnection.DEFAULT_BROKER_URL);
	}
}
Output:
Exception in thread "main" java.lang.Error: Unresolved compilation problems:
	ConnectionFactory cannot be resolved to a type
	ActiveMQConnectionFactory cannot be resolved to a type
	ActiveMQConnection cannot be resolved to a variable
	at com.roytuts.classexception.NoClassDefinitionFoundExceptionTest.main(NoClassDefinitionFoundExceptionTest.java:11)

What are different class loaders ?

Please go through http://www.oracle.com/technetwork/articles/javase/classloaders-140370.html