代码拉取完成,页面将自动刷新
package Stream;
import java.util.ArrayList;
import java.util.function.BiFunction;
import java.util.function.BinaryOperator;
import java.util.function.Predicate;
import java.util.stream.Stream;
/**
* Stream类的reduce函数介绍
* 参考链接:https://blog.csdn.net/icarusliu/article/details/79504602
* reduce函数有三种重载形式
*/
public class Reduce {
/**
* 一个参数的reduce()
* Optional<T> Reduce(BinaryOperator<T> accumulator)
* 示例:输出求和与求最大值的结果是否与预期相同
*/
public void one_para() {
Stream<Integer> s = Stream.of(1, 2, 3, 4, 5, 6);
/*
求和,也可以写成lambda语法:Integer sum = s.Reduce((a, b) -> a + b).get();
*/
Integer sum = s.reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer + integer2;
}
}).get();
/*
求最大值,也可以写成lambda语法:Integer max = s.Reduce((a, b) -> a >= b ? a : b).get()
Stream对象不能反复使用,加入build代码,报ArrayList不能转为Integer,看来这个builder是一个一个add的,算了
还是再来一遍赋值,好奇有没有什么办法可以聪明点。
*/
/*
Stream.Builder sb = Stream.builder();
Integer[] array = new Integer[]{1, 2, 3, 4, 5, 6};
List<Integer> o = Arrays.asList(array);
sb.add(o);
s = sb.build();
*/
s = Stream.of(1, 2, 3, 4, 5, 6);
Integer max = s.reduce(new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer >= integer2 ? integer : integer2;
}
}).get();
System.out.println("sum is 21: " + (sum == 21));
System.out.println("max is 6: " + (max == 6));
}
/**
* 两个参数的reduce()
* T Reduce(T identity, BinaryOperator<T> accumulator)
* 示例:输出所有元素连到一起并在最前面添加[value]
*/
public void two_para() {
Stream<String> s = Stream.of("test", "t1", "t2", "te", "aaa", "ta");
/*
结果将是:[value]testt1t2teaaata,也可使用lambda语法:System.out.println(s.Reduce("[value]", (s1, s2) -> s1.concat(s2)))
*/
System.out.println(s.reduce("[value]", new BinaryOperator<String>() {
@Override
public String apply(String s, String s2) {
return s.concat(s2);
}
}));
}
/**
* 三个参数的reduce(),串行流时第三个参数无效
* <U> U Reduce(U identity, BiFunction<U, ? supper T, U> accumulator, BinaryOperator<U> combiner)
* 示例:将一个流中的元素从String变为List<String>,如“ab”变为“[ab]”
*/
public void three_para() {
Stream<String> s = Stream.of("ab", "cd");
/*
结果将是[["ab"],["cd"]],
也可使用lambda语法:System.out.println(s.Reduce(new ArrayList<String>,
(s1, s2) -> new ArrayList<>(s1, s2), (r1, r2) -> r1.addAll(r2))
*/
System.out.println(s.reduce(new ArrayList<ArrayList<String>>(), new BiFunction<ArrayList<ArrayList<String>>, String, ArrayList<ArrayList<String>>>(){
@Override
public ArrayList<ArrayList<String>> apply(ArrayList<ArrayList<String>> r, String s) {
ArrayList<String> h = new ArrayList<String>();
h.add(s);
r.add(h);
return r;
}
}, new BinaryOperator<ArrayList<ArrayList<String>>>() {
@Override
public ArrayList<ArrayList<String>> apply(ArrayList<ArrayList<String>> r, ArrayList<ArrayList<String>> r2) {
r.addAll(r2);
return r;
}
}));
}
/**
* 三个参数的reduce(),并行流使得第三个参数生效
* Stream.parallel()进行流化
* 示例:预期求和结果为10,实际为18,并行似乎有几个并行的就每个并行都会加上identity,最后combine发现identity多次使用导致和串行的结果不同
*/
public void three_para_parallel() {
/**
* lambda语法:
* System.out.println(Stream.of(1,2,3).parallel().
* reduce(4, (s1, s2) -> s1 + s2, (s1, s2) -> s1 + s2))
*/
System.out.println(Stream.of(1,2,3).parallel().reduce(4, new BiFunction<Integer, Integer, Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer + integer2;
}
}, new BinaryOperator<Integer>() {
@Override
public Integer apply(Integer integer, Integer integer2) {
return integer + integer2;
}
}));
}
/**
* 三个参数的reduce()
* 不会出现上面的求和翻倍情况,因为第一个参数为引用类型,每个并行分段用的初始identity是同个引用,最好第一个参数使用线程安全类型,
* 如Collections.synchronizedList(new ArrayList<String>())
*/
public void three_para_ext() {
/**
* 模拟Filter查找其中含有字母a的所有元素,打印结果将是aa ab ad
* lambda语法:
* s1.parallel().reduce(new ArrayList<String>(), (r, t) -> {if (predicate.test(t)) r.add(t); return r;},
* (r1,r2) -> {System.out.println(r1==r2); return r2;}).stream.forEach(System.out::println);
*/
Stream<String> s1 = Stream.of("aa", "ab", "c", "ad");
Predicate<String> predicate = t -> t.contains("a");
s1.parallel().reduce(new ArrayList<String>(), new BiFunction<ArrayList<String>, String, ArrayList<String>>() {
@Override
public ArrayList<String> apply(ArrayList<String> strings, String s) {
if (predicate.test(s)) {
strings.add(s);
}
return strings;
}
}, new BinaryOperator<ArrayList<String>>() {
@Override
public ArrayList<String> apply(ArrayList<String> strings, ArrayList<String> strings2) {
System.out.println(strings == strings2);
return strings;
}
}).stream().forEach(System.out::println);
//下面这块不知道为啥转出不了ad,找到原因了,不能复用前面的predicate,这个变量在前面用过,再在这里使用就会将ad打印成null
//给predicate再赋一遍值也不行,因为reduce里的lambda表达式会报predicate需要是final的,所以这里再定义一个predicate1变量
//不过运行main会发现每次下面的输出都不一样,以后再探究
s1 = Stream.of("aa", "ab", "c", "ad");
Predicate<String> predicate1 = t -> t.contains("a");
s1.parallel().reduce(new ArrayList<String>(), (r, t) -> {if(predicate1.test(t)) r.add(t); return r;},
(r1, r2) -> {System.out.println(r1 == r2); r1.addAll(r2); return r1;}).stream().forEach(System.out::println);
}
public static void main(String... args) {
Reduce reduce = new Reduce();
reduce.one_para();
reduce.two_para();
reduce.three_para();
reduce.three_para_parallel();
reduce.three_para_ext();
}
}
此处可能存在不合适展示的内容,页面不予展示。您可通过相关编辑功能自查并修改。
如您确认内容无涉及 不当用语 / 纯广告导流 / 暴力 / 低俗色情 / 侵权 / 盗版 / 虚假 / 无价值内容或违法国家有关法律法规的内容,可点击提交进行申诉,我们将尽快为您处理。