You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java 8中构造方法引用与调用构造方法的Lambda表达式的区别

Understanding ()->new StringBuilder vs StringBuilder::new in Stream.collect()

Great question! Let's break down these two syntaxes in the context of Java 8's Stream API, especially when using collect().

First, let's recall what the first parameter of collect() does: it's a Supplier<R>—a function that returns a new instance of the container we want to collect elements into (here, StringBuilder). Both ()->new StringBuilder and StringBuilder::new implement this Supplier<StringBuilder> interface, but let's dig into the details:

1. Functional Equivalence (for your use case)

In your specific scenario (using the no-arg StringBuilder constructor), these two syntaxes do exactly the same thing: every time the stream needs a new container (especially critical in parallel streams, where multiple containers are created and merged later), they will invoke the no-arg StringBuilder() constructor to create a fresh instance.

Your code snippet 1 using method references (with a small fix for the print statement):

Stream<String> stream = Stream.of("b", "a", "s", "i", "l");
StringBuilder basil = stream.collect(StringBuilder::new, StringBuilder::append, StringBuilder::append);
System.out.println(basil); // Fixed: original code printed the string "basil" instead of the StringBuilder's content

Is functionally identical to this finished Lambda-based version (your incomplete code snippet 2):

Stream<String> stream = Stream.of("b", "a", "s", "i", "l");
StringBuilder basil = stream.collect(() -> new StringBuilder(), StringBuilder::append, StringBuilder::append);
System.out.println(basil);

2. Syntactic & Semantic Nuances

  • Method references (StringBuilder::new) are a syntax sugar for referencing an existing constructor. The compiler directly resolves this to a reference to the no-arg StringBuilder constructor. It's more concise and reads like "use the StringBuilder constructor".
  • Lambda expressions (()->new StringBuilder) are an anonymous function that explicitly defines the action of creating a new StringBuilder. They're more verbose but make the "new instance" action explicit, which can be easier for beginners to parse.

3. When Would They Differ?

The only time these syntaxes would behave differently is if you were using a constructor with parameters, or if the type inference context changed:

  • For example, if you wanted to use a StringBuilder with an initial capacity, the Lambda would be straightforward: ()->new StringBuilder(100), while a method reference would require wrapping (since there's no direct way to pass arguments to a constructor reference in this Supplier context).
  • In rare cases, type inference might work better with method references, but that's edge-case stuff for complex generic scenarios.

Bottom Line

For your Stream.collect() use case with the no-arg StringBuilder constructor, both syntaxes are interchangeable. Choose whichever feels more readable to you—method references are cleaner for experienced developers, while Lambdas make the instantiation logic explicit for those learning the API.

内容的提问来源于stack exchange,提问作者Basil Battikhi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.20 12:05:31