stream流入门

文章目录

  • 前言
  • 一、定义
  • 二、使用
    • 1.创建数据流
    • 2.创建流
      • 1.单列集合
      • 2.数组
      • 3.双列集合
    • 3.中间操作
    • 4.终结操作
  • 三、Optional
    • 1.使用
  • 总结


前言

  • 在工作中你会见到大量的stream流的链式编程,为了简便地操作集合和数组,同时提高效率,我们使用stream流。

一、定义

  • stream流是jdk8引入的一种函数式编程的API,在Java中没有函数,所以引入新的函数式编程操作API,它是强大的处理数据的API。

二、使用

注意
我们必须要有终结操作,比如forEach(o->Println)
必须要有数据源,stream()

1.创建数据流

  • .stream 创建数据流
  • .distinct 去重
  • .filter(each -> 条件)
  • .forEach(each -> 遍历操作)
List<User> users = userServiceImpl.getAllUsers();
// 1.创建stream流
users.stream() 	// 创建stream流
	.distinct() // 去重
	.filter(each -> each.getAge() < 18) // 通过过滤器筛选
	.forEach(each -> System.out.println(each.getName())); 
	// 遍历操作

2.创建流

1.单列集合

List<User> users = userServiceImpl.getAllUsers();
users.stream()		// 获得数据流
	 .forEach(each->System.out.println(each));	

2.数组

  • 方法一:Arrays.stream()
int[] array = new int[]{1,2,3,4,5};
Arrays.stream(array)
	  .distinct()
	  .filter(each->each > 2)
	  .forEach(each->System.out.println(each));
  • 方法二:Stream.of()
int[] array = new int[]{1,2,3,4,5};
Stream.of(array)
	  .distinct()
	  .filter(each->each > 2)
	  .forEach(each->System.out.println(each));

3.双列集合

  • .entrySet() 将map转换成单列集合
  • each.getKey() 获得键
  • each.getValue() 获得值
Map<String, Integer> map = new HashMap<>();
map.put("迪迦",999);
map.put("戴拿",999);
map.put("盖亚",999);
map.entrySet() // 先把map变成单列集合
   .stream()	// 再直接创造数据流
   .filter(o->o.getValue()>16)
   .filter(o->o.getKey().equals("迪迦"))
   .forEach(o->System.out.println(o)); // 终结操作

3.中间操作

  • filter
  • distinct
  • map :将流当中的元素进行转换。注意,只能转换一层,如果说要转换成某个属性,而该属性又是一个集合,需要写两次forEach,所以我们要用flatMap。用来类型转换,常和reduce配合。
List<User> users = userServiceImpl.getAllUsers();
users.stream()		// 获得数据流
	 .map(each->each.getName());
	 .forEach(each->System.out.println(each));	
	 // 将每个User对象转换为其name属性
  • sorted:排序,如果一个类具有比较能力需要我们实现Comparable< T >接口,同时重写compareTo方法。如何确定顺序,自己去调试。
public class User implements Comparable<User>{
	Integer age;
	@Override
	public int compareTo(User other){
		return this.age - other.age;
	}
}
List<User> users = userServiceImpl.getAllUsers();
users.stream()		// 获得数据流
	 .sorted()
	 .forEach(each->System.out.println(each));	
	 // 将每个User对象转换为其name属性
  • 以上写法等价于:
List<User> users = userServiceImpl.getAllUsers();
users.stream()		// 获得数据流
	 .sorted((o1,o2)->o1.getAge()-o2.getAge())
	 .forEach(each->System.out.println(each));	
	 // 将每个User对象转换为其name属性
  • limit:设置流的长度。
List<User> users = userServiceImpl.getAllUsers();
users.stream()		// 获得数据流
	 .sorted((o1,o2)->o1.getAge()-o2.getAge())
	 .limit(2) // 取出前两个数据
	 .forEach(each->System.out.println(each));	
	 // 将每个User对象转换为其name属性
  • skip:跳过流中的前n个元素。
