Stream的Collection()
方法是一个可变的约简。基于Java文档:
可变缩减操作在处理流中的元素时,将输入元素累积到可变结果容器中,例如Collection或StringBuilder。
我尝试了以下方法,它编译没有问题。
Stream<String> stream1 = Stream.of("w", "o", "l", "f");
String word = stream1.collect(String::new, String::concat, String::concat);
System.out.println(word);
如果供应商是StringBuffer,我将收集操作视为元素将附加到提供的StringBuffer。
既然String是一个不可变的对象,那么可变约简在这里是如何工作的?它是否与每次实现累加器时创建新对象的reduce操作相同?
根据Oracle/Java留档:
收集
<R> R collect(Supplier<R> supplier, <R,? super T> accumulator, <R,R> combiner)
对该流的元素执行可变缩减操作。可变约简是这样一种约简,其中约简的值是可变的结果容器,例如ArrayList,元素通过更新结果的状态而不是替换结果来合并。
https://docs.oracle.com/javase/8/docs/api/java/util/stream/Stream.html#collect-java.util.function.Supplier-java.util.function.BiConsumer-java.util.function.BiConsumer-
可变约简
可变约简操作在处理流中的元素时,将输入元素累积到可变结果容器中,例如Collection或StringBuilder。如果我们想获取一个字符串流并将它们连接成一个长字符串,我们可以通过普通约简来实现这一点:
字符串连接=字符串。reduce(“”,字符串::concat)
https://docs.oracle.com/javase/8/docs/api/java/util/stream/package-summary.html#MutableReduction
因此,简而言之,它之所以有效,是因为java在幕后使用stringbuilder
由于String是一个不可变对象,可变缩减在这里是如何工作的?
没有。当您运行时,您将得到一个空字符串(仅供应商
的结果)。如果供应商返回一个不可变对象,编译器无法强制检查,这绝对是它无法做到的。而且由于您的容器是不可变的,因此对它的更新被简单地忽略了。这就像这样做:
String s = "abc";
s.concat("def"); // the result is ignored here
如果你把它写成lambda,可能会更有意义:
Stream<String> stream1 = Stream.of("w", "o", "l", "f");
String word = stream1.collect(
String::new,
(left, right) -> {
left.concat(right); // result is ignored
},
String::concat);
另一方面,当您使用reduce时,您必须返回一些内容:
String word = stream1.reduce(
"",
(x, y) -> {
return x.concat(y);
},
(x, y) -> {
return x.concat(y);
});
当然,您仍然可以:
String word = stream1.reduce(
"",
(x, y) -> {
x.concat(y);
return x; // kind of stupid, but you could
},
(x, y) -> {
return x.concat(y);
});
如果你想打破它;但这不是重点。
Python中的字符串是不可变的,这意味着该值不能更改。我正在测试该场景,但看起来原始字符串已被修改。我只是想理解这个概念
本文向大家介绍为什么字符串对象在Java中是不可变的?,包括了为什么字符串对象在Java中是不可变的?的使用技巧和注意事项,需要的朋友参考一下 通常,字符串用于表示重要细节,例如数据库连接URL,用户名密码等。字符串的不变性有助于使这些细节保持不变。 类似地,在加载类时,将String用作参数。那时,更改字符串可能会导致加载错误的类。 如果不可变,则变量(字符串)自动为线程安全的。
我是java编程的新手。而且我不明白为什么string对象在Java中是不可变的。
问题内容: 我更喜欢编译时错误-为什么不是这种情况?在不提供返回类型的情况下调用相同的问题时,可以将其应用于具有返回类型的任何方法。 可以在不提供引用/变量来保存返回类型的情况下调用: 问题答案: 该对象将立即创建并有资格进行垃圾收集(即,可能很快就会被垃圾收集)。 这不是编译时错误的原因是,并非每个返回方法的方法都需要您使用该返回值。某些方法仅因其副作用而被调用。 一个很好的例子是:它返回一个对
我看到了很多关于使用字符串文字和新关键字创建对象的问题,比如: 使用新运算符的String对象数量 但这并不能澄清我的疑虑。 情况1:使用字符串文字的字符串对象。它在字符串常量池中创建一个对象,如果它不存在,则返回此对象的引用。此对象被隐式驻留。 案例2:使用new()的字符串对象。它创建了两个对象,一个在字符串常量池中,另一个在堆区域中。引用变量引用堆区域对象。对于这个对象,我们需要调用inte