0Pricing
Java Academy · 课时

Supplier 与 Consumer

生成并消费值

Supplier 与 Consumer 是 CoddyKit 上的免费 Java Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Java Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Java Academy 课程共包含 4 节课。

Supplier 的作用

Supplier<T> 不接受任何参数,并生成 T 类型的值。

  • 它的方法是 T get()。
  • 非常适合延迟或推迟创建值。
import java.util.function.Supplier;

public class Main {
    public static void main(String[] args) {
        Supplier<String> greeting = () -> "Hello!";
        System.out.println(greeting.get());
    }
}

Supplier 具有惰性

Supplier 中的代码只有在调用 get 时才会运行。因此,Supplier 非常适合用于可能永远不需要计算的高成本默认值。

import java.util.function.Supplier;

public class Main {
    public static void main(String[] args) {
        Supplier<Integer> expensive = () -> {
            System.out.println("computing...");
            return 42;
        };
        System.out.println("before get");
        System.out.println(expensive.get());
    }
}

使用 Supplier 提供默认值

许多接口会接受一个 Supplier,以便仅在需要时计算值,例如 Optional.orElseGet。

import java.util.Optional;

public class Main {
    public static void main(String[] args) {
        Optional<String> name = Optional.empty();
        System.out.println(name.orElseGet(() -> "default"));
    }
}

Consumer 的作用

Consumer<T> 接受一个值,但不返回任何值(无返回值)。

  • 它的方法是 void accept(T t)。
  • 它用于打印或记录日志等副作用操作。
import java.util.function.Consumer;

public class Main {
    public static void main(String[] args) {
        Consumer<String> printer = s -> System.out.println("Got: " + s);
        printer.accept("data");
    }
}

使用 forEach 的 Consumer

最常见的 Consumer 使用场景是 Iterable.forEach 和 Stream.forEach。

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<String> items = List.of("a", "b", "c");
        items.forEach(item -> System.out.println(item));
    }
}

使用 andThen 链接 Consumer

Consumer 支持 andThen,可以依次对同一个输入运行两个消费者。

import java.util.function.Consumer;

public class Main {
    public static void main(String[] args) {
        Consumer<String> first = s -> System.out.println("upper: " + s.toUpperCase());
        Consumer<String> second = s -> System.out.println("len: " + s.length());
        first.andThen(second).accept("hello");
    }
}

处理两个输入的 BiConsumer

BiConsumer<T, U> 接受两个参数但不返回任何值。Map.forEach 使用它来遍历键值对。

import java.util.Map;

public class Main {
    public static void main(String[] args) {
        Map<String, Integer> ages = Map.of("Ann", 30, "Bob", 25);
        ages.forEach((name, age) -> System.out.println(name + "=" + age));
    }
}

作为 Consumer 的方法引用

像 System.out::println 这样的方法引用就是简洁的 Consumer。

import java.util.List;

public class Main {
    public static void main(String[] args) {
        List<Integer> nums = List.of(1, 2, 3);
        nums.forEach(System.out::println);
    }
}

组合 Supplier 和 Consumer

Supplier 可以将其生成的值直接传给 Consumer,形成简单的先生成后消费流程。

import java.util.function.Supplier;
import java.util.function.Consumer;

public class Main {
    public static void main(String[] args) {
        Supplier<String> source = () -> "payload";
        Consumer<String> sink = s -> System.out.println("received " + s);
        sink.accept(source.get());
    }
}

返回对象的供应者

当不需要参数时,构造方法可以通过 ClassName::new 自然地充当供应者。

import java.util.ArrayList;
import java.util.List;
import java.util.function.Supplier;

public class Main {
    public static void main(String[] args) {
        Supplier<List<String>> factory = ArrayList::new;
        List<String> list = factory.get();
        list.add("x");
        System.out.println(list);
    }
}

副作用与纯函数

请记住它们的区别:

  • Supplier:没有输入,但会产生输出。
  • Consumer:接收输入,但不产生输出(会产生副作用)。
  • Function:接收输入并返回输出。
import java.util.function.Supplier;
import java.util.function.Consumer;

public class Main {
    public static void main(String[] args) {
        Supplier<Integer> dice = () -> 4;
        Consumer<Integer> show = n -> System.out.println("rolled " + n);
        show.accept(dice.get());
    }
}

快速检查

哪种函数式接口不接收参数但会返回值?

回顾

您已经用函数式方式生成和消费值:

  • Supplier<T> 使用 get() 进行延迟生成。
  • Consumer<T> 使用 accept() 产生副作用,并通过 andThen 进行链接。
  • BiConsumer<T,U> 处理两个输入,例如用于 Map.forEach。
  • 方法引用和构造方法引用可以让这两种写法都更加简洁。

常见问题解答

「Supplier 与 Consumer」课时是免费的吗?

是的 — 「Supplier 与 Consumer」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Java Academy 课程的其余内容,请升级到 CoddyKit PRO。 Java Academy 课程共包含 4 节课。

「Supplier 与 Consumer」这节课中我会学到什么?

生成并消费值 你通过在浏览器中直接运行的动手代码来练习 Java Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Java Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Java Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「Supplier 与 Consumer」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Java Academy 课中编写并运行代码吗?

能。每节 Java Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. Function 与 BiFunction
  2. Supplier 与 Consumer
  3. Predicate 与组合
  4. 自定义函数式接口
← 返回 Java Academy