stream流常用有哪些方法(stream流map方法)

 分类:IT知识时间:2022-07-10 07:30:16点击:

流模型的操作很多,大致上可以把其中的api方法分成两部分:

-延迟发放:返回值类型都是Stream接口自身,因此可以支持链式操作。

-终结方法:返回值类型不是Stream接口自身,因此不能再进行链式操作。比如:count方法和forEach方法

下面介绍几种常用的方法:

1、forEach方法

(1)原理解析

void forEach(Consumer consumer);// 借助于该函数式接口中的方法accept方法, Consumer 是一个消费型接口,用来消费一个指定泛型的数据

(2)示例代码

public class TestForEach {	public static void main(String[] args){		// 1.获取一个数据源
		Stream<String> stream = stream.of("abc","aaa","abd","bcd","ddd");		// 2. 转换数据
		// 3. 执行操作获取想要的结果
		stream.forEach(str -> {			if (str.contains("a")){
				System.out.println(str);
			} 
		});
	}
}// 展示的结果abc aaa abd

2、filter方法

(1)原理解析

可以通过filter方法将一个流转换另外一个子集流

Stream<T> filter(Predicate<? super T> Predicate) 返回由与此给定匹配的此流元素组成的流// 借助于Predicate函数式接口当中的抽象方法 test(T t) 对数据进行过滤

该方法接受一个函数式接口Predicate,可以使用Lambda表达式进行条件的筛选

Predicate接口


java.util.stream.Predicate函数式接口,其中唯一的抽象方法

boolean test(T t),该方法会返回布尔类型值,代表指定的条件是否满足,如果条件满足返回true,那么Stream流的方法filter将集合或者数组其中的元素保留下来,如果条件不满足返回false,那么filter方法会舍弃该元素

(2)示例代码

public static void main(String[] args) {		// 1、 准备一个数据源
		// 获取该数据源
		String[] arr = {"小孙","小王","小赵","老王","涂少","老刘"};		// 2. 数据转换
		// 使用Stream流中的方法filter,对姓涂的人过滤掉
		Stream<String> stream = Stream.of(arr);
		Stream<String> stream2 = stream.filter(name -> !name.contains("涂"));
		Stream<String> stream3 = stream2.filter(name -> name.startsWith("小"));
		stream3.forEach(name ->System.out.println(name));
		stream2.filter(name -> !name.contains("少")).forEach(name ->System.out.println(name));		 
		/* Stream流属于管道流,每次只能被消费一次
		 * 第一个Stream流调用完毕后,数据就会被转换到下一个Stream上
		 * 而这时第一个Stream流已经使用完毕,就会关闭了。
		 * 所以第一个Stream就不能再调用方法了。
		 * 如果你强制调用方法,程序就会抛出非法状态异常
		 * java.lang.IllegalStateException: stream has already been operated upon or closed
		 * stream.filter(name -> !name.contains("涂"))
		      .filter(name -> name.startsWith("小"))
		      .forEach(name ->System.out.println(name));
		*/
	}

3、映射:map

(1)原理解析

map方法:将流中的数据映射到另一个流中。

<R> Stream<R> map<Function<? super T,? extends R> mapper)//返回由给定函数应用于此流的元素的结果组成的流

该方法接受一个函数式接口Function作为方法参数,可以将当前流中的T数据转换成另一种R类型的数据。

Function接口:Java.util.stream.Function函数式接口。其中唯一的抽象方法如下

R apply(T t)// 可以将一种T类型的数据转换成R类型的数据,那么这种转换的动作,我们将之称为“映射”

(2)示例代码

public static void main(String[] args) {		// 1. 准备一个数据源
		// 获取数据源
		// 把String字符串的整数-->int类型的整数
		Stream<String> stream = Stream.of("123","124","125","126","120");		// 2. 数据转换 把字符串类型的数据转换成int类型的数据 由于Function是一个函数式接口,所以可以使用Lambda表达式
		// apply(T t) //		Stream<Integer> stream2 = stream.map(str -> Integer.valueOf(str));
		Stream<Integer> stream2 = stream.map((String str) -> {			return Integer.valueOf(str);
		});		// 遍历
		stream2.forEach(num -> System.out.println(num));
	}

4、统计个数:count

(1)原理解析

可以像Collection集合当中的size()一样,统计流中的元素个数,通过count方法来实现

// 返回此流中的元素数long count();

该方法返回一个long类型的值代表流中的元素个数(区别于size()返回值int值)

(2)示例代码

public class Demo01Count {    public static void main(String[] args) {
      Stream<Integer> stream =  Stream.of(1,2,3,4,5,6);      // 统计个数
      long count =   stream.count();
      System.out.println(count);// 6  
    } 
}

5、取用流中前几个:limit

(1)原理解析

limit()方法可以对流中的数据进行限制–>截取操作,需要一个参数max,设定取用流中前max个数。注意点:参数是一个long类型的,截取的长度不能超过流中的最大元素个数,否则不进行操作。

(2)示例代码

public class Demo02Limit {    public static void main(String[] args){        // 准备一个数据源
        // 获取数据源
       Stream<Integer> stream =  Stream.of(12,13,14,15,16,20,30);       // 想要截取流中的前五个元素
       Stream<Integer> stream02  = stream.limit(5);       // 查看流中的元素个数
        System.out.println(stream02.count());// 5
    }   
}

6、跳过前几个:skip

(1)原理解析

跳过前几个元素后,取用后面的元素时,可以用到skip方法

Stream<T> skip(long n) // 在丢弃流的前n元素后,返回由该流的后面元素组成的流

如果流中的当前个数小于n,你将会得到一个长度为0的空流;反之流中的个数大于n,则会跳过前n个元素。

(2)示例代码

public static void main(String[] args) {		// 1.
		String[] source = {"123","124","125","126","abc","abd","abe"};
		Stream<String> stream = Stream.of(source);		// 2. 跳过前4个元素
    Stream<String> stream3 = stream.skip(4);    // 空流 
		Stream<String> stream2 = stream.skip(source.length+1);// 空流
		// 3. 
		//stream3.forEach(str -> System.out.println(str));// abc abd abe
		long count = stream2.count();
		System.out.println(count);// 0
	}

7、组合:concat

(1)原理解析

如果有两个流,希望合并成一个流,那么可以使用concat静态方法

// 创建一个懒惰连接的流,其元素是第一个流的所有元素,后跟第二个流的所有元素。 
static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)

(2)示例代码

public class Demo04Concat {    public static void main(String[] args){        // 准备二个数据源
        // 获取两次数据源
       Stream<Integer> stream   =   Stream.of(12,13,14,15,16,20,30);
       Stream<Integer> stream02 =   Stream.of(1,2,3,4,5,6,7);       // 把两个流合并成一个流
       Stream<Integer> stream03 =   Stream.concat(stream,stream02); 
       stream03.forEach(num -> System.out.print(num + " "));       //展示结果: 12,13,14,15,16,20,30,1,2,3,4,5,6,7  
    }   
}

最后总结:

流式操作在我们日常工作用途还是挺广的,当我们需要遍历某种集合时,可以将集合转换成stream流式,这样最大的好处就是提升了代码的效率和质量。


除注明外的文章,均为来源:老汤博客,转载请保留本文地址!
原文地址: