七的博客

Java8函数式接口-Function

Java

Java8函数式接口-Function

Function 接口常用于将一种类型的值转换为另一种类型的值 , 或对输入参数执行某种计算或处理操作。

只要理解到了这种转换关系,下面这些接口应该很容易就可以知道怎么去使用。

1. 通用 Function 接口分类

java.util.function 包下,共计 17 个接口。 按照功能以及参数分类。可以分成下面几个小类,这样可以更好的记忆:

1.1 基础接口

基础接口就是通过泛型实现入参跟出参,可以根据需要固化为具体的类型。

  • Function
  • BiFunction

1.2 基本数据类型的 Function 接口

  • DoubleFunction
  • IntFunction
  • LongFunction

1.3 对象类型转换为基本数据类型

  • ToDoubleFunction
  • ToIntFunction
  • ToLongFunction

1.4 两个对象类型转换为基本数据类型

  • ToDoubleBiFunction
  • ToIntBiFunction
  • ToLongBiFunction

1.5 基本数据类型之间相互转换

  • DoubleToIntFunction
  • DoubleToLongFunction
  • IntToDoubleFunction
  • IntToLongFunction
  • LongToDoubleFunction
  • LongToIntFunction

2. 接口的设计思路

Function 接口的设计思路是提供一个通用的函数抽象,用于表示接收一个参数并产生一个结果的函数。使用泛型的方式,允许指定输入参数和输出结果的类型,可以灵活地应用于各种场景。

BiFunctionFunction 设计思路也是一样的,只不过 BiFunction 是接收两个参数然后产生一个结果的函数。

3. 通用 Function 接口定义

3.1 Function

源码:

@FunctionalInterface
public interface Function<T, R> {

    R apply(T t);

    default <V> Function<V, R> compose(Function<? super V, ? extends T> before) {
        Objects.requireNonNull(before);
        return (V v) -> apply(before.apply(v));
    }

    default <V> Function<T, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t) -> after.apply(apply(t));
    }

    static <T> Function<T, T> identity() {
        return t -> t;
    }
}

作用:接收一个参数并返回一个结果的操作。

使用场景: 将一个对象转换为另一个类型的时候可以使用 。 比如 POJO、DTO 等对象的转换。

final Function<String, Integer> strLength = String::length;
// 结果为 5
final int length = strLength.apply("Hello");

3.2 BiFunction

源码:

@FunctionalInterface
public interface BiFunction<T, U, R> {

    /**
     * Applies this function to the given arguments.
     *
     * @param t the first function argument
     * @param u the second function argument
     * @return the function result
     */
    R apply(T t, U u);

  
    default <V> BiFunction<T, U, V> andThen(Function<? super R, ? extends V> after) {
        Objects.requireNonNull(after);
        return (T t, U u) -> after.apply(apply(t, u));
    }
}

作用: 接收两个参数并返回一个结果的操作。

使用场景:将两个不同类型的对象转换为为另一种类型时使用。

final BiFunction<String, String, String> concat = String::concat;
// 结果为 "Hello World"
final String result = concat.apply("Hello", " World"); 

3.3 DoubleFunction

源码:

@FunctionalInterface
public interface DoubleFunction<R> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    R apply(double value);
}

作用: 接收一个 double 类型参数并返回一个结果。

使用场景: 将一个 double 类型的值转换为为另一种类型时使用。

final DoubleFunction<String> doubleToString = Double::toString;

// 结果为 "3.14"
final String result = doubleToString.apply(3.14); 

3.4 IntFunction

源码:

@FunctionalInterface
public interface IntFunction<R> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    R apply(int value);
}

作用:接收一个 int 类型参数并返回一个结果。

使用场景:将一个 int 类型的值转换为另一种类型时使用。

final IntFunction<String> intToString = Integer::toString;

// 结果为 "42"
final String result = intToString.apply(42); 

3.5 LongFunction

源码:

@FunctionalInterface
public interface LongFunction<R> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    R apply(long value);
}

作用:接收一个 long 类型参数并返回一个结果的操作。

使用场景:将一个 long 类型的值转换为另一种类型时使用。

final LongFunction<String> longToString = Long::toString;

// 结果为 "123"
final String result = longToString.apply(123L); 

3.6 ToDoubleFunction

源码:

@FunctionalInterface
public interface ToDoubleFunction<T> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    double applyAsDouble(T value);
}

作用:接收一个参数并返回一个 double 类型结果的操作。

使用场景:将一个对象转换为 double 类型的值可以使用。

final ToDoubleFunction<String> parseDouble = Double::parseDouble;

// 结果为 3.14
final double result = parseDouble.applyAsDouble("3.14"); 

3.7 ToDoubleBiFunction

源码:

public interface ToDoubleBiFunction<T, U> {

    /**
     * Applies this function to the given arguments.
     *
     * @param t the first function argument
     * @param u the second function argument
     * @return the function result
     */
    double applyAsDouble(T t, U u);
}

作用:接收两个参数并返回一个 double 类型结果的操作。

3.8 ToIntFunction

源码:

@FunctionalInterface
public interface ToIntFunction<T> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    int applyAsInt(T value);
}

使用场景:将一个对象转换为 int 类型的值的时候可以用。

final ToIntFunction<String> parseInt = Integer::parseInt;

// 结果为 42
final int result = parseInt.applyAsInt("42"); 

3.9 ToIntBiFunction

源码:

public interface ToIntBiFunction<T, U> {

    /**
     * Applies this function to the given arguments.
     *
     * @param t the first function argument
     * @param u the second function argument
     * @return the function result
     */
    int applyAsInt(T t, U u);
}

