Java Stream

流的定义

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

流的特点

  1. Stream 本身不会存储数据;
  2. Stream 不会改变数据源,相反会生成一个持有结果的新 Stream;
  3. Stream 的操作时延迟的,会等到需要结果的时候才去执行。

流的创建

  1. 通过 Collection 系列集合提供的 stream() 或者 parallelStream() 方法创建;
	List<String> list = new ArrayList<>();
	Stream<String> stream = list.stream(); //串行流
	Stream<String> stringStream = list.parallelStream();//并行流
  1. 通过 Arrays 的 stream() 方法创建;
	String[] arr = new String[10];
	Stream<String> stream = Arrays.stream(arr);
  1. 通过 Stream 类的静态方法创建;
   	Stream<String> stream = Stream.of("test");
  1. 创建无限流
   	Stream<Integer> stream = Stream.iterate(0, (x) -> x + 2);

Stream 的中间操作

Stream 的多个中间操作可以连接起来形成流水线,除非流水线上触发终止操作,否则中间操作不会执行任何的处理,而在终止操作时一次性全部处理,称为惰性求值。

  1. filter(过滤):从流中排除某些元素;
	String[] arr = {"abcx","sjdjs","66"};
	Stream<String> stream1 = Arrays.stream(arr);
	Stream<String> stream2 = stream1.filter((e) -> {
		System.out.println(e); //注意,此条语句不会执行,会在终止操作时统一执行
		return e.length()>2;
	});
	stream2.forEach(System.out::println);//运行结果:abcx、sjdjs
  1. limit(截断):使其元素不超过指定数量
	String[] arr = {"java","ruby","shell","json"};
	Stream<String> stream1 = Arrays.stream(arr);
	Stream<String> stream2 = stream1.limit(2);//指定元素不超过两个
	stream2.forEach(System.out::println);//运行结果:java、ruby
  1. skip(跳过):跳过元素,返回去掉前n个元素的流。如果流中的元素不超过n个,则返回一个空流,与limit(n)互补;
	List<Integer> list = new ArrayList<>();
	list.add(1);
	list.add(2);
	list.add(3);
	list.add(4);

	Stream<Integer> stream = list.stream().skip(2);
	stream.forEach(System.out::println);//运行结果:3,4; 跳过了1、2
  1. distinct(去重):通过流所生成的元素的 hashCode() 和 equals() 去重。
	List<Integer> list = new ArrayList<>();
	list.add(1);
	list.add(2);
	list.add(3);
	list.add(4);
	list.add(1);
	list.add(1);

	Stream<Integer> stream = list.stream().distinct();
	stream.forEach(System.out::println);//运行结果: 1、2、3、4
  1. map(映射):接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
	List<String> list = Arrays.asList("a","b","c","d");
	Stream<String> stream = list.stream().map((str) -> str.toUpperCase());
	stream.forEach(System.out::println);//运行结果:A、B、C、D,大写方法全部应用到每个元素上
  1. flatMap:接收一个函数作为参数,将流中的每一个元素地换成一个流,然后把所有的流连接成一个流。
import org.junit.Test;

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

public class StreamMapTest {

	public static Stream<Character> strToCharStream(String str){
		List<Character> list = new ArrayList<>();
		for (Character character : str.toCharArray()){
			list.add(character);
		}
		return list.stream();
	}

	@Test
	public void test(){
		String[] arr = new String[]{"aaa","bbb","ccc"};

		Stream<Stream<Character>> mapStream = Arrays.stream(arr).map(StreamMapTest::strToCharStream);//得到的是 Stream<Stream<Character>>,即流的流
		mapStream.forEach(System.out::print);
		System.out.println();
		Stream<Stream<Character>> mapStream2 = Arrays.stream(arr).map(StreamMapTest::strToCharStream);
		mapStream2.forEach((s)->s.forEach(System.out::print));
		System.out.println();
		Stream<Character> flatStream = Arrays.stream(arr).flatMap(StreamMapTest::strToCharStream);//得到的 Stream<Character>,即单个流
		flatStream.forEach(System.out::print);

	}
}
/*
*java.util.stream.ReferencePipeline$Head@244038d0java.util.stream.ReferencePipeline$Head@5680a178java.util.stream.ReferencePipeline$Head@5fdef03a
*aaabbbccc
*aaabbbccc
*/
  1. sorted():自然排序;sorted(Comparator com):定制排序;
	public void testSorted(){

		List<String> list = Arrays.asList("wade ","james ","kobe ");
		list.stream().sorted().forEach(System.out::print);
		System.out.println();
		list.stream().sorted((e1,e2)-> -e1.compareTo(e2)).forEach(System.out::print);
	}
	/** 输出结果:
	* james kobe wade 
	 * wade kobe james 
	 */

