使用Stream对List、Set和Map的增强操作

Stream接口

Stream是在JDK1.8中才引入的接口,其中包含大量对集合对象操作的功能方法,它能使得对集合对象的操作更加高效和遍历。

Stream的特点:

  • Stream不存储元素
  • Stream不会修改数据源,而是会产生一个修改后的Stream对象,进而链式调用
  • Stream的执行具有延迟特性

 

如何创建Stream对象:

1.从数组中获取Stream对象

//方式1:Arrays中的静态stream方法
		Integer[] arr= {1,2,3,4,5};
		Stream<Integer> stream=Arrays.stream(arr);

2.使用Stream中的静态方法of

//方式2:Stream类中的静态方法of(T... param)
		Stream<String> stream2=Stream.of("a","b","c","d");
		Stream<Integer> stream3=Stream.of(1,2,3,4,5);

3.使用集合

List<Integer> list =Arrays.asList(1,2,3,4);
		//普通流
		Stream<Integer> stream01=list.stream();
		//并行流
		Stream<Integer> stream02=list.parallelStream();

Stream转换成数组、集合

1.Stream-->数组

//String[] :: new 等价于创建一个new String[stream元素个数]
		List<Integer> list=Arrays.asList(1,2,3,4,5);
		Integer[] arr=list.stream().toArray(Integer[]::new);//Stream-->数组
		System.out.println(Arrays.toString(arr));

2.Stream-->List、Set、Stack

//Stream-->List、Set、Stack
		List<String> list3=Arrays.asList("a","b","c","a"); //将list--->Stream 
		Stream<String> stream1=list3.stream(); //将Stream ---> list 
		List<String> list4=stream1.collect(Collectors.toList()); 
		System.out.println(list4); //将Stream ---> Set 
		Set<String> set1=stream1.collect(Collectors.toSet()); 
		System.out.println(set1); //将Stream ---> Stack 
		Stack<String> stack=stream1.collect(Collectors.toCollection(Stack::new));

Stream流的操作方法:

流的链式调用有两类方法:一类是中间操作,指的是调用过程中会产生新的Stream对象进而用来调用新的方法。另一类是终端操作,指的是调用这类方法会终止掉Stream流,从而结束掉链式调用。

常用操作方法:

中间操作方法:

  • filter:过滤,将符合条件的数据保留下来生成一个新的Stream
  • sorted:排序,对Stream中元素进行排序,然后生成一个新的Stream
  • distinct:去掉重复值,将不重复的元素 生成一个新的Stream
  • map:遍历流中每一个元素,生成一个新的Stream对象
  • flatMap:将每一个元素拆分成新的流
  • limit:截断流,返回一个不超过给定长度的新Stream对象

终端操作方法:

  • forEach:遍历流中元素,会关闭流
  • findFirst:返回第一个元素
  • findAny:
  • allMatch:要求所有Stream中所有元素都满足条件才返回true
  • noneMatch:要求所有Stream中所有元素都不满足才返回true
  • anyMatct:要求所有Stream中只要有一个元素满足就返回true
  • reducr:把Stream中元素按照一种规则串起来,参数必须要是Integer类型或者Double类型
  • count:返回Stream中元素的个数
  • collect:将Stream装换为别的类型(List、Set、Stack等)
  • groupingBy:Collections中用于分组的方法
中间操作: Stream<T> distinct() 去重 
          Stream<T> filter(Predicate<? super T> predicate) 过滤 
          <R> Stream<R> flatMap(Function<? super T,? extends Stream<? extends R>> mapper) 1:n映射 
          Stream<T> limit(long maxSize) 获取指定个数元素的Stream 
          <R> Stream<R> map(Function<? super T,? extends R> mapper) IntStream mapToInt(ToIntFunction<? super T> mapper) 将对象某个属性为int 字段存入IntStream中 
          Stream<T> sorted() 返回由此流的元素组成的流,根据自然顺序排序。 
          Stream<T> sorted(Comparator<? super T> comparator) 
