JDK8 New Features

Published 2026-07-29 09:24 Updated 2026-07-29 09:24 835 words 5 min read ... Page views

This article introduces the main features of Java 8, including enumerations, basics of variable parameters, as well as interface default and static methods, functional interfaces, Lambda expressions, method references, and Stream stream operations in JDK 8. It focuses on how Lambda expressions simplify the implementation of functional interfaces, as well as common operations of Stream streams in data processing such as mapping, filtering, sorting, deduplication, and statistics.

JDK 8 New Features

Some common syntax has been introduced in Java 5 and is often used together when learning JDK 8 features.

enumeration

Enumeration is a special type used to represent a fixed set of constants. Enumeration constants must be written at the beginning of the enumeration body.

public enum Week {
    MON("星期一"),
    TUE("星期二"),
    WED("星期三"),
    THU("星期四"),
    FRI("星期五"),
    SAT("星期六"),
    SUN("星期日");

    private final String chineseName;

    Week(String chineseName) {
        this.chineseName = chineseName;
    }

    public String getChineseName() {
        return chineseName;
    }
}

Enumeration constants cannot be added or deleted at will after type definition is completed. The properties of enumerated objects are usually designed to be immutable.

variable parameters

Variable parameters allow you to pass in an indefinite number of arguments of the same type when calling a method. A method can have at most one variable parameter, and it must be at the end of the parameter list.

public class Test {
    public static void method(String text, int... numbers) {
        System.out.println(text);
        for (int number : numbers) {
            System.out.println(number);
        }
    }

    public static void main(String[] args) {
        method("abc", 1, 2, 3, 4);
    }
}

Within a method, variable parameters are used as arrays.

Main features of JDK 8

Interface default and static methods

JDK 8 allows interfaces to define default and static methods. The default method is decorated with default and is mainly used to be compatible with existing implementation classes when extending interfaces.

public interface ITest {
    void method();

    default void method1() {
        System.out.println("默认方法");
    }

    static void method2() {
        System.out.println("静态方法");
    }
}

functional interface

An interface that has only one abstract method is called a functional interface. Functional interfaces can contain default methods and static methods because they are not abstract methods.

The @FunctionalInterface annotation is used to verify whether the interface meets the requirements of a functional interface.

@FunctionalInterface
public interface ITest {
    void method();

    default void method1() {
        System.out.println("默认方法");
    }
}

Lambda expressions

Lambda expressions are used to succinctly represent the implementation of functional interface abstraction methods. Their basic structure is:

(参数列表) -> { 方法体 }

For example, an implementation of Runnable can be provided directly when creating a thread:

new Thread(() -> {
    System.out.println("执行 run 方法");
}).start();

Parameter types can usually be inferred by the compiler. When there is only one statement in the method body, the braces can be omitted; if the only statement is a return expression, return can also be omitted.

Arrays.sort(strings, (s1, s2) -> s1.length() - s2.length());

Lambda expressions are written succinctly, but they must appear where functional interface objects are required.

method reference

Method references can be used when an existing method can complete the operations described by a Lambda expression. Common forms are as follows:

类名::静态方法
类名::实例方法
对象::实例方法
类名::new

Whether a method reference can be used depends on whether the abstract method parameters and return values of the target functional interface are compatible with the referenced method. The method names are not required to be the same.

List<String> list = new ArrayList<>();
Collections.addAll(list, "ab", "cd", "ef");

list.forEach(value -> System.out.println(value));
list.forEach(System.out::println);

list.forEach(Test::upperPrintln);
public class Test {
    public static void upperPrintln(String value) {
        String result = String.valueOf(value.charAt(0)).toUpperCase()
                + value.substring(1);
        System.out.println(result);
    }
}

Stream stream

Stream is used to perform operations such as filtering, mapping, sorting, and aggregation on data sequences. It does not store data directly and usually uses a collection or array as the data source.

traverse element

forEach() is a termination operation used to consume elements in the stream.

List<Integer> list = Arrays.asList(3, 2, 2, 3, 7, 3, 5);

list.stream().forEach(System.out::println);
list.parallelStream().forEach(System.out::println);

The output order of parallel streams is not necessarily the same as the original set.

mapping element

map() converts each element to another value and generates a new stream.

list.stream()
        .map(number -> number * 2)
        .forEach(System.out::println);

Filtering and interception

filter() retains elements based on conditions, and limit() limits the number of results. Depending on the order of operations, the results may be different.

list.stream()
        .limit(3)
        .filter(number -> number > 2)
        .forEach(System.out::println);

list.stream()
        .filter(number -> number > 2)
        .limit(3)
        .forEach(System.out::println);

Sort and de-duplication

sorted() is used for sorting and distinct() is used for deduplication removal.

list.stream()
        .sorted()
        .distinct()
        .forEach(System.out::println);

gather result

collect() can collect stream processing results into new collections or strings.

List<Integer> oddNumbers = list.stream()
        .filter(number -> (number & 1) == 1)
        .collect(Collectors.toList());
System.out.println(oddNumbers);

List<String> words = Arrays.asList("a", "b", "c");
String result = words.stream()
        .collect(Collectors.joining("-"));
System.out.println(result);

statistical quantity

count() returns the number of elements in the flow.

long count = list.stream()
        .filter(number -> number > 2)
        .count();
System.out.println(count);

If you enjoyed this, leave a comment~

... Page views
© 2026 跨越星轨的客 @Hoshiumi
Powered by theme astro-koharu · Inspired by Shoka