Stream API

Stream API说明

Java8中有两大最为重要的改变。第一个是 Lambda 表达式;另外一个则是 Stream API

Stream API ( java.util.stream) 把真正的函数式编程风格引入到Java中。这是目前为止对Java类库最好的补充,因为Stream API可以极大提供Java程序员的生产力,让程序员写出高效率、干净、简洁的代码。

Stream Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。 使用Stream API 对集合数据进行操作,就类似于使用 SQL 执行的数据库查询。也可以使用 Stream API 来并行执行操作。简言之Stream API 提供了一种高效且易于使用的处理数据的方式

什么是 Stream

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

Stream 不是集合,自己 不会存储元素。
Stream 不会改变源对象。相反,他们会返回一个持有结果的新 Stream
Stream 操作 是延迟执行的 。必须搞清楚有哪些数据才能往下执行,这 意味着他们会等到需要结果的时候才执行
Stream 只能“消费”一次,如果想继续做其他操作,需要重新获取 stream 对象

④更像一个高级的iterator,单向,不可往复,数据只能遍历一次,遍历过一次后即用尽了,但是可以并行化数据!哦也!!\(^o^)/

17a8b8cac78ab94fec29cb0c87832773d6c.jpg

b7bb870f3c6abe7de8de908c25b21454fdc.jpg

3566bb5a17d0c0f14666398ded7e22185b5.jpg

176462069ff0bab404a0fe492f5a21318be.jpg

bf47ae7c914b6fac3495804515a1b66bee3.jpg

8997ad3976cd4fd1f3e6b5345f34daf8f7b.jpg

caa3dc6979cefbf72ab3198b63e6ac933e2.jpg

b212ae7af5c9f4c58d2f2f4f7d3ab2177fb.jpg

8913f9f5548c7677787271b30afae845d2b.jpg

6dc23e598def37e9a9d9302fe6d21900a83.jpg

并行流与串行

并行流就是把一个内容分成多个数据块,并用不同的线程分别处理每个数据块的流。

Java 8 中将并行进行了优化,我们可以很容易的对数据进行并行操作。Stream API 可以声明性地通过 parallel() sequential() 在并行流与顺序流之间进行切换。

Optional

         到目前为止,臭名昭著的空指针异常是导致Java应用程序失败的最常见原因。以前,为了解决空指针异常,Google公司著名的Guava项目引入了Optional类,Guava通过使用检查空值的方式来防止代码污染,它鼓励程序员写更干净的代码。受到Google Guava的启发,Optional类已经成为Java 8类库的一部分

        Optional实际上是个容器:它可以保存类型T的值,或者仅仅保存nullOptional提供很多有用的方法,这样我们就不用显式进行空值检测

Optional类的Javadoc描述如下:这是一个可以为null的容器对象。如果值存在则isPresent()方法会返回true,调用get()方法会返回该对象

 

Optional<T> (java.util.Optional) 是一个容器类,代表一个值存在或不存在原来用 null 表示一个值不存在,现在 Optional 可以更好的表达这个概念。并且可以避免空指针异常

常用方法:

Optional.empty() : 创建一个空的 Optional 实例

Optional.of(T t) : 创建一个 Optional 实例

Optional.ofNullable(T t):t 不为 null,创建 Optional 实例,否则创建空实例

isPresent() : 判断是否包含值

T get(): 如果调用对象包含值,返回该值,否则抛异常

orElse(T t) :  如果调用对象包含值,返回该值,否则返回t

orElseGet(Supplier s) :如果调用对象包含值,返回该值,否则返回 s 获取的值

map(Function f): 如果有值对其处理,并返回处理后的Optional,否则返回 Optional.empty()

flatMap(Function mapper):map 类似,要求返回值必须是Optional

package day26_1;

import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import org.junit.Test;

/**
 * Stream是流, 是工作流
 *   要处理批量的数据
 * 
 * 1) Stream 不保存数据, 只处理数据
 * 2) Stream 是延迟执行的, 只有最后的执行操作下达的时候才会执行其中的操作, 并且可以有多个流式处理
 * 3) Stream 的消费是一次性的, 每处理一次都会产生一个新的流
 * 4) Stream 不会修改数据源
 * 
 * Stream操作有经典的3步
 * 1) 创建流
 * 2) 一系列的中间操作, 流水线, (可以省略)
 * 		filter(Predicate p) // 流中的每个数据都要经过判定的判定, 如果判断结果为真的留下, 假的丢弃。
 * 		distinct(); 去重依据的是对象的hashCode和equals
 * 		limit(int size) 限制最多的个数
 * 		sorted() 自然排序
 * 		sorted(Comparator com) 定制排序
 * 		map(Function fun) 把流中的所有数据转换为另外的类型并产生新流
 * 		
 * 3) 终止流
 * 		Optional<T> findFirst(); // 返回流中的第一个元素
 * 		long count();
 * 		reduce(BinaryOperator bo) ;// 二元运算, 两输入一输出, 最后产生一个结果
 * 		collect()收集
 * 
 * Optional 的正确用法 , 尽量避免空指针
 * 		orElse(非空);
 */