终端操作: boolean allMatch(Predicate<? super T> predicate) Stream中所有元素否满足条 件才返回true 
          boolean anyMatch(Predicate<? super T> predicate) Stream中有任意一个元素满 足条件返回true 
          boolean noneMatch(Predicate<? super T> predicate) Stream中所有元素都不满足 条件返回true 
          <R,A> R collect(Collector<? super T,A,R> collector) 将Stream转换成 数 组、List、Set 结合groupingBy分组 使用转换map 
          Optional<T> findAny() Optional<T> findFirst() void forEach(Consumer<? super T> action) 遍历Stream中元素 
          Optional<T> max(Comparator<? super T> comparator) 根据提供的 Comparator返回此流的最大元素。 
          Optional<T> min(Comparator<? super T> comparator) 根据提供的 Comparator返回此流的最小元素。 
          Optional<T> reduce(BinaryOperator<T> accumulator)

 

在使用filter时会使用到Lambda表达式,因此介绍一下Lambda表达式:

首先,Lambda表达式是JDK1.8版本新增加特性,它的格式如下;

Lambda表达式的格式:

第一部分:(参数)

第二部分:->

第三部分:方法体

 

Lambda表达式的功能是为了替代匿名内部类。

它适用于只有一个抽象方法的接口(方法大于1就不知道传入参数是哪个方法的参数了)。

还有就是作为函数式接口适用于函数式编程场景(因为Java中的函数式编程体现就是Lambda,所以函数式接口就是可以使用Lambda的接口)。

使用例子来对比一下使用Lambda表达式和不使用的区别:

package com.lambda;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Consumer;

public class Demo1 {
	public static void main(String[] args) {
		List<String> list= new ArrayList<String>();
		Collections.addAll(list, "科特迪瓦", "阿根廷", "澳大利亚", "塞尔维亚", "荷兰", 
				"尼日利亚", "日本", "美国", "中国", "新西兰", "巴西", "比利时",
				"韩国", "喀麦隆", "洪都拉斯", "意大利");
		//匿名内部类
		Collections.sort(list,new Comparator<String>() {

			@Override
			public int compare(String o1, String o2) {
				return o1.length()-o2.length();
			}
		});
		//未简化版Lambda表达式
		Collections.sort(list,(String o1,String o2) -> {return o1.length()-o2.length();});
		//简化版Lambada表达式
		Collections.sort(list,(o1,o2) -> o1.length()-o2.length());
		
		//使用foreach遍历
		list.forEach(new Consumer<String>() {

			@Override
			public void accept(String t) {
				System.out.println(t);
			}} );
		
		//使用lambda表达式遍历
		list.forEach(t->System.out.println(t));
		//简化lambda表达式
		list.forEach(System.out::println);
		
	}

}

使用例子来看看Lambda在函数式接口在中的作用:

介绍一下,我使用了Predicate类,我们只用把它理解为过滤的条件就行,因为它创建的对象的作用确实就是为了给过滤器提供过滤条件。

package com.lambda;

import java.util.Arrays;
import java.util.List;
import java.util.function.Predicate;

public class Demo4 {
	public static void main(String[] args) {
		List<String> list=Arrays.asList("Java","Peee","JSwing","Python");
		//过滤条件
		Predicate<String> tj1=(t)->t.startsWith("J");
		Predicate<String> tj2=(t)->t.length()==4;
		//stream是对集合功能的增强操作,然后调用过滤器,过滤条件通过Lambda表达式定义
		list.stream().filter(tj1.and(tj2)).forEach(System.out::println);

	}

}

以上是我对Lambda表达式的入门级的理解和总结。接下来接着介绍Stream的相关内容方法。其他的方法都相对比较简单,通过简单的例子应该就能理解它们的用法,在此只着重介绍分组的相关内容。

 

分组(待补充和修正)

首先要知道哪里使用分组?

通常理解题目意思时出现按照某种条件分类讨论问题的时候,就需要想到可能使用分组。

分组的调用方法?

调用collect方法,参数可以传递分组,格式为:collect(Collectors.groupingBy(分组条件));

清楚以下类以相关方法:

IntSummaryStatistics
DoubleSummaryStatistics
LongSummaryStatistics
  • 2
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值