Q 1. What are the main features introduced in Java 8?

   - Lambda Expressions

   - Functional Interfaces

   - Stream API

   - Default Methods in Interfaces

   - Method References

   - New Date and Time API (java.time package)


Q 2. What are Lambda Expressions?

   Lambda expressions are a concise way to represent a method implementation, essentially treating code as data. They enable the use of functional programming concepts in Java.


Q 3. What is a Functional Interface?

 Here are the key points to understand about functional interfaces in Java 8:

1. Single Abstract Method (SAM): A functional interface has only one abstract method. However, it can have multiple default or static methods.

2. Lambda Expressions: Functional interfaces are designed to work seamlessly with lambda expressions. 

3. Method References: Method references allow you to reference methods or constructors of functional interfaces, making your code more concise and readable.

4. @FunctionalInterface Annotation: While not required, you can annotate your custom functional interfaces with `@FunctionalInterface` to indicate that they are intended to be used as functional interfaces. The compiler will enforce the single abstract method rule, and if you accidentally violate it, you'll get a compilation error.

Here's an example of a simple functional interface and its usage:


@FunctionalInterface

interface MyFunctionalInterface {

    void doSomething(); // Abstract method

}


public class Main {

    public static void main(String[] args) {

        // Using a lambda expression to implement the abstract method

        MyFunctionalInterface functionalInterface = () -> {

            System.out.println("Doing something...");

        };

        

        // Calling the abstract method through the functional interface

        functionalInterface.doSomething();

    }

}

Q 4. What is the Stream API?

   The Stream API provides a way to process collections of data in a functional-style, allowing operations like filtering, mapping, and reducing on data sets.


Q 5. How do you create a Stream in Java 8?

   Streams can be created from various sources such as collections, arrays, or by using `Stream.of()` and `Stream.generate()` methods.


Q 6. What are Method References?

   Method references allow you to refer to methods by their names without invoking them. They are shorthand notation for a lambda expression targeting a specific method.


Q 7. Explain Default Methods in Interfaces.

   Default methods are methods with an implementation in an interface. They were introduced to support backward compatibility when new methods are added to interfaces. Existing implementing classes don't need to implement these default methods.


Q 8. How does the New Date and Time API differ from the old Date and Calendar classes?

   The new Date and Time API (java.time package) provides a more reliable and comprehensive way to handle date and time. It's immutable, thread-safe, and addresses many of the shortcomings of the old Date and Calendar classes.


Q 9. What is the `forEach` method in Java 8 Streams used for?

   The `forEach` method is used to iterate through the elements of a stream and perform a specified action on each element.


Q 10. How does Java 8 handle the "NullPointerException" in its Stream operations?

    Java 8 introduces the `Optional` class which helps avoid null pointer exceptions. Stream operations like `map`, `filter`, and `flatMap` return `Optional` values, which can be processed safely.


Q 11. What is the purpose of the `Supplier` interface?

    The `Supplier` interface represents a supplier of results, and it doesn't take any arguments. It is often used when lazy evaluation is required.


Q 12. How can you convert a `List` to a comma-separated string using Java 8?

    You can use the `Collectors.joining()` method along with streams to achieve this:


    String result = myList.stream()

                          .map(Object::toString)

                          .collect(Collectors.joining(", "));