public class SteamTest {
	
	@Test
	public void test13() {
		Stream<Student> stream = StudentData.getList().stream();
		//stream.parallel();
		Set<Student> set = stream.distinct().collect(Collectors.toSet()); // toList
		for (Student student : set) {
			System.out.println(student);
		}
	}
	
	@Test
	public void test12() {
		Stream<Student> stream = StudentData.getList().stream();
		// 找出最高分
		Optional<Double> optional = stream.distinct().map(t -> t.getScore()).reduce((t1, t2) -> t1 > t2 ? t1 : t2);
		System.out.println(optional.orElse(101.0));
	}
	
	@Test
	public void test11() {
		Stream<Student> stream = StudentData.getList().stream();
		// 统计有几个五年级同学
		long count = stream.distinct().filter(t -> t.getGrade() == 5).count();
		System.out.println(count);
	}
	
	@Test
	public void test10() {
		Stream<Student> stream = StudentData.getList().stream();
		Optional<Student> findFirst = stream.distinct().filter(t -> t.getGrade() == 3).findFirst();
		//System.out.println(findFirst.get());
		System.out.println(findFirst.orElse(new Student()).toString());
	}
	
	@Test
	public void test9() {
		Stream<Student> stream = StudentData.getList().stream();
		stream.distinct().map(t -> t.getScore()).forEach(System.out::println);
	}
	
	@Test
	public void test8() {
		Stream<Student> stream = StudentData.getList().stream();
		stream.sorted((t1, t2) -> t1.getGrade() - t2.getGrade()).forEach(System.out::println);
	}
	
	@Test
	public void exer2() {
		//找出3年级中没有及格的同学, 倒序排序, 并取出前2个3年级同学.
		Stream<Student> stream = StudentData.getList().stream();
		stream.distinct().filter(t->t.getGrade()==3).filter(t->t.getScore()<60)
		.sorted((t1, t2) -> (int)(t2.getScore() - t1.getScore())).limit(2).forEach(System.out::println);
	}
	
	@Test
	public void test7() {
		Stream<Student> stream = StudentData.getList().stream();
		stream.distinct().limit(50).forEach(System.out::println);
	}
	
	@Test
	public void test6() {
		Stream<Student> stream = StudentData.getList().stream();
		stream.distinct().forEach(System.out::println);
	}
	
	@Test
	public void test5() {
		Stream<Student> stream = StudentData.getList().stream();
		// 所有姓张的并且及格的
		stream.filter(t -> t.getScore() >= 60).filter(t -> t.getName().startsWith("张")).forEach(System.out::println);
	}
	
	@Test
	public void exer1() {
		// 找出3年级没有及格的同学
		Stream<Student> stream = StudentData.getList().stream();
		stream.filter(t -> t.getGrade() == 3).filter(t -> t.getScore() < 60).forEach(System.out::println);
	}
	
	@Test
	public void test4() {
		// 无限流
		//Stream<Integer> generate = Stream.generate(() -> 100);
		Stream<Double> generate = Stream.generate(Math::random);
		generate.forEach(System.out::println);
	}
	
	@Test
	public void test3() {
		// 基于一些散数据
		Stream<String> stream = Stream.of("abc", "xxx", "zzz", "yyy", "qq");
		stream.forEach(System.out::println);
	}
	
	@Test
	public void test2() {
		// 基于数组
		Integer[] arr = {1, 3, 8, 9, 10};
		Stream<Integer> stream = Arrays.stream(arr);
		//stream.forEach(t -> System.out.println(t));
		stream.forEach(System.out::println); // 方法引用的方式
	}
	
	@Test
	public void test1() {
		// 基于集合获取流
		List<Student> list = StudentData.getList();
		Stream<Student> stream = list.stream();
		// 终止流 , forEach(Consumer con); // 把流中的每个对象都经过这个消费器消费一下
		stream.forEach(t -> System.out.println(t));
		//stream.forEach(t -> System.out.println(t)); 必须一次性使用流
	}
}

转载于:https://my.oschina.net/architectliuyuanyuan/blog/3048182

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值