优点:代码简洁 ,并行简单
介绍
继承关系
Stream 的继承关系
* @param <T> the type of the stream elements
* @since 1.8
* @see IntStream
* @see LongStream
* @see DoubleStream
* @see <a href="package-summary.html">java.util.stream</a>
*/
public interface Stream<T> extends BaseStream<T, Stream<T>> {
一个父类以及四个子类 方法很相似,为什么不把 IntStream 等设计成 Stream 的子接口?,因为Java不允许只有返回类型不同的方法重载。
特点
为函数式编程而生 。对 stream 的任何修改都不会修改背后的数据源,比如对 stream 执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新 stream 。
惰式执行 。 stream 上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
可消费性 。 stream 只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成。
对 stream 的操作分为为两类, 中间操作( intermediate operations )和结束操作( terminal operations ) ,二者特点是:
中间操作总是会惰式执行 ,调用中间操作只会生成一个标记了该操作的新 stream ,仅此而已。
结束操作会触发实际计算 ,计算发生时会把所有中间操作积攒的操作以 pipeline 的方式执行,这样可以减少迭代次数。计算完成之后 stream 就会失效。
| Stream操作分类 | ||
| 中间操作(Intermediate operations) | 无状态(Stateless) | unordered() filter() map() mapToInt() mapToLong() mapToDouble() flatMap() flatMapToInt() flatMapToLong() flatMapToDouble() peek() |
| 有状态(Stateful) | distinct() sorted() sorted() limit() skip() | |
| 结束操作(Terminal operations) | 非短路操作 | forEach() forEachOrdered() toArray() reduce() collect() max() min() count() |
| 短路操作(short-circuiting) | anyMatch() allMatch() noneMatch() findFirst() findAny() | |
Stream上的所有操作分为两类:中间操作和结束操作,中间操作只是一种标记,只有结束操作才会触发实际计算。中间操作又可以分为无状态的(Stateless)和有状态的(Stateful),无状态中间操作是指元素的处理不受前面元素的影响,而有状态的中间操作必须等到所有元素处理之后才知道最终结果,比如排序是有状态操作,在读取所有元素之前并不能确定排序结果;结束操作又可以分为短路操作和非短路操作,短路操作是指不用处理全部元素就可以返回结果,比如找到第一个满足条件的元素。之所以要进行如此精细的划分,是因为底层对每一种情况的处理方式不同。
使用:
package com.chenkang.tenant;
import com.chenkang.tenant.entity.SysUser;
import lombok.extern.slf4j.Slf4j;
import org.junit.jupiter.api.Test;
import org.springframework.boot.test.context.SpringBootTest;
import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;
import java.util.Optional;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.DoubleStream;
import java.util.stream.Stream;
@Slf4j
@SpringBootTest
class TenantApplicationTests {
private static List<SysUser> userList;
static {
userList= new ArrayList<>();
userList.add(new SysUser(1,"张三",12,1));
userList.add(new SysUser(2,"李四",9,2));
userList.add(new SysUser(3,"王五",30,1));
userList.add(new SysUser(4,"赵六",9,4));
}
/**
* 过滤返回的是布尔类型
*/
@Test
void filter(){
List<SysUser> collect = userList.stream().filter(sysUser -> sysUser.getTentId() == 1).collect(Collectors.toList());
log.info("userList:{}",collect);
}
/**
* 去重 对象去重需要重写 equals
*/
@Test
void distinct(){
List<SysUser> collect = userList.stream().distinct().collect(Collectors.toList());
log.info("userList:{}",collect);
}
/**
* 可能返回任意一个元素
*/
@Test
void findAny(){
Optional<SysUser> any = userList.stream().findAny();
log.info("user:{}",any.isPresent()?any.get():"no value");
}
/**
* 返回第一个元素
*/
@Test
void findFirst(){
Optional<SysUser> any = userList.stream().findFirst();
log.info("user:{}",any.isPresent()?any.get():"no value");
}
/**
* 可以返回数量
*/
@Test
void count(){
long count = userList.stream().count();
log.info("user:{}",count);
}
/**
* 最大值
*/
@Test
void max(){
Optional<SysUser> max = userList.stream().max(Comparator.comparing(SysUser::getUserAge));
log.info("user:{}",max.isPresent()?max.get():"no value");
}
/**
* 最小值
*/
@Test
void min(){
Optional<SysUser> min = userList.stream().min(Comparator.comparing(SysUser::getUserAge));
log.info("user:{}",min.isPresent()?min.get():"no value");
}
/**
* 排序
*/
@Test
void sorted(){
List<SysUser> collect = userList.stream().sorted(Comparator.comparing(SysUser::getUserAge)).collect(Collectors.toList());
final Stream<SysUser> sorted = userList.stream().sorted(Comparator.comparingInt(SysUser::getUserAge));
log.info("collect:{}",collect);
log.info("sorted:{}",sorted);
}
/**
* 转换 可以返回新的数据类型
*/
@Test
void map(){
List<Integer> collect = userList.stream().map(sysUser -> sysUser.getUserAge()).collect(Collectors.toList());
log.info("collect:{}",collect);
}
/**
* 转换 数据类型再操作求和
*/
@Test
void mapTo(){
double sum = userList.stream().mapToDouble(SysUser::getTentId).sum();
log.info("sum:{}",sum);
}
/**
* 转换 数据类型再操作求和
*/
@Test
void reduce(){
//BigDecimal 的运算
//promotionGroupDtoList.stream().map(PromotionGroupDto::getGroupPrice).reduce(BigDecimal.ZERO, BigDecimal::add);
Optional<Integer> reduce = userList.stream().map(SysUser::getUserAge).reduce((n1,n2)->n1+n2);
log.info("reduce:{}",reduce.get());
}
/**
* 转换 筛选 只返回布尔类型
* anyMatch表示,判断的条件里,任意一个元素成功,返回true
*
* allMatch表示,判断条件里的元素,所有的都是,返回true
*
* noneMatch跟allMatch相反,判断条件里的元素,所有的都不是,返回true
*/
@Test
void anyMath(){
boolean match = userList.stream().allMatch(sysUser -> sysUser.getUserAge()==2);
log.info("match:{}",match);
}
}