java中Stream流

一 概述

数据渠道、管道,用于操作数据源(集合、数组等)所生成的元素序列。

集合讲的是数据,流讲的是计算

即一组用来处理数组,集合的API。

二 Stream特点

1 Stream 不是数据结构,没有内部存储,自己不会存储元素。

2 Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。

3 Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

4 不支持索引访问。

5 延迟计算

6  支持并行

7 很容易生成数据或集合

8 支持过滤,查找,转换,汇总,聚合等操作。

三 应用场景

流式计算处理,需要延迟计算、更方便的并行计算

更灵活、简洁的集合处理方式场景

四 代码实现

4.1 运行机制

Stream分为源source,中间操作,终止操作。

流的源可以是一个数组,集合,生成器方法,I/O通道等等。

一个流可以有零个或多个中间操作,每一个中间操作都会返回一个新的流,供下一个操作使用,一个流只会有一个终止操作。

中间操作也称为转换算子-transformation

Stream只有遇到终止操作,它的数据源会开始执行遍历操作。

终止操作也称为动作算子-action

因为动作算子的返回值不再是 stream,所以这个计算就终止了

只有碰到动作算子的时候,才会真正的计算

4.2 创建流的方式

 1 数组转换为流

String[] strings = { "q", "w", "e", "r" };
Stream<String> stream1 = Stream.of(strings);

2 通过集合

Arrays.asList : 把数组转换为集合

List<String> list = Arrays.asList(strings);
Stream<string> stream1 = list.stream();

3 通过Stream的generate创建

        generate是一个无限流(无限大),所以经常结合limit一起使用,来限制最大个数
        generate参数是一个 Supplier ,而 Supplier中有一个get方法用于获取数据, 而 get方法的返回值,会作为数据保存到这个流中,下面程序也就意味中该流中的数据都是1

Stream<Integer> stream2 = Stream.generate(()->1);

limit 是中间操作,设置流的最大个数,forEach 遍历,是终止操作

Stream<Integer> stream2 = Stream.generate(()->1);
stream2.limit(5).forEach(x->System.out.println(x) );
//运行结果为:1 1 1 1 1

4 通过String.iterate

        String.iterate 也是无限流

Stream<Integer> stream3 = Stream.iterate(1, x->x+2);

表示 参数1表示起始值,x+2表示步长为2 ,相当于 for(int i =1 ; true ; i+=2)

Stream<Integer> stream3 = Stream.iterate(1, x->x+2);
stream3.limit(5).forEach(x->System.out.println(x));
//运行结果为:1 3 5 7 9 

5 已有类的API

String string = "abc";
		IntStream chars = string.chars();
		chars.forEach(x->System.out.println((char)x));//a b c

4.3 常见的中间操作

         一个中间操作链,对数据进行处理,一个流可以进行0~N个中间操作,他们每一个都生成新的流,方便下一个进行操作,但是只能有一个终止操作

filter: 对元素进行筛选,不符合就不要了

distinct: 去除重复元素

 skip : 跳过多少元素

limit:取最大条数(前几条)

map: 对集合中元素进行遍历操作

sorted:排序

例子:

package day02;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;


