Java 8 introduced several significant features, including Lambda expressions, the Stream API, and new date/time APIs. Understanding these features can enhance your coding efficiency and improve your applications.
For a detailed overview of Java 8 features, refer to our article: Java 8 Features.
A lambda expression is a concise way to represent an anonymous function that can be passed around as a parameter.
(a, b) -> a + b; // Example of a lambda expression
Lambda expressions can be used to implement functional interfaces, which are interfaces with a single abstract method.
@FunctionalInterface
interface MyFunctionalInterface {
void myMethod();
}
MyFunctionalInterface myFunc = () -> System.out.println("Hello from lambda!");
myFunc.myMethod();
The Stream API allows you to process sequences of elements (like collections) in a functional style.
You can create a stream from a collection using the stream()
method.
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> stream = list.stream();
filter()
method in streams?The filter()
method is used to filter elements based on a predicate.
List<String> filtered = list.stream()
.filter(s -> s.startsWith("a"))
.collect(Collectors.toList());
map()
method in streams?The map()
method is used to transform each element in the stream.
List<Integer> lengths = list.stream()
.map(String::length)
.collect(Collectors.toList());
reduce()
method in streams?The reduce()
method is used to combine elements in the stream into a single result.
Optional<String> concatenated = list.stream()
.reduce((s1, s2) -> s1 + s2);
collect()
method in streams?The collect()
method is used to accumulate the elements of a stream into a collection.
List<String> collected = stream.collect(Collectors.toList());
A functional interface is an interface that contains exactly one abstract method.
Optional
class?The Optional
class is a container object which may or may not contain a value, used to avoid null references.
You can create an Optional using the Optional.of()
, Optional.ofNullable()
, or Optional.empty()
methods.
Optional<String> optional = Optional.of("Hello");
You can check if an Optional has a value using the isPresent()
method.
if (optional.isPresent()) {
System.out.println(optional.get());
}
flatMap()
method in Optional?The flatMap()
method is used to transform the value inside an Optional and return another Optional.
Optional<String> transformed = optional.flatMap(value -> Optional.of(value.toUpperCase()));
ifPresent()
method in Optional?The ifPresent()
method executes a block of code if the Optional contains a value.
optional.ifPresent(value -> System.out.println(value));
orElse()
method in Optional?The orElse()
method returns the value if present, otherwise returns a default value.
String value = optional.orElse("Default");
orElseGet()
method in Optional?The orElseGet()
method returns the value if present, otherwise invokes a supplier to provide a default value.
String value = optional.orElseGet(() -> "Default");
orElseThrow()
method in Optional?The orElseThrow()
method returns the value if present, otherwise throws an exception.
String value = optional.orElseThrow(() -> new IllegalArgumentException("Value not present"));
method reference
in Java 8?A method reference is a shorthand notation of a lambda expression to call a method.
List<String> list = Arrays.asList("a", "b", "c");
list.forEach(System.out::println);
default
method in interfaces?A default method is a method defined in an interface with a body, allowing interfaces to have methods without breaking existing implementations.
interface MyInterface {
default void myDefaultMethod() {
System.out.println("Default method");
}
}
static
method in interfaces?A static method in an interface can be called without an instance of the interface.
interface MyInterface {
static void myStaticMethod() {
System.out.println("Static method");
}
}
MyInterface.myStaticMethod();
Collectors
class?The Collectors
class provides various implementations of the Collector
interface for use with the Stream API.
Collectors.toList()
?You can use Collectors.toList()
to collect the elements of a stream into a List.
List<String> collected = list.stream().collect(Collectors.toList());
Collectors.joining()
?You can use Collectors.joining()
to concatenate the elements of a stream into a single string.
String result = list.stream().collect(Collectors.joining(", ")); // "a, b, c"
Collectors.groupingBy()
?You can use Collectors.groupingBy()
to group elements of a stream by a classifier function.
Map<Integer, List<String>> grouped = list.stream()
.collect(Collectors.groupingBy(String::length));
Collectors.partitioningBy()
?You can use Collectors.partitioningBy()
to partition elements of a stream into two groups based on a predicate.
Map<Boolean, List<String>> partitioned = list.stream()
.collect(Collectors.partitioningBy(s -> s.length() > 1));
java.time
package?The java.time
package provides a comprehensive date and time API introduced in Java 8.
You can create a LocalDate
instance using the LocalDate.now()
method or by specifying a date.
LocalDate date = LocalDate.now(); // Current date
LocalDate specificDate = LocalDate.of(2023, 1, 1); // January 1, 2023
You can create a LocalTime
instance using the LocalTime.now()
method or by specifying a time.
LocalTime time = LocalTime.now(); // Current time
LocalTime specificTime = LocalTime.of(12, 30); // 12:30 PM
You can create a LocalDateTime
instance using the LocalDateTime.now()
method or by combining a date and time.
LocalDateTime dateTime = LocalDateTime.now(); // Current date and time
LocalDateTime specificDateTime = LocalDateTime.of(2023, 1, 1, 12, 30); // January 1, 2023, 12:30 PM
You can format a LocalDate
using the DateTimeFormatter
class.
DateTimeFormatter formatter = DateTimeFormatter.ofPattern("dd-MM-yyyy");
String formattedDate = date.format(formatter);
You can parse a date string into a LocalDate
using the LocalDate.parse()
method.
LocalDate parsedDate = LocalDate.parse("01-01-2023", formatter);
Duration
class?The Duration
class represents a time-based amount of time, such as "34.5 seconds".
You can create a Duration
instance using the Duration.ofSeconds()
method or other similar methods.
Duration duration = Duration.ofSeconds(60); // 60 seconds
Period
class?The Period
class represents a date-based amount of time, such as "3 years, 2 months, and 1 day".
You can create a Period
instance using the Period.of()
method.
Period period = Period.of(1, 2, 3); // 1 year, 2 months, and 3 days
OptionalInt
class?The OptionalInt
class is a specialized version of Optional
for handling int
values.
You can create an OptionalInt
using the OptionalInt.of()
method or OptionalInt.empty()
.
OptionalInt optionalInt = OptionalInt.of(5);
Stream.of()
method?The Stream.of()
method creates a stream from a specified set of values.
Stream<String> stream = Stream.of("a", "b", "c");
You can create a parallel stream using the parallelStream()
method on a collection.
List<String> list = Arrays.asList("a", "b", "c");
Stream<String> parallelStream = list.parallelStream();
Collectors.toMap()
method?The Collectors.toMap()
method collects elements of a stream into a Map.
Map<String, Integer> map = list.stream()
.collect(Collectors.toMap(s -> s, String::length));
Collectors.counting()
method?The Collectors.counting()
method counts the number of elements in a stream.
long count = list.stream().collect(Collectors.counting());
Collectors.summingInt()
method?The Collectors.summingInt()
method calculates the sum of an integer-valued property of the elements in a stream.
int sum = list.stream()
.map(String::length)
.collect(Collectors.summingInt(Integer::intValue));
Collectors.averagingInt()
method?The Collectors.averagingInt()
method calculates the average of an integer-valued property of the elements in a stream.
double average = list.stream()
.map(String::length)
.collect(Collectors.averagingInt(Integer::intValue));
Collectors.joining()
method's advantage?The Collectors.joining()
method provides a convenient way to concatenate strings with a specified delimiter.
Collectors.mapping()
method?The Collectors.mapping()
method applies a mapping function before accumulating the results.
List<String> mapped = list.stream()
.collect(Collectors.mapping(String::toUpperCase, Collectors.toList()));
Collectors.toSet()
method?The Collectors.toSet()
method collects the elements of a stream into a Set.
Set<String> set = list.stream().collect(Collectors.toSet());
Collectors.toCollection()
method?The Collectors.toCollection()
method collects the elements of a stream into a specified collection type.
List<String> collectedList = list.stream()
.collect(Collectors.toCollection(ArrayList::new));
Stream.concat()
method?The Stream.concat()
method concatenates two streams into a single stream.
Stream<String> combined = Stream.concat(stream1, stream2);
Stream.distinct()
method?The Stream.distinct()
method returns a stream consisting of the distinct elements of the original stream.
List<String> distinctList = list.stream().distinct().collect(Collectors.toList());
Stream.sorted()
method?The Stream.sorted()
method returns a stream with the elements sorted in natural order or by a specified comparator.
List<String> sortedList = list.stream().sorted().collect(Collectors.toList());