Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Java

Khác biệt giữa Function và Predicate trong Java 8 Functional Interfaces

Cả Function và Predicate là Functional Interfaces (có đúng 1 abstract method) trong package java.util.function, nền tảng của lập trình hàm trong Java 8+.

Bảng so sánh

Tiêu chíFunctionPredicate
Type parameters2: T (input), R (output)1: T (input)
Abstract methodR apply(T t)boolean test(T t)
Return typeBất kỳ kiểu R nàoChỉ boolean
Mục đíchBiến đổi (transformation): T → RKiểm tra điều kiện (test): T → true/false
Default methods hữu íchandThen, compose, identity()and, or, negate, isEqual()
Primitive specializationsIntFunction, LongFunction, DoubleFunction, ToIntFunction...IntPredicate, LongPredicate, DoublePredicate
Binary variantsBiFunctionBiPredicate

Ví dụ Function: Biến đổi dữ liệu

import java.util.*;
import java.util.function.Function;

public class FunctionDemo {
    public static void main(String[] args) {
        List numbers = Arrays.asList(78, 10, 20, 30, 40);
        
        // Function: Integer -> Integer (chia 2)
        Function half = n -> n / 2;
        
        // Dùng với Stream.map() – intermediate op
        numbers.stream()
               .map(half)                 // áp dụng function
               .forEach(System.out::println); // 39, 5, 10, 15, 20
        
        // Function chaining: andThen (apply f rồi g)
        Function doubleIt = n -> n * 2;
        Function halfThenDouble = half.andThen(doubleIt);
        System.out.println(halfThenDouble.apply(10)); // 10 → 5 → 10
        
        // compose (apply g rồi f)
        Function doubleThenHalf = half.compose(doubleIt);
        System.out.println(doubleThenHalf.apply(10)); // 10 → 20 → 10
    }
}

Ví dụ Predicate: Lọc dữ liệu

import java.util.*;
import java.util.function.Predicate;

public class PredicateDemo {
    public static void main(String[] args) {
        List numbers = Arrays.asList(5, 10, 15, 20, 25, 30);
        
        // Predicate: Integer -> boolean (lớn hơn 10)
        Predicate greaterThan10 = n -> n > 10;
        
        // Dùng với Stream.filter() – intermediate op
        numbers.stream()
               .filter(greaterThan10)
               .forEach(System.out::println); // 15, 20, 25, 30
        
        // Predicate composition: and, or, negate
        Predicate even = n -> n % 2 == 0;
        Predicate greaterThan10AndEven = greaterThan10.and(even);
        Predicate greaterThan10OrEven = greaterThan10.or(even);
        Predicate notGreaterThan10 = greaterThan10.negate();
        
        System.out.println(">10 & even: " + numbers.stream().filter(greaterThan10AndEven).toList()); // [20, 30]
        
        // Static factory: isEqual
        Predicate isHello = Predicate.isEqual("Hello");
        System.out.println(isHello.test("Hello")); // true
        System.out.println(isHello.test("World")); // false
    }
}

Khi nào dùng cái nào?

  • Function: Map/transform: convert DTO→Entity, parse String→Object, calculate, format, enrich data. Dùng với Stream.map(), Collectors.toMap(keyMapper, valueMapper), Optional.map().
  • Predicate: Filter/validate/check: lọc collection, validation, conditional logic, partition. Dùng với Stream.filter(), Collectors.partitioningBy(), Optional.filter(), Collection.removeIf().

Biến thể phổ biến khác

  • Consumer: void accept(T t) – tiêu thụ, không trả về (forEach, logging).
  • Supplier: T get() – cung cấp, không input (lazy init, factory).
  • UnaryOperator: Function – input/output cùng kiểu.
  • BinaryOperator: BiFunction – reduce, combine.