public class Stream_01 {
public static void main(String[] args) {
	List <String> list=Arrays.asList("a","b","c","a");
	Stream<String> stream=list.stream();
//	stream.filter(x->false);
//	stream.filter(x->false);//流一旦用了之后,得重新生成
	// stream has already been operated upon or closed(流已经被操作)
//可以通过链式调用解决,因为stream使用后必须生成新的流,不能使用原来的stream
//	stream.filter(x->false).filter(x->false);//中间操作
	//x->x.equals("a") 是一个断言操作,如果返回false就不要该数据,如果返回true就要该数据
	List<String> value=stream.filter(x->x.equals("a")).collect(Collectors.toList());//转化为list
	//collect(Collectors.toList()); 终止操作,把(Streams)流转化为集合的固定写法
	System.out.println(value );//[a, a]
//	value.forEach(x->System.out.println(x));
	/**
	 * skip:跳过
	 */
	stream=list.stream();//重新生成新的流
	
	value=stream.skip(2).collect(Collectors.toList());//跳过2个
	value.forEach(x->System.out.println(x));//c a
	/**
	 * map:对集合中的元素进行遍历并操作
	 */
	List<Integer> list2=Arrays.asList(1000,1200,1100,5000,900);
	Stream <Integer> stream2=list2.stream();
	//涨薪百分之十
	List<Integer> result=stream2.map(x->x+x/10).collect(Collectors.toList());
	System.out.println(result);//[1100, 1320, 1210, 5500, 990]
	/**
	 * distinct: 去除重复
	 */
	stream=list.stream();
	list=stream.distinct().collect(Collectors.toList());//[a, b, c]
	System.out.println(list);
	/**
	 * limit:取前几条
	 */
	stream=list.stream();
	list=stream.limit(2).collect(Collectors.toList());
	System.out.println(list);//[a, b]
	/**
	 * sorted:排序
	 */
	 stream2=list2.stream();
		//涨薪百分之十
//	 result=stream2.sorted().collect(Collectors.toList());//默认升序
        result=stream2.sorted((x,y)->y-x).collect(Collectors.toList());//自定义为降序
		System.out.println(result);//[5000, 1200, 1100, 1000, 900]
	
	
	
	
	
}
}

运行时常见异常:

出现原因:流已经被操作了.流一旦用了之后,得重新生成

解决方法:重新生成流->Stream<String> stream=list.stream();

4.4 常见的终止操作

 一旦执行终止操作 , 中间操作才会真正执行,并且stream就不能在使用了

forEach:遍历

collect:收集器

 min ,max,count,agerage: 计算相关

 anyMatch: 匹配数据,比如是否包含

package day02;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.stream.Stream;

import javax.swing.plaf.ListUI;


public class Stream_03 {

	public static void main(String[] args) {
		// TODO Auto-generated method stub
		List <String> list=Arrays.asList("a","b","c");
		Stream<String> stream=list.stream();
/**
 * forEach :遍历操作
 */
		stream.forEach(x->System.out.println(x));//a,b,c
		/**
		 * 计数
		 */
		stream=list.stream();
		long count=stream.count();
		System.out.println(count);//3
		//所以这样很难体现出count的优势,一般需要结合中间操作执行,优势更大
		stream=list.stream();
		count=stream.filter(x->x.equals("a")).count();
		System.out.println(count);//1
		//获取最大值
		List<Integer> list2=Arrays.asList(1,4,3,6,5);
		Stream<Integer> stream2=list2.stream();
		Integer i=stream2.max((x,y)->x-y).get();
		System.out.println(i);//6
		//获取最小值
		 list2=Arrays.asList(1,4,3,6,5);
		 stream2=list2.stream();
		 i=stream2.min((x,y)->x-y).get();
		System.out.println(i);//1
		//匹配器 anyMatch
		 stream2=list2.stream();
		 boolean flab=stream2.anyMatch(x->x==5);
		 System.out.println(flab);//true
		 System.out.println(list2.contains(5));//true
		 List<User> listu=new ArrayList<User>();
		 listu.add(new User(19, "张三"));
		 listu.add(new User(17, "张三"));
		 listu.add(new User(17, "张三"));
		 listu.add(new User(18, "张三"));
		 Stream<User> streamu=listu.stream();
		 flab=streamu.anyMatch(x->x.getAge()==19);
//	 使用contains需要覆写equals方法
		 System.out.println("包含年龄19:  "+flab); //包含年龄19:  true
 	}
	
	
	
}
class User{
	private int age;
	public User(int age, String name) {
		super();
		this.age = age;
		this.name = name;
	}
	public int getAge() {
		return age;
	}
	public void setAge(int age) {
		this.age = age;
	}
	public String getName() {
		return name;
	}
	public void setName(String name) {
		this.name = name;
	}
	private String name;
	
}

 

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值