终止操作

  1. allMatch():全部匹配
	List<Integer> list = Arrays.asList(3,4,5,6,7);
	System.out.println(list.stream().allMatch(e-> e>1));//输出 ture
	System.out.println(list.stream().allMatch(e-> e>5));//输出 false
  1. anyMatch():部分匹配
	List<Integer> list = Arrays.asList(3,4,5,6,7);
	System.out.println(list.stream().anyMatch(e -> e>5));//输出 ture
	System.out.println(list.stream().anyMatch(e -> e==1));//输出 false
  1. noneMatch():不匹配
	List<Integer> list = Arrays.asList(3,4,5,6,7);
	System.out.println(list.stream().noneMatch(e -> e==1));//输出 true
	System.out.println(list.stream().noneMatch(e -> e==3)); //输出 false
  1. findFirst():返回第一个元素
	List<Integer> list = Arrays.asList(3,4,5,6,7);
	Optional<Integer> first = list.stream().findFirst();
	System.out.println(first.get());//输出3
  1. findAny():返回当前流的任一一个元素
	List<Integer> list = Arrays.asList(3,4,5,6,7);
	Optional<Integer> any = list.stream().filter(e -> e > 5).findAny();
	System.out.println(any.get()); //输出6
  1. count():返回流的元素的个数
	List<Integer> list = Arrays.asList(3,4,5,6,7);
	long count = list.stream().filter(e -> e > 5).count();
	System.out.println(count);//输出2
  1. max():返回流中的最大元素
    min():返回流中的最小元素
	List<Integer> list = Arrays.asList(3,4,5,6,7);
	Optional<Integer> max = list.stream().filter(e -> e > 5).max((e1, e2) -> e1.compareTo(e2));
	System.out.println(max.get());//输出7

	Optional<Integer> min= list.stream().filter(e -> e > 5).min((e1, e2) -> e1.compareTo(e2));
	System.out.println(min.get());//输出6
  1. reduce() : 归约,可以将流中的元素反复结合起来,得到一个值

	List<String> list = Arrays.asList("football","basketball","swimming","tennis");
	String reduce = list.stream().reduce("table tennis", (e1, e2) -> e1 + "," + e2);
	System.out.println(reduce);//输出:table tennis,football,basketball,swimming,tennis  第一个参数为起始值,将每个元素进行拼接
	Optional<String> reduce2 = list.stream().filter(e -> e.length() > 6).map(e -> e.toUpperCase()).reduce(String::concat);//没有起始值,所以有可能为空,返回类型为Optional<String>
	System.out.println(reduce2.get()); //输出结果:FOOTBALLBASKETBALLSWIMMING
  1. collect():收集,接收一个Collector的接口的实现,用于给Stream 中的元素做汇总,Collectors 工具类提供了常用的方法。
		List<String> list = Arrays.asList("football","basketball","swimming","tennis","tennis","tennis");
		Long collect = list.stream().collect(Collectors.counting());
		System.out.println(collect);//输出 6
		Set<String> collect1 = list.stream().collect(Collectors.toSet());
		System.out.println(collect1); //输出[swimming, basketball, football, tennis]

并行流和串行流

串行流和并行流的抽象方法存在 BaseStream 中

  1. 串行流:sequential(),返回顺序的等效流。可能会返回本身,或者是因为流已经是顺序的,或者是因为底层流状态被修改为顺序的。
	Instant start = Instant.now();
		long sum = LongStream.rangeClosed(0, 10000000000L)
				.sequential() //指定串行流
				.sum();
	Instant end = Instant.now();
	long time = ChronoUnit.MILLIS.between(start, end);
	System.out.println(time); //输出 4566  根据机器的不同此值不同
  1. 并行流:parallel(),返回一个并行的等效流。可能会返回本身,或者因为这个流已经是并行的,或者因为底层流状态被修改为并行的。
	Instant start = Instant.now();
	longsum = LongStream.rangeClosed(0, 10000000000L)
			.parallel() //指定并行流
			.sum();
	Instant end = Instant.now();
	long time = ChronoUnit.MILLIS.between(start, end);
	System.out.println(time); //输出 1330 根据机器的不同此值不同
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值