Stream–集合流
简介
Stream是对集合操作的增强,流不是集合的元素,不是一种数据结构,不负责数据的存储。流更像是一个迭代器,可以单向的遍历集合中的每一个元素,并且不可循环。
为什么使用集合的流式编程
有些时候,对集合中元素进行操作时,需要使用其他操作的结果。在这个过程中,集合的流式编程会大大简化编程的代码量。将数据源中的数据读到一个流中,可以对这个流中的数据进行操作(删除,过滤。。。),每次处理的结果都是一个流对象,可以对这个流继续操作。
流式编程的步骤
- 获取数据源:将集合的数据读到一个流中;
- 中间操作:对流进行处理,得到的结果仍然是一个流对象;
- 终止操作:对流中的数据整合,关闭流对象。
注
:中间操作和终止操作时,基本上的方法都是函数式接口,需要lamda表达式来达到简化代码的目得。
1、数据源的获取
将数据读到一个流中,对流进行的操作不会影响数据源的数据,筛选的只是流中的所剩数据
//集合
public static Stream<Integer> getDatasource(){
List<Integer> list = new ArrayList<>();
Collections.addAll(list,1,2,3,4,5,6,7,8,9);
return list.stream();//同步流
//return list.parallelStream();//异步流
}
//包装类数组
public static Stream<Integer> getAraayDatasource(){
Integer[] array = new Integer[]{1,2,3,4,5,6,7,8,9};
Stream<Integer> stream = Arrays.stream(array);
return stream;
}
//基本数据数组
public static IntStream getIntDatasource(){
int[] array = new int[]{1,2,3,4,5,6,7,8,9};
IntStream intStream = Arrays.stream(array);
return intStream;
}
2、终止操作
通过最终操作提取出流中想要的数据,之后会销毁这个流。操作关闭的流会抛异常。
- collect:将流中的数据收集起来,对这些数据进行处理。
public static void main(String[] args) {
Stream<Integer> stream = Datasource.getDatasource();
//[1, 2, 3, 4, 5, 6, 7, 8, 9]
//Set<Integer> set = stream.collect(Collectors.toSet());
//{2=3, 3=4, 4=5, 5=6, 6=7, 7=8, 8=9, 9=10, 10=11}
//Map<Integer, Integer> map = stream.collect(Collectors.toMap(i -> i + 1, i -> i + 2));
//[1, 2, 3, 4, 5, 6, 7, 8, 9]
List<Integer> list = stream.collect(Collectors.toList());
System.out.println(list);
}
- reduce:将流中的数据按一定的规则聚和起来。方法中一个返回值两个参数的函数式接口
public static void main(String[] args) {
Stream<Integer> stream = Datasource.getDatasource();
Optional<Integer> integerOptional = stream.reduce((p1, p2) -> p1 + p2);
Integer integer = integerOptional.get();
System.out.println(integer);//45
}
- count:统计流中的数据数量
public static void main(String[] args) {
Stream<Integer> stream = Datasource.getDatasource();
System.out.println(stream.count());
}
- foreach:遍历流中的数据。方法中一个参数没有返回值的函数式接口
public static void main(String[] args) {
Stream<Integer> stream = Datasource.getDatasource();
stream.forEach(System.out::println);
}
- max&min:按照指定的规则找出最大最小值
public static void main(String[] args) {
Stream<Integer> stream = Datasource.getDatasource();
Integer max = stream.max(Integer::compareTo).get();
Integer min = stream.min(Integer::compareTo).get();
}
-
Matching:
allmatch:流中元素都匹配规则,返回true
anymstch:流中任意元素满足规则,返回true
nonematch:流中元素都不满足规则,返回true
public static void main(String[] args) {
Stream<Integer> stream = Datasource.getDatasource();
//System.out.println(stream.allMatch(integer -> integer > 5));//false
//System.out.println(stream.anyMatch(integer -> integer > 5));//true
System.out.println(stream.noneMatch(integer -> integer <0));//true
}
-
find
findfirst:返回流中的第一个元素;
firstany:返回流中的任意(一般为第一个);多线程时不一定
public static void main(String[] args) {
Stream<Integer> stream = Datasource.getDatasource();//并行流
//System.out.println(stream.findFirst().get());//1
System.out.println(stream.findAny().get());//6
}
---
public static void main(String[] args) {
Stream<Integer> stream = Datasource.getDatasource();//串行流
//System.out.println(stream.findFirst().get());//1
System.out.println(stream.findAny().get());//1
}
- IntStream的另外的终止操作
public static void main(String[] args) {
IntStream intStream = Datasource.getIntDatasource();
int asInt = intStream.max().getAsInt();//最大值
int asInt1 = intStream.min().getAsInt();//最小值
int sum = intStream.sum();//和
long count = intStream.count();//元素个数
double v = intStream.average().getAsDouble();//平均值
IntSummaryStatistics summaryStatistics = intStream.summaryStatistics();//数据分析合集
double average = summaryStatistics.getAverage();
long count1 = summaryStatistics.getCount();
int max = summaryStatistics.getMax();
int min = summaryStatistics.getMin();
}
3、中间操作
对流处理可进行多次
- filter:条件过滤,剔除不满足条件的元素
stream.filter(integer -> integer>5).forEach(System.out::println);
- distinct:去除流中重复的元素。去重原则与HashSet一样,实体类需要重写hashcode()和equls
stream.distinct().forEach(System.out::println);
-
sorted:
-
[无参]排序实体类需实现Comparable接口;
-
[有参]自定义接口实现
-
stream.sorted().forEach(System.out::println);
-
limit & skip:
limit:限制,截取一定数量的数据
skip:跳过,掉过指定数量的数据
stream.distinct()
.limit(5)
.skip(2)
.sorted()
.forEach(System.out::println);
-
map & flatmap
map:提供规则,用新的数据替换流中的数据
flatmap:扁平化映射,将流中的容器中的数据直接读取到流中
stream.map(integer -> "第"+integer+"个数据").forEach(System.out::println);
//第1个数据、第2个数据、第3个数据、第4个数据、第5个数据、第6个数据、第7个数据、第8个数据、第9个数据
public static void main(String[] args) {
String[] array = new String[]{"hello","world"};
Stream<String> stream = Arrays.stream(array);
//统计出现的字符
// stream.map(String::toCharArray)
.forEach(e-> System.out.println(e));//{'h','e','l','l','o'} ,{'w','o','r','l','d'}
stream.map(s->s.split(""))//{"h","e","l","l","o"} ,{"w","o","r","l","d"}
.flatMap(Arrays::stream)//{"h","e","l","l","o","w","o","r","l","d"}
.distinct()//{"h","e","l","o","w","r","d"}
.forEach(System.out::print);//helowrd
}
- mapToInt:一个参数,int类型的返回值,返回流对象为IntStream
IntStream intStream = stream.mapToInt(Integer::byteValue);
IntSummaryStatistics summaryStatistics = intStream.summaryStatistics();
4、Collectors工具类的其他操作
- maxby()、minby() 、summingInt()、averagingInt()、summarizingInt():都可通过mapToInt()替换
- joining:将流中的数据拼接成一个字符串,只能操作Stream
public static void main(String[] args) {
String[] array = new String[]{"hello","world","java","c++"};
Stream<String> stream = Arrays.stream(array);
//参数一:分隔符
//参数二:前缀
//参数三:后缀
String collect = stream.collect(Collectors.joining("-", "[", "]"));
System.out.println(collect);//[hello-world-java-c++]
}
版权声明:本文为qq_38473355原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。