min——返回流中最小值
List<Student> list=Arrays.asList(
new Student("里斯", 12, "男"),
new Student("刘丽", 11, "女"),
new Student("刘星", 22, "女"),
new Student("菜鸡", 42, "女"),
new Student("菜鸡", 42, "女"),
new Student("王五", 75, "男"));
@Test
public void test(){
boolean allMatch = list.stream().allMatch((e)->e.getAge()>20);
System.out.println(allMatch);
boolean anyMatch = list.stream().anyMatch((e)->e.getAge()>20);
System.out.println(anyMatch);
boolean noneMatch = list.stream().noneMatch((e)->e.getAge()>330);
System.out.println(noneMatch);
Optional<Student> findFirst = list.stream().findFirst();
System.out.println(findFirst.get());
Optional<Student> findAny = list.stream().findAny();
System.out.println(findAny.get());
long count = list.stream().count();
System.out.println(count);
System.out.println("================");
Optional<Student> max = list.stream().max((e1,e2)->Integer.compare(e1.getAge(), e2.getAge()));
System.out.println(max.get());
Optional<Integer> min = list.stream().map((e)->e.getAge()).min((e1,e2)->Integer.compare(e1, e2));
System.out.println(min.get());
}
归约
reduce(T identity, BinaryOperator) / reduce(BinaryOperator) ——可以将流中元素反复结合起来,得到一个值。
List<Student> list=Arrays.asList(
new Student("里斯", 12, "男",88.09),
new Student("刘丽", 11, "女",28.09),
new Student("刘星", 22, "女",78.09),
new Student("菜鸡", 42, "女",98.09),
new Student("菜鸡", 42, "女",83.09),
new Student("王五", 75, "男",84.09));
@Test
public void tets01(){
Optional<Integer> reduce = list.stream().map(Student::getAge).reduce((x,y)->x+y);
System.out.println(reduce.get());//204
System.out.println("================");
Integer reduce2 = list.stream().map(Student::getAge).reduce(0,(x,y)->x+y);
//因有起始值所以这段代码返回值为Integer,Optional为避免为null
System.out.println(reduce2);//204
}
收集
collect——将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法
@Test
public void test02(){
Object[] array = list.stream().map(Student::getName).toArray();
for (Object object : array) {
System.out.println(object);
}
System.out.println("================");
List<String> collect = list.stream().map(Student::getName).collect(Collectors.toList());
collect.forEach(System.out::println);//里斯 刘丽 刘星 菜鸡 菜鸡 王五
System.out.println("================");
Set<String> collect2 = list.stream().map(Student::getName).collect(Collectors.toSet());
collect2.forEach(System.out::println);//里斯 刘丽 刘星 菜鸡 王五
}
@Test
public void test03(){
Long collect = list.stream().map(Student::getAge).collect(Collectors.counting());
System.out.println(collect);//6
System.out.println("================");
Optional<Integer> collect2 = list.stream().map(Student::getAge).collect(Collectors.maxBy((x,y)->Integer.compare(x, y)));
System.out.println(collect2.get());//75
System.out.println("================");
Optional<Double> collect3 = list.stream().map(Student::getScore).collect(Collectors.minBy((e1, e2) -> Double.compare(e1, e2)));
System.out.println(collect3.get());//28.09
System.out.println("================");
Double collect4 = list.stream().collect(Collectors.averagingDouble(Student::getAge));
System.out.println(collect4);//34.0
}
@Test
public void test04(){
DoubleSummaryStatistics collect = list.stream().collect(Collectors.summarizingDouble(Student::getScore));
System.out.println(collect.getAverage());//76.59
System.out.println(collect.getMax());//98.09
System.out.println(collect.getMin());//28.09
}
//分组
@Test
public void test05(){
Map<String, List<Student>> collect = list.stream().collect(Collectors.groupingBy(Student::getName));
System.out.println(collect);
//{里斯=[Student [name=里斯, age=12, sex=男, score=88.09]], 菜鸡=[Student [name=菜鸡, age=42, sex=女, score=98.09], Student [name=菜鸡, age=42, sex=女, score=83.09]],
//王五=[Student [name=王五, age=75, sex=男, score=84.09]], 刘星=[Student [name=刘星, age=22, sex=女, score=78.09]], 刘丽=[Student [name=刘丽, age=11, sex=女, score=28.09]]}
}
//分组之后的操作
@Test
public void test06(){
Map<String, Long> collect = list.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.counting()));
System.out.println(collect);//{女=4, 男=2} 是不是这个时候觉得跟sql一样牛逼了
Map<String, Double> collect2 = list.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.averagingInt(Student::getAge)));
System.out.println(collect2);//{女=29.25, 男=43.5}
List<Student> lists=Arrays.asList(
new Student("里斯", 12, "男",88.09),
new Student("刘丽", 22, "女",28.09),
new Student("刘星", 22, "女",78.09),
new Student("菜鸡", 42, "女",98.09),
new Student("菜鸡", 42, "女",83.09),
new Student("王五", 75, "男",84.09));
Map<String, Map<Integer, List<Student>>> collect3 = lists.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy(Student::getAge)));
System.out.println(collect3);
/**
* {女={22=[Student [name=刘丽, age=22, sex=女, score=28.09], Student [name=刘星, age=22, sex=女, score=78.09]],
* 42=[Student [name=菜鸡, age=42, sex=女, score=98.09], Student [name=菜鸡, age=42, sex=女, score=83.09]]},
* 男={75=[Student [name=王五, age=75, sex=男, score=84.09]], 12=[Student [name=里斯, age=12, sex=男, score=88.09]]}}
*/
Map<String, Map<String, List<Student>>> collect5 = lists.stream().collect(Collectors.groupingBy(Student::getSex, Collectors.groupingBy((e)->{
if(e.getScore()>=60){
return "及格";
}else if(e.getScore()<60){
return "不及格";
}else if(e.getScore()>90){
return "优秀";
}else{
return "一般";
}
})));
System.out.println(collect5);
/**
* {
* 女={不及格=[Student [name=刘丽, age=22, sex=女, score=28.09]], 及格=[Student [name=刘星, age=22, sex=女, score=78.09], Student [name=菜鸡, age=42, sex=女, score=98.09], Student [name=菜鸡, age=42, sex=女, score=83.09]]},
* 男={及格=[Student [name=里斯, age=12, sex=男, score=88.09], Student [name=王五, age=75, sex=男, score=84.09]]}
* }
*/
}
//分区
@Test
public void test07(){
Map<Boolean, List<Student>> collect = list.stream().collect(Collectors.partitioningBy((e)->e.getAge()>29));
System.out.println(collect);
/**
* {
* false=[Student [name=里斯, age=12, sex=男, score=88.09], Student [name=刘丽, age=11, sex=女, score=28.09], Student [name=刘星, age=22, sex=女, score=78.09]],
* true=[Student [name=菜鸡, age=42, sex=女, score=98.09], Student [name=菜鸡, age=42, sex=女, score=83.09], Student [name=王五, age=75, sex=男, score=84.09]]
* }
*/
}
@Test
public void test08(){
String collect = list.stream().map(Student::getName).collect(Collectors.joining());
System.out.println(collect);//里斯刘丽刘星菜鸡菜鸡王五
String collect2 = list.stream().map(Student::getName).collect(Collectors.joining(","));
System.out.println(collect2);//里斯,刘丽,刘星,菜鸡,菜鸡,王五
String collect3 = list.stream().map(Student::getName).collect(Collectors.joining(",","<<<<",">>>>"));
System.out.println(collect3);//里斯,刘丽,刘星,菜鸡,菜鸡,王五
}
============stream并行流==============
jdk1.7 有多线程处理框架 Fork join ,可以用于数据的并行操作,缺点:代码比较多,理解较难
Fork join 可以看这篇文章点击打开链接
计算1-10000000000L的累加
新建ForkJoinCalculate
import java.util.concurrent.RecursiveTask;
public class ForkJoinCalculate extends RecursiveTask<Long>{
/**
*
*/
private static final long serialVersionUID = 13475679780L;
private long start;
private long end;
private static final long THRESHOLD = 10000L; //临界值
public ForkJoinCalculate(long start, long end) {
this.start = start;
this.end = end;
}
@Override
protected Long compute() {
long length = end - start;
if(length <= THRESHOLD){
long sum = 0;
for (long i = start; i <= end; i++) {
sum += i;
}
return sum;
}else{
long middle = (start + end) / 2;
ForkJoinCalculate left = new ForkJoinCalculate(start, middle);
left.fork(); //拆分,并将该子任务压入线程队列
ForkJoinCalculate right = new ForkJoinCalculate(middle+1, end);
right.fork();
return left.join() + right.join();
}
}
测试类:
@Test
public void test1(){
long start = System.currentTimeMillis();
ForkJoinPool pool = new ForkJoinPool();
ForkJoinTask<Long> task = new ForkJoinCalculate(0L, 10000000000L);
long sum = pool.invoke(task);
System.out.println(sum);
long end = System.currentTimeMillis();
System.out.println("耗费的时间为: " + (end - start)); //112-1953-1988-2654-2647-20663-113808
}
Stream的并行流: parallel
@Test
public void test3(){
long start = System.currentTimeMillis();
Long sum = LongStream.rangeClosed(0L, 10000000000L)//0-10000000000L的数
.parallel()
.sum();
System.out.println(sum);
long end = System.currentTimeMillis();
System.out.println("耗费的时间为: " + (end - start)); //2061-2053-2086-18926
}
总结:stream的终止操作简直了,有的时候你忘记了sql怎么写,不管是排序还是分组还是分组计数,还是列转行等操作,
java8都能实现,而且有的时候为了考虑sql的效率我们也不可能写很多东东,就像前几天的一个需求,一个对象下的关联基础信息要给进行大于5的判断,只取前5个。。。。limit是吧,可我的sql已经够长了,本身就是多重嵌套,这个对象表相关的东东太多了。。。。那就只可以在代码中了,如果是以前你怎么做?现在呢?当然这个案列也没有很恰当,具体好不好使用了就知道。