Stream的使用
Stream是Java1.8新出的一个类,主要用对集合进行计数、过滤、排序、聚合等操作,非常方便
常用方法
在看案例前,先来了解一下这个类从常用方法把
map (mapToInt, flatMap 等):将对应的元素按照给定的方法进行转换,比如获取部分值,值转换都可以用map来进行,如下
List<String> names = Arrays.asList("Java8", "Lambdas", "In", "Action");
List<String[]> collect = words.stream().map(word -> word.split("")).collect(Collectors.toList());
flatMap:map中的一种,如果你在使用了map之后想使用foreach输出每个元素,那么就应该使用,flatMap,因为返回的就是多个流的集合,无法继续接下来的 foreach 操作的,因此需要 flatMap 将两个 Stream扁平化成一个 Stream,才能使用foreach输出每个元素,如下
List<String> names = Arrays.asList("Java8", "Lambdas", "In", "Action");
List<String> collect1 = words.stream().map(word -> word.split("")).flatMap(Arrays::stream).collect(Collectors.toList());
collect1.stream().forEach(System.out::println);
filte:过滤,相当于数据库中where条件,符合条件的筛出来
List<String> names = Arrays.asList("Java8", "Lambdas", "In", "Action");
names.stream().filter(e->"Java8".equals(e)).forEach(System.out::println);
distinct:去重,即去掉重复值,如果是对象的话,记得重写equals和hashCode()方法,否则去重是无效的
List<String> list = Arrays.asList("111","222","333","111","222");
list.stream().distinct().forEach(System.out::println);
sorted(排序):通过执行规则排序,按照学生的id进行降序排序,再按照年龄进行降序排序
data.stream()
.sorted((stu1,stu2) ->Long.compare(stu2.getId(), stu1.getId()))
.sorted((stu1,stu2) -> Integer.compare(stu2.getAge(),stu1.getAge()))
.forEach(System.out::println);
limit:限制返回个数
List<String> list = Arrays.asList("333","222","111");
list.stream().limit(2).forEach(System.out::println);
skip:跳过几个元素
List<String> list = Arrays.asList("333","222","111");
list.stream().skip(2).forEach(System.out::println);
reduce:将集合中每个元素聚合成一条数据,可以对字符串进行聚合,也可以对数字进行聚合,在对数字进行聚合的时候,可以看作是累加操作
List<String> list = Arrays.asList("欢","迎","你");
String appendStr = list.stream().reduce("北京",(a,b) -> a+b);
System.out.println(appendStr);
累加:
List<Integer> num = Arrays.asList(1, 2, 3, 4, 5, 6);
Integer reduce = num.stream().reduce(0, (a, b) -> a + b);
System.out.println("sum:"+reduce);
int sum = num.stream().mapToInt(Integer::intValue).sum();
System.out.println("sum:"+sum);
max、min:最大、最小值
List<Integer> num = Arrays.asList(1, 2, 3, 4, 5, 6);
Integer max = num.stream().reduce(Integer::max).get();
System.out.println("max:"+max);
int min = num.stream().mapToInt(Integer::intValue).sum();
System.out.println("min:"+min);
如果是针对对象求则需要指明用哪个字段比较,这样才能得到最小值
Student minS = students.stream().min((stu1,stu2) ->Integer.compare(stu1.getAge(),stu2.getAge())).get();
findAny:该方法返回当前流中的任意元素,可以和其他流操作结合使用比如ifPresent()判断是否存在,或者get()获得返回值
案例
来看一个加和案例:entity在文章末尾给出,我们需要对entity的score进行加和,而score的类型为BigDecimal,但是Stream支持的三种加和类型为Int、Long、Double,为此应该需要将BigDecima转为Int、Long、Double,不转的话,编译也是过不了的,这里使用了mapToDouble,
并且调用了doubleValue(),将BigDecima转换为Double类型
//用Stream对一年级,一班的学生成绩进行加和
List<Student> list = iStudentService.list();
double sum = list.stream().filter(e -> e.getSgrade().equals("一年级")).mapToDouble(e -> e.getScore().doubleValue()).sum();
System.out.println(sum+"sum");
return new Result("","good",sum);
如果Score是String类型,是否也可以进行加和呐?当然是可以的,但是需要调用Double.parseDouble将字符串解析为Double类型,再求和,如下
List<StudentInfo> studentInfos = iStudentService.selectByAll(null);
double sum = studentInfos.stream().filter(e -> e.getSgrade().equals("一年级")).mapToDouble(e -> Double.parseDouble(e.getScore())).sum();
return new Result("","good",sum);
entity
@Data
@EqualsAndHashCode(callSuper = false)
@TableName("STUDENT")
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
/**
* 学号
*/
@TableId("SID")
private String sid;
/**
* 姓名
*/
@TableField("SNAME")
private String sname;
/**
* 年级
*/
@TableField("SGRADE")
private String sgrade;
/**
* 班级
*/
@TableField("SCLASS")
private String sclass;
@TableField("COUNT_TIME")
private LocalDateTime countTime;
@TableField("PIC_PATH")
private String picPath;
@TableField("STUDENT_TYPE")
private String studentType;
@TableField("SCORE")
private BigDecimal score;
}