List<User> users = userServiceImpl.getAllUsers();
users.stream()		// 获得数据流
	 .sorted((o1,o2)->o1.getAge()-o2.getAge())
	 .skip(2) // 跳过前两个元素
	 .forEach(each->System.out.println(each));	
	 // 将每个User对象转换为其name属性
  • flatMap: 当需要转换成集合类型的时候,要调用两次stream。并且要使用flatMap。
List<User> users = userServiceImpl.getAllUsers();
users.stream()		// 获得数据流
	 .flatMap(each->each.getList().stream())
	 .forEach(each->System.out.println(each));	
	 // 将每个User对象转换为其name属性

4.终结操作

  • forEach():遍历集合。
  • count():统计集合中的元素。
  • min()/max():统计集合中的最大最小值。
Optional<Integer> max = users
	.stream()
	.flatMap(author -> author.getBooks().stream())
	.max((o1, o2) -> o1 - o2)
System.out.print(max.get());
  • collect():用于将流中的元素累积成一个结果容器。可以通过不同的收集器Collectors来实现各种复杂的转换操作。
List<User> users = userServiceImpl.getAllUsers();
List<User> newUsers = users
	.stream()
	.map(each->each.getAge())
	.collect(Collectors.toList());
List<User> users = userServiceImpl.getAllUsers();
List<User> newUsers = users
	.stream()
	.map(each->each.getAge())
	.collect(Collectors.toSet());
List<User> users = userServiceImpl.getAllUsers();
List<User> newUsers = users
	.stream()
	.filter(each->each.getAge() > 18)
	.collect(Collectors.toMap(each->each.getId(), each->each.getName()));
  • reduce:聚合操作。
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
Optional<Integer> sum = list.stream()
				  .reduce((o1,o2)->o1 + o2);
  • anyMatch:只要有一个匹配就返回true。
  • allMatch:必须全部匹配就返回true。
  • noneMatch:必须全都不匹配就返回true。
List<Integer> list = Arrays.asList(1,2,3,4,5,6,7);
boolean exist = list.stream()
				.anyMatch(o1->o1 == 3);
  • findAny:获取流中任意一个元素,无法保证是第一个元素。
  • findFirst:获取流中的第一个元素。
List<Integer> list = Arrays.asList(1,2,3,4,5);
Optional<Integer> first = list.stream()
							  .sorted((o1,o2)->o1-o2)
							  .findFirst()
  • ifPresent:判断是否存在。
first.ifPresent(o->System.out.println(o));

reduce:归并操作,将stream流中的元素进行归并操作。

List<Integer> list = Arrays.asList(1,2,3,4,5,6);
Integer sum = list.stream()
				  .reduce(0,  (r,e)->r + e)
				  // 表示从0开始,result+element
// 使用reduce求最小值
List<Integer> list = Arrays.asList(1,2,3,4,5,6);
Integer min = list.stream()
				  .reduce(Integer.MAXVALUE, (r, e) -> r > e ? e : r);

三、Optional

  • Optional是jdk8引入的容器类,用于解决空指针问题,它表示一个值可能存在,也可能不存在,提供了一系列方法来安全出的空的情况。
  • 一句话:优雅的避免空指针

1.使用

  • 创建对象,通常把它封装成一个对象来使用。
List<Users> list = userService.getAll();
Optional<List<User>> usersOptions = Optional.ofNullable(list);
userOptions.ifPresent(each->System.out.println(each));
  • 安全消费值:
  • 使用ifPresent()。以上就是例子。
  • 安全的获取值:
  • 如果 Optional 中的值为 null,则通过 Supplier 提供一个默认值。
  • Supplier 是 Java 8 引入的一个函数式接口,它表示一个 提供值的供应商。
  • orElseThrow:捕获,没有就抛出异常。
User user = new User("aaa","bbb");
Optional<User> userOptions = Optional.ofNullable(user);
User user = userOptions.orElseGet(()->new User("ccc","ddd"));
System.out.println(user.toString());
  • 过滤器filter、转换器map、
  • 跟中间操作的filter是一样的,但是它保留了结果为optional对象。

总结

  • stream是一次性的。
  • stream是懒加载形式的,必须要有终结方法。

你可能感兴趣的:(java)