JAVA8新特性之stream

  • 流的操作流程
  • 中间操作的方法
  • 1.用谓词筛选:filter(),该操作返回一个谓词做参数,并返回一个符合谓词的元素的流
  • 2.去重:distinct(),返回一个元素各异的流
  • 3.截短流:limit(int n),返回一个指定长度的流
  • 4.跳过元素:skip(int n),返回一个丢弃了前n个元素的流,如果元素不足n个,则返回一个空流
  • 5.映射:map(),接收一个函数,将应用到每个元素上,并映射成一个新的元素
  • 6.流的扁平化:flatMap(),各个数组并不是分别映射成一个流,而是转化为流的内容
  • 终端操作的方法
  • 1.查找和匹配:allMatch(),anyMatch(),noneMatch(),findFirst()和findAny()
  • 规约:reduce(),将流中的元素反复结合起来,得到一个值
  • 收集器:collector(),将元素按指定方法收集起来
  • 并行流


流的操作流程

  1. 一个执行查询的数据源
  2. 一个中间操作链,形成一条流的流水线
  3. 一个终端操作,执行流水线,并能生成结果
@Data
@Accessor(chain=true) //链式
public class User {
   private String id;
   private String name;
   private int age;
   public boolean isOldEnough(){
   	return age > 26;
   } 
}

//生成数据源
public class UserUtils {
   public static List<User> createUsers(){
   	List<User> users = new ArrayList<User>();
   	for(int i = 0 ; i<100 ; i++){
   		User user = new User();
   		user.setId(i+"id").setName("name"+i).setAge(i);
   		users .add(user);
   	}
   	return users;
   }
}

中间操作的方法

1.用谓词筛选:filter(),该操作返回一个谓词做参数,并返回一个符合谓词的元素的流

//筛选出年龄大于26的用户

//老式写法
List<User> users = UserUtils.createUsers();
List<User> filteredUsers = new ArrayList<>();
users.forEach((user)->{
	if(user.isOldEnough()){
		filteredUsers .add(user);
	}
});

//流式写法
List<User> users = UserUtils.createUsers().stream().filter(User :: isOldEnough).collect(Collectors.toList());

2.去重:distinct(),返回一个元素各异的流

List<User> users = UserUtils.createUsers().stream().distinct().(Collectors.toList());

3.截短流:limit(int n),返回一个指定长度的流

List<User> users = UserUtils.createUsers().stream().limit(6).(Collectors.toList());

4.跳过元素:skip(int n),返回一个丢弃了前n个元素的流,如果元素不足n个,则返回一个空流

List<User> users = UserUtils.createUsers().stream().skip(6).(Collectors.toList());

//skip()和limit()是一对方法,可以结合使用达到对数据进行分段处理的目的
List<User> users = UserUtils.createUsers().stream().skip(6).limit(6).(Collectors.toList()); //获取第二个6元素的集合

5.映射:map(),接收一个函数,将应用到每个元素上,并映射成一个新的元素

List<String> userNames = UserUtils.createUsers().stream().map(User :: getName).(Collectors.toList());

6.流的扁平化:flatMap(),各个数组并不是分别映射成一个流,而是转化为流的内容

List<Integer> num1 = Arrays.asList(1,2,3);
List<Integer> num2 = Arrays.asList(3,4);
List<int[]> list = num1.stream().flatMap(i->{
	num2.stream().map(j->new int[]{i,j})
}).collect(Collectors.toList());
//执行结果为[(1,3),(1,4),(2,3),(2,4),(3,3),(3,4)]

终端操作的方法

1.查找和匹配:allMatch(),anyMatch(),noneMatch(),findFirst()和findAny()

boolean isOld = UserUtils.createUsers().stream().anyMatch(User :: isOldEnough);
/**
 * allMatch(),检查是否所有的元素都符合给定的谓词
 * anyMatch(),检查是否有一个元素符合给定的谓词
 * noneMatch(),检查是否元素都不符合给定的谓词
 * findAny(),返回当前流中的任意元素,可以和filter()结合使用效果更好
 * findFirst(),查找第一个元素
 */
List<User> users = UserUtils.createUsers().stream().filter(User :: isOldEnough).findAny();

规约:reduce(),将流中的元素反复结合起来,得到一个值

List<Integer> nums = Arrays.asList(1,2,3,4,5,6);
int num = nums.stream().reduce(0,Integer :: sum); //执行结果21

收集器:collector(),将元素按指定方法收集起来

Collectors.toList(),把流中的所有元素收集到一个List里;
.toSet(),返回一个set
.toCollection(),把流中的所有元素放到指定的集合中 //使用方法:collect(toCollection(),ArrayList :: new);
counting(),计算流中的元素个数;
summingInt(),对流中的整数性求和;
averaingInt(),返回平均值;
summarizingInt(),收集流中的Integer属性的统计值,最大、最小、平均值等;
joining(),调用toString()方法;
maxBy(),按照指定比较器的最大值;
minBy(),最小值;
reducing(),合并为单个值(二进制);
collectingAndThen(),对结果应用转换函数;
groupingBy(),分组操作;
partitingBy(boolean flag),对结果进行分区

并行流

parallel(),将顺序流变成并行流;
sequential(),将并行流转换成顺序流;

list.parallelStream().sorted(Comparator.compring(User :: getName)).sequential().collect(Collectors.groupingBy(User :: getAge));