What New Features Related to Collections Were Introduced in Java 8?

What New Features Related to Collections Were Introduced in Java 8? | Code Examples and Detailed Explanation

Explore the key new features related to Java collections introduced in Java 8, including Lambda expressions, the Streams API, and default methods in interfaces. Learn how these enhancements improve code readability and performance through detailed explanations and code examples.

Introduction to Java 8 Collections Features

Java 8 revolutionized the way we work with collections by introducing powerful new features that greatly enhance the language’s functionality and expressiveness. Some of the most notable updates include the introduction of Lambda Expressions, the Streams API, and default methods in interfaces. These additions make it easier to write cleaner, more concise, and more efficient code.

1. Lambda Expressions and Functional Interfaces

Before Java 8, working with collections required using verbose anonymous classes for actions like sorting, filtering, and transforming data. With the introduction of Lambda Expressions, we can now write more concise and readable code.

A Lambda Expression is a clear and simple way to represent a method using an expression. Lambda expressions enable you to treat functionality as a method argument, or to create a functional interface. It essentially allows you to pass behavior (code) as a parameter.

Lambda Expression Syntax

 (parameter1, parameter2) -> expression 

Example of using Lambda expressions with a collection:


import java.util.*;
import java.util.stream.*;

public class LambdaExample {
    public static void main(String[] args) {
        List names = Arrays.asList("John", "Jane", "Mary", "Robert");

        // Using Lambda to sort the list
        names.sort((name1, name2) -> name1.compareTo(name2));

        names.forEach(name -> System.out.println(name));
    }
}
        

In this example, we use a lambda expression to sort a list of names and print them using the forEach method.

2. Streams API

The Streams API in Java 8 allows us to process data in a functional programming style. It provides a high-level abstraction for performing operations on data collections in a declarative way, without the need to explicitly iterate through the collection.

With Streams, you can perform operations such as filtering, mapping, and reducing on a collection. Streams can be created from various sources, such as collections, arrays, I/O channels, etc.

Creating and Using Streams


import java.util.*;
import java.util.stream.*;

public class StreamExample {
    public static void main(String[] args) {
        List names = Arrays.asList("John", "Jane", "Mary", "Robert");

        // Using Streams to filter and print names starting with 'J'
        names.stream()
             .filter(name -> name.startsWith("J"))
             .forEach(System.out::println);
    }
}
        

This code demonstrates how to use the stream() method to create a stream, filter the list to only include names starting with ‘J’, and print them using the forEach method.

Stream Operations

  • map(): Transforms each element into another form.
  • filter(): Selects elements that match a given condition.
  • collect(): Collects the results of stream operations into a collection.
  • reduce(): Combines elements into a single result (e.g., sum, max).

3. Default Methods in Interfaces

Java 8 introduced the concept of default methods in interfaces. A default method provides a body for a method in an interface. It allows the interface to add new methods without breaking the implementing classes.

This feature makes it easier to evolve the API by adding methods to interfaces without requiring all implementing classes to provide an implementation for the new method.

Default Method Example


interface MyInterface {
    default void printMessage() {
        System.out.println("Hello from the default method!");
    }
}

public class DefaultMethodExample implements MyInterface {
    public static void main(String[] args) {
        DefaultMethodExample obj = new DefaultMethodExample();
        obj.printMessage();  // Uses the default method from the interface
    }
}
        

In this example, the interface MyInterface defines a default method printMessage(), which is implemented without requiring any class to explicitly implement it.

4. New Collection Methods in Java 8

Java 8 also introduced several new utility methods in the Collection and Map interfaces, enhancing the ease of working with collections. Some of these new methods are:

  • forEach: Performs the given action for each element of the collection.
  • removeIf: Removes all elements of the collection that satisfy a given condition.
  • replaceAll: Replaces each element of the collection using a provided function.
  • computeIfAbsent: Computes a value for the key if it’s absent in the map.

Using removeIf and replaceAll


import java.util.*;

public class CollectionMethodsExample {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7);

        // Using removeIf to remove even numbers
        numbers.removeIf(number -> number % 2 == 0);
        System.out.println(numbers);  // Output: [1, 3, 5, 7]

        // Using replaceAll to double the numbers
        numbers.replaceAll(number -> number * 2);
        System.out.println(numbers);  // Output: [2, 6, 10, 14]
    }
}
        

This code snippet demonstrates how to use removeIf to filter out elements and replaceAll to modify elements of a list.

5. Parallel Streams

Java 8 introduced parallel streams, which allow you to perform parallel processing of data in collections. This can significantly improve performance when dealing with large datasets.

Parallel Stream Example


import java.util.*;
import java.util.stream.*;

public class ParallelStreamExample {
    public static void main(String[] args) {
        List numbers = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);

        // Using parallel stream to sum numbers
        int sum = numbers.parallelStream().mapToInt(Integer::intValue).sum();
        System.out.println("Sum: " + sum);  // Output: Sum: 55
    }
}
        

In this example, the parallelStream() method is used to process the numbers in parallel, improving performance on multi-core systems.

Conclusion

Java 8 introduced significant enhancements to the Collections API, making it more powerful, flexible, and easier to use. Features like Lambda expressions, the Streams API, and default methods in interfaces simplify code and reduce boilerplate. These improvements align with functional programming principles, allowing for more expressive and readable code.

© 2025 Tech Interview Guide. All rights reserved.

Please follow and like us:

Leave a Comment