共计 1756 个字符,预计需要花费 5 分钟才能阅读完成。
根本应用
先举一个简略的例子:
算法题:Words
题目形容
每个句子由多个单词组成,句子中的每个单词的长度都可能不一样,咱们假如每个单词的长度 Ni 为该单词的分量,你须要做的就是给出整个句子的均匀分量 V。
解答要求
工夫限度:1000ms, 内存限度:100MB
输出
输出只有一行,蕴含一个字符串 S(长度不会超过 100),代表整个句子,句子中只蕴含大小写的英文字母,每个单词之间有一个空格。
输入
输入句子 S 的均匀分量 V(四舍五入保留两位小数)。
Who Love Solo
输入样例
3.67
这道题的意思是求一句话中每个单词的均匀长度,咱们求得总长度而后除以单词数量即可,刚好能用到 reduce()这个办法。
public class Demo {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String[] s = sc.nextLine().split(” “);
double res = Arrays.stream(s).mapToDouble(a ->a.length()).reduce(0,(a,b)->a+b);
System.out.println(String.format(“%.2f”,res/s.length));
}
}
在代码中,.reduce(0,(a,b)->a+b); 这一块就是咱们经典的应用案例,咱们要先明确其中 a,b 的含意,而后再学习如何应用
要害概念:初始值的定义(Identity),累加器(Accumulator),组合器(Combiner)
Identity : 定义一个元素代表是归并操作的初始值,如果 Stream 是空的,也是 Stream 的默认后果
Accumulator: 定义一个带两个参数的函数,第一个参数是上个归并函数的返回值,第二个是 Strem 中下一个元素。
Combiner: 调用一个函数来组合归并操作的后果,当归并是并行执行或者当累加器的函数和累加器的实现类型不匹配时才会调用此函数。
也就是说 0 就是咱们的初始值,(a,b)->a+ b 就是咱们的累加器,其中 a 就是上一次的计算结果,b 就是 Stream 流中以后元素,而前面的 a + b 则是计算规定,比方如果咱们改成 a *b,那就是计算乘积了,当然咱们也能够用办法援用来代替 lambda 表达式。
double res = Arrays.stream(s).mapToDouble(a ->a.length()).reduce(0,Double::sum);
1
这就是最根本的应用了,不晓得小伙伴们有没有学会呢?
额定举例
当然,咱们能够用 reduce 办法解决其余类型的 stream,例如,能够操作一个 String 类型的数组,把数组的字符串进行拼接。
List<String> letters = Arrays.asList(“a”, “b”, “c”, “d”, “e”);
String result = letters
.stream()
.reduce(“”, (partialString, element) -> partialString + element);
assertThat(result).isEqualTo(“abcde”);
同样也能够用办法援用来简化代码
String result = letters.stream().reduce(“”, String::concat);
assertThat(result).isEqualTo(“abcde”);
咱们再把下面的拼接字符串的例子改下需要,先把字符串转变成大写而后再拼接
String result = letters
.stream()
.reduce(
“”, (partialString, element) -> partialString.toUpperCase() + element.toUpperCase());
assertThat(result).isEqualTo(“ABCDE”);
另外,咱们能够并行地归并元素(并行归并),如下并行归并一个数字数组来求和
List<Integer> ages = Arrays.asList(25, 30, 45, 28, 32);
int computedAges = ages.parallelStream().reduce(0, a, b -> a + b, Integer::sum);