作用:接收两个参数并返回一个 int 类型结果的操作。

3.10 ToLongFunction

源码:

@FunctionalInterface
public interface ToLongFunction<T> {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    long applyAsLong(T value);
}

使用场景:将一个对象转换为 long 类型的值的时候可以用。

final ToLongFunction<String> parseLong = Long::parseLong;

// 结果为 123L
final long result = parseLong.applyAsLong("123"); 

3.11 ToLongBiFunction

源码:

@FunctionalInterface
public interface ToLongBiFunction<T, U> {

    /**
     * Applies this function to the given arguments.
     *
     * @param t the first function argument
     * @param u the second function argument
     * @return the function result
     */
    long applyAsLong(T t, U u);
}

作用:接收两个参数并返回一个 long 类型结果的操作。

3.12 DoubleToIntFunction

源码:

@FunctionalInterface
public interface DoubleToIntFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    int applyAsInt(double value);
}

使用场景: 将 double 类型的值转换为 int 类型的值时可以使用。

final DoubleToIntFunction doubleToInt = x -> (int) x;

// 结果为 3
final int result = doubleToInt.applyAsInt(3.14); 

3.13 DoubleToLongFunction

源码:

@FunctionalInterface
public interface DoubleToLongFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    long applyAsLong(double value);
}

使用场景: 将 double 类型的值转换为 long 类型的值时可以使用。

final DoubleToLongFunction doubleToLong = x -> (long) x;

// 结果为 3L
final long result = doubleToLong.applyAsLong(3.14); 

3.14 IntToDoubleFunction

源码:

@FunctionalInterface
public interface IntToDoubleFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    double applyAsDouble(int value);
}

使用场景: 将一个 int 类型的值转换为 double 类型时可以使用。

final IntToLongFunction intToLong = x -> (long) x;

// 结果为 42L
final long result = intToLong.applyAsLong(42); 

3.15 IntToLongFunction

源码:

@FunctionalInterface
public interface IntToLongFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    long applyAsLong(int value);
}

使用场景: 将一个 int 类型的值转换为 long 类型时可以使用。

final IntToLongFunction intToLong = x -> (long) x;

// 结果为 42L
final long result = intToLong.applyAsLong(42); 

3.16 LongToDoubleFunction

源码:

@FunctionalInterface
public interface LongToDoubleFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    double applyAsDouble(long value);
}

使用场景: 将一个 long 类型的值转换为 double 类型时可以使用。

final LongToDoubleFunction longToDouble = x -> (double) x;

// 结果为 123.0
final double result = longToDouble.applyAsDouble(123L); 

3.17 LongToIntFunction

源码:

@FunctionalInterface
public interface LongToIntFunction {

    /**
     * Applies this function to the given argument.
     *
     * @param value the function argument
     * @return the function result
     */
    int applyAsInt(long value);
}

使用场景: 将一个 long 类型的值转换为 int 类型时可以使用。

final LongToIntFunction longToInt = x -> (int) x;

// 结果为 123
final int result = longToInt.applyAsInt(123L); 

4. JDK 中使用案例

官方的案例中,大部分 Function 接口都是与 Stream API 一起使用,实现集合的流式处理。

4.1 例子 - 字符串列表转换为字符串的长度列表

这里给个使用案例,假设有一个字符串列表,然后需要获取字符串列表的长度。

使用的接口就是 Function,同时限定泛型为

import java.util.Arrays;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

public class FunctionExample {
    public static void main(String[] args) {
       final List<String> names = Arrays.asList("str01", "str", "string2");
        
        // 使用 Function 接口将字符串转换为长度
       final Function<String, Integer> stringLength = String::length;
        
       final List<Integer> lengths = names.stream()
                                     .map(stringLength)
                                     .collect(Collectors.toList());
        
        // 输出: [5, 3, 7]
        System.out.println(lengths); 
    }
}

5. 实际项目运用案例

5.1 基本的 Function 来做数据转换案例

使用 Function 接口将电压值转换为功率值。

// 使用Function接口将电压值转换为功率值
fianl Function<Double, Double> function = voltage -> voltage * voltage / resistance;

final double power = voltageToPower.apply(36.0);

5.2 基本数据类型的 Function 接口转换案例

使用 IntFunction 接口计算变压器的输出电压。


final IntFunction<Integer> function = inputVoltage -> inputVoltage * 10;
final int outputVoltage = function.apply(22);

System.out.println("变压器输入电压为22伏时,输出电压为" + outputVoltage + "伏");

5.3 对象类型转换为基本数据类型案例

使用 ToDoubleFunction 接口将电表读数转换为千瓦时。


final ToDoubleFunction<String> function = function -> Double.parseDouble(reading) / 1000;

final double kWh = function.apply("1500");

System.out.println("电表读数为1500时,相当于" + kWh + "千瓦时");

5.4 两个对象类型转换为基本数据类型的BiFunction接口案例

使用 ToIntBiFunction 来计算电费。


final ToIntBiFunction<Double, Integer> moneyFunction = (kWh, hours) -> (int) (kWh * hours * 0.5);

fianl int money = moneyFunction.applyAsInt(2.5, 100);

System.out.println("在100小时内消耗2.5千瓦时的电力,电费为" + money + "元");

5.5 基本数据类型之间转换的Function接口案例

用 IntToDoubleFunction 接口将电量等级转换为实际电量值。


fianl IntToDoubleFunction function = level -> level * 95.5;

double energy = function.applyAsDouble(3);

System.out.println("电量等级为3时,实际电量值为" + energy);