stream详解
stream主要是对JAVA中collection类的聚合功能的增强。Stream API配合lamada表达式,极大的提升了编程效率和程序可读性。Stream中支持并行和串行两种聚合方式。
Stream使用的时候包括三个步骤
- 创建流
- 中间操作(多个中间操作可以连接起来形成流水线,除非流水线发生终止操作,否则中间操作不会执行任何处理,而在终止操作的时候一次性全部处理,被称为惰性求值或者叫延迟加载)
- 终止操作
代码演示
1.创建流
//集合获取流
List<Person> list = Lists.newArrayList();
Stream<Person> stream = list.stream();
//数组获取流
String[] array = {"java","python","go"};
Stream<String> arrayStream = Arrays.stream(array);
//根据值获取流
Stream<String> valueStream = Stream.of("java","python","go");
2.中间操作
1.筛选与切片(filter,skip,limit,distinct)
@Test
public void test1() {
//测试filter(接收lambad表达式,从集合中将某些元素排除)
//JDK8中有双冒号的用法,就是把方法当做参数传到stream内部,
//使stream的每个元素都传入到该方法里面执行一下。
list.stream().filter((e)->{
return e.getAge()>15;
})
//终结操作
.forEach(System.out::println);
}
@Test
public void test2() {
//测试limit 截断流,使给出的元素不超过限定值
list.stream().filter((e)->{
return e.getAge()>15;
})
.limit(1)
//终结操作
.forEach(System.out::println);
}
@Test
public void test3() {
//测试skip 跳过给定值,如果流中元素低于给定值,则返回空流
list.stream().filter((e)->{
return e.getAge()>15;
})
.skip(3)
//终结操作
.forEach(System.out::println);
}
@Test
public void test4() {
//测试distinct 将对象去重,根据hashcode和equals去重
list.stream().filter((e)->{
return Objects.equal(e.getSex(), "男");
})
.distinct()
//终结操作
.forEach(System.out::println);
}
2.映射(map和flatMap)
public void test5() {
//map 接收一个函数作为参数,并将该函数应用到流中的每个元素上,映射成一个新的元素
//类似于guva中Lists.transform方法
list.stream()
.filter((e)->e.getAge()>25)
.map((e)->e.getName())
.forEach(System.out::println);
}
public void test6() {
//flatMap 接收一个函数作为参数,将流中的每一个值转换为另个流
//然后把所有的流合成一个流
//在未使用flatMap的时候需要针对流嵌套流进行双层循环
List<String> list = Lists.newArrayList("aaa","bbb","ccc","ddd","eee");
list.stream()
.map(TestStreamApi::listCharacter)
.forEach((e)->{
e.forEach(System.out::println);
});
//使用flatmap
list.stream()
.flatMap(TestStreamApi::listCharacter)
.forEach(System.out::println);;
}
public static Stream<Character> listCharacter(String value){
List<Character> result = Lists.newArrayList();
for(Character character:value.toCharArray()) {
result.add(character);
}
return result.stream();
}
3.排序(sorted 默认自然排序或者实现comparator)
//测试排序
public void test7() {
//sorted 排序
list.stream()
.sorted((e1,e2)->{
if(e1.getAge() > e1.getAge()) {
return e1.getAge()-e2.getAge();
}else {
return e2.getAge()-e1.getAge();
}
}).forEach(System.out::println);
}
3 终止操作
1.查找与匹配(allMatch,anyMatch,noneMatch,findFirst,findAny,count,max,min)
//测试查找与匹配
@Test
public void test8() {
//allMatch 检查是否匹配所有的元素
Boolean boolean1 = list.stream()
.allMatch(e->Objects.equal(e.getSex(),"男"));
System.out.println(boolean1);
//anyMatch 检查至少是否匹配了一个元素
Boolean boolean2 = list.stream()
.anyMatch(e->Objects.equal(e.getSex(), "男"));
System.out.println(boolean2);
//noneMatch 检查是否没有匹配所有元素
Boolean boolean3 = list.stream()
.noneMatch(e->Objects.equal(e.getSex(), "男"));
System.out.println(boolean3);
//findFirst 查找第一个元素
Optional<Person> optional = list.stream()
.findFirst();
System.out.println(optional.get());
//查找任意一个元素
Optional<Person> optional2 = list.stream()
.skip(2)
.findAny();
System.out.println(optional2.get());
}
@Test
public void test9() {
// count 返回流中元素的总数
long count = list.stream()
.count();
System.out.println(count);
//max 返回流中最大值
Optional<Person> optional = list.stream()
.max((e1,e2)->e1.getAge()-e2.getAge());
System.out.println(optional.get());
//min 返回流中最小值
Optional<Person> optiona2 = list.stream()
.min((e1,e2)->e1.getAge()-e2.getAge());
System.out.println(optiona2.get());
}
2 规约(reduce,collect)
@Test
public void test10() {
//reduce 将流中元素反复结合起来 得到一个值
List<Integer> demo = Lists.newArrayList(1,2,3,4,5,6,7,8,9,10);
Integer sum = demo.stream()
.reduce(0, (x,y)->x+y);
System.out.println(sum);
//算出人数的年龄综合
Optional<Integer> optional = list.stream()
.map(Person::getAge)
.reduce(Integer::sum);
System.out.println(optional.get());
}
public void test11() {
//收集 collect 将流转换为其他形式。接收一个Collector接口的实现,
//用于给Stream中元素做汇总的方法,并且通过collectors提供了更多的静态
//实现收集器
//tolist转换为集合,类似toset toCollection
List<Person> persons = list.stream()
.filter(e->e.getSex().equals("女"))
.collect(Collectors.toList());
System.out.println(persons);
//groupingby 对流中的某属性将流进行分组
Map<String, List<Person>> map = list.stream()
.collect(Collectors.groupingBy(
e->e.getSex()));
System.out.println(JSON.toJSONString(map));
}
备注 关于collectors的静态方法收集器一览
方法 | 返回类型 | 作用 |
---|---|---|
toList | List | 把流中元素收集到List |
toSet | Set | 把流中元素收集到Set |
toCollection | Collection | 把流中元素收集到创建的集合 |
counting | Long | 计算流中元素的个数 |
summingInt | Integer | 对流中元素的整数属性求和 |
averagingInt | Double | 计算流中元素Integer属性的平均值 |
summarizingInt | IntSummaryStatistics | 收集流中Integer属性的统计值。如:平均值 |
joining | String | 连接流中每个字符串 |
maxBy | Optional 根据比较器选择最大值 | |
minBy | Optional | 根据比较器选择最小值 |
reducing | 归约产生的类型 | 从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值 |
collectingAndThen | Optional | 根据比较器选择最小值 |
minBy | 转换函数返回的类型 | 根据比较器选择最小值 |
minBy | Optional | 包裹另一个收集器,对其结果转换函数 |
groupingBy | Map<K,List> | 根据某属性值对流分组,属性为K,结果为V |
partitioningBy | Map<Boolean,List> | 根据true或false进行分区 |