搜索
您的当前位置:首页正文

stream()流的使用

来源:易榕旅网

引入流

  • java api提供的一种利用声明式的方式处理数据集合的一个东西,可以被看成一个高级迭代器

流的操作

流水线:也就是很多流操作本身会返回一个流,可以将多个操作连接起来,形成一个更大的流

  • filter() :谓词过滤,筛选出适合条件的实体
  • sorted():对集合进行排序
  • map():提取某项元素
  • collect():将流转换为其它形式
  • limit():截断流,是元素不超过给定数量
  • 流的迭代是内部迭代,外部迭代一般是有程序员控制的迭代,foreach就属于外部迭代,并且流只能遍历一次

中间操作

  • 像filter、sorted等都会生成一个流,中间操作也就是会将这些流合并成一个流,这个东西也叫做合并循环

终端操作

  • 终端操作会从流水线生成结果,其结果是任何不是流的值,比如List、Integer、void等
//forEach会返回void的终端操作
menu.stream().forEach(System.out.println);

流的使用

谓词筛选

  • 因为流支持filter操作,filter是属于行为参数化的,可以通过谓词来筛选出我们需要的元素

筛选各异的元素

  • 流可以使用distinct()方法,它会返回一个各异元素的流(底层是通过hashcode和equals()实现)

流的切片

  • takewhile(): filter()会把所有的元素都过一遍,如果数据量过大,速度会非常慢,takewhile()当遇到不符合的元素会停止处理,大大节约了时间
  • dropwhile():dropwhile()是对takewhile()的补充,它会丢弃掉谓词为false的元素,当谓词为true,它会停止处理,并返回谓词为false的元素

截断流

  • 上面提到了,对流进行截断,返回给定数量的元素

跳过元素

  • skip(n):跳过给定数量的元素,如果 n 大于元素个数,则会返回一个空的流

映射

映射是指map()操作,它会返回我们指定的元素属性

流的扁平化

flatMap()的作用是,各个数组并不是分别映射成一个流,而是映射成流的内容

例子: 给定一个单词表["Hello", "World"], 想要返回列表['H', 'e', 'l', 'o', 'W', 'r', 'd']

第一次尝试:
	word.stream().map(item->item.split(" "))
		.distinct()
		.toCollect()
	map(item->item.split())的返回结果是Stream<String[]>,我们需要的是Stream<String>,distinct操作并不能形成我们想要的结果

第二次尝试:
	word.stream().map(item->item.split(" "))
		.map(Arrays::stream)
		.distinct()
		.collect()
	map(Arrays::stream)是将每一个数组变为一个流,并不能达到我们要的结果

第三次尝试:
	word.stream().map(item->item.split(" "))
		.flatMap(Arrays::stream)
		.distinct()
		.collect()
	flatMap(Arrays::stream)会将每一个数组的内容分别映射为流的内容,然后将流合并形成一个流,在进行distinct()就可以达到效果

查找和匹配

常见的数据处理的套路是看数据集中的某些元素是否匹配一个给定的元素,Stream Api通过allMatch、anyMatch、noneMatch、findFirst和findAny实现

  • anyMatch():流中是否有一个元素能匹配给定的谓词
  • noneMatch():所有元素是否匹配给定的谓词
  • noneMatch():确保没有元素与给定的谓词匹配
  • findAny():返回当前流的任意元素
  • findFirst():指定流中元素的出现顺序
Optional:
	一般用来处理空指针异常的,允许程序中出现null了,一般来说查询的返回结果可以给一个Optional
	isPresent():有值返回true,没有值返回false
	ifPresent(Consumer<T> block): 会在存在值的时候执行代码块
	get(T other): 会在值存在时返回值,不存在值抛出异常
	orElse(): 存在值就返回值,不存在值就返回一个默认值

归约

将流中的元素反复结合起来,得到一个值,这样的操作叫做归约操作,归约的优势在于内部迭代和并行化,并行化就是将stream()变为parallelStream()

  • reduce(初始值一般为0, 需要的操作)
int sum = numbers.stream().reduce(0, Integer::sum);
//无初始值的情况
Optional<Integer> sum = numbers.stream().reduce((a,b)-> (a+b));

元素求和、最大值和最小值

Optional<Integer> sum = numbers.stream().reduce(0, Integer::sum);
Optional<Integer> max = numbers.stream().reduce(Integer:max);
Optional<Integer> min = numbers.stream().reduce(Integer:min);

数值流

  • mapToInt(): 返回一个IntStream()
  • mapToDouble():返回一个DoubleStream()
  • OptionalInt 的默认值是0,用来求和还行,求最大值不适用
  • rangeClosed(1,100):是IntStream的一个方法,可以规定数值范围
//使用归约求涉及到拆包的问题
int sum = numbers.stream().reduce(0, Integer::sum);
//map的返回值是Stream<类>,不行
Optional<Integer> sum = numbers.stream().map(::方法).sum();
//maptoInt()的返回值是IntStream,还支持max()、min()、average()等
Optional<Integer> sum = numbers.stream().mapToInt(::方法).sum();
//使用orElse来指定OptionalInt的值,如果没有最大值,显方式提供一个默认最大值
OptionalInt<Integer> test = xxx;
int max = test.orElse(1);

构建流

由值构建流
Stream<String> stream = Stream.of("modern", "java", "In", "Action");
stream.map(String :: toUpperCase).forEach(System.out::println);
//创建一个空的流
Stream<String> emptyStream = Stream.empty();
由数组创建流
int[] numbers = {2, 3, 5, 7, 11, 13};
int sum = Arrays.stream(numbers).sum();

因篇幅问题不能全部显示,请点此查看更多更全内容

Top