
Java8 Stream API使用示例Stream是什么Java8中的Stream也叫流不过不同于IO流它是对集合操作的一个增强API个人理解1、它使用内部迭代操作集合2、它提供了类似数据库中count、avg等聚合操作学习过程中留个记录话不多说上代码。import java.util.ArrayList; import java.util.Comparator; import java.util.DoubleSummaryStatistics; import java.util.List; import java.util.Map; import java.util.Optional; import java.util.OptionalDouble; import java.util.stream.Collectors; import java.util.stream.Stream; public class StreamDemo { public static void main(String[] args) { /** * 创建流 * 1、Collection等通过stream()方法、Arrays中得静态方法stream获取数组流 * 2、Stream.of()Stream.iterate()、Stream.generate()无限流 */ //初始化数据 ListStudent list new ArrayList(); list.add(new Student(5, 张三, 22,语文, 85)); list.add(new Student(1, 李四, 23,数学, 86)); list.add(new Student(4, 麻子, 21,语文, 82)); list.add(new Student(6, 麻子, 21,英语, 98)); list.add(new Student(2, 张三, 22,数学, 99)); list.add(new Student(7, 李四, 23,语文, 90)); //list.add(new Student(8, 李四, 23,语文, 90)); //测试去重的时候可以加上这条记录 /* * 1.1、filter 过滤数据留下入参返回true的数据 * 需求查询分数大于90的人 */ ListStudent collect list.stream().filter(s - s.getScore()90).collect(Collectors.toList()); System.out.println(1.1、filter 查询分数大于90的人:collect); /* * 1.2、filter 过滤数据留下入参返回true的数据 * 需求查询语文分数大于等于90的人 */ ListStudent c2 list.stream() .filter(s - { if(s.getSubject().equals(语文) s.getScore()90){ return true; }else{ return false; } }).collect(Collectors.toList()); System.out.println(1.2、filter 查询语文分数大于等于90的人:c2); /* *这里输出用了lambda的方法引用 *概念对于一个lambda表达式只是调用了一个方法时可以用方法引用的方式简化lambda表达式 *方法引用的标准形式是类名::方法名。注意只需要写方法名不需要写括号 有以下四种形式的方法引用 类型 示例 引用静态方法 ContainingClass::staticMethodName 引用某个对象的实例方法 containingObject::instanceMethodName 引用某个类型的任意对象的实例方法 ContainingType::methodName 引用构造方法 ClassName::new * */ list.stream() .filter(s - { if(s.getSubject().equals(语文) s.getScore()90){ return true; }else{ return false; } }).forEach(System.out::println); //方法引用 /* * 2.1、map 转换可以将原对象转换成另一个对象流 * 典型需求得到id列表 */ ListInteger idList list.stream().map(Student::getId).collect(Collectors.toList()); System.out.println(2.1、map 由ListStudent转换后得到ListIntegerid列表:idList); /* * 2.2、mapToDouble 转换可以将原对象流转换成Double流 * 典型需求求张三的平均分 */ OptionalDouble average list.stream() .filter(s - s.getName().equals(张三)) //保留张三的记录 .mapToDouble(Student::getScore) //将分数转成一个mapToDouble流 .average(); //求平均分 DoubleSummaryStatistics summary list.stream() .filter(s - s.getName().equals(张三)) //保留张三的记录 .mapToDouble(Student::getScore) //将分数转成一个mapToDouble流 .summaryStatistics(); System.out.println(2、mapToDouble 求张三的平均分: (average.isPresent()?average.getAsDouble():average.orElse(0))); System.out.println(2、summaryStatistics 张三分数统计: 总分summary.getSum(),最高分summary.getMax(),最低分summary.getMin(),共几科summary.getCount(),平均分summary.getAverage()); /* * 3、distinct 去重根据对象的hashCode和equals方法去重 * 典型需求列表去重 */ ListStudent distinctList list.stream().distinct().collect(Collectors.toList()); System.out.println(3、distinct 去重后列表:distinctList); /* * 4、sort 排序可以自定义排序规则 * 需求先根据姓名升序再根据科目升序在再根据分数降序 */ ListStudent sortedList list.stream().sorted(Comparator.comparing(Student::getName) //姓名升序 //.thenComparing(Student::getSubject) //科目升序 .thenComparing(Student::getScore).reversed()) //分数降序 .collect(Collectors.toList()); System.out.println(4、sort 先根据姓名升序再根据科目升序在再根据分数降序:sortedList); /* * 5、peek 什么都不干一般用于调试输出元素啥的 * 按照Java团队的说法peek()方法存在的主要目的是用调试通过peek()方法可以看到流中的数据经过每个处理点时的状态 * 需求过滤长度大于3的字符串转成大写 */ Stream.of(one, two, three, four) .filter(e - e.length() 3) //长度大于3的得到 three, four .peek(e - System.out.println(Filtered value: e)) .map(String::toUpperCase) // 转成大写 .peek(e - System.out.println(Mapped value: e)) .collect(Collectors.toList()); /* * 6、limit 截取前N条数据 * 需求截取前3条数据 */ ListStudent limitList list.stream().limit(3) .collect(Collectors.toList()); System.out.println(6、limit 截取前3条数据:limitList); /* * 6、skip 跳过N条数据 * 需求跳过1条数据 */ ListStudent skipList list.stream().skip(1) .collect(Collectors.toList()); System.out.println(7、skip 跳过1条数据:skipList); /* * 7.1、reduce 归约把值合成一个 使用只有一个入参的情况 * OptionalT reduce(BinaryOperatorT accumulator); * 需求求和 */ OptionalInteger accResult Stream.of(1, 2, 3, 4) .reduce((acc, item) - { //第一个参数是统计值第一次执行是第一个元素第二个参数是流元素第一次是第二个元素 System.out.println(acc : acc); //统计结果第一次执行是第一个元素 acc item; System.out.println(item: item); //流里面的元素第一次是第二个元素 System.out.println(acc : acc); //统计结果 System.out.println(--------); return acc; }); System.out.println(7.1、reduce 归约 使用只有一个入参的情况 统计结果: accResult.get()); System.out.println(--------); /* * 7.2、reduce 归约把值合成一个 使用有两个入参的情况,第一个入参是统计初始值第二个是累加器 * T reduce(T identity, BinaryOperatorT accumulator); * param identity 是返回结果 * paramaccumulator 累加器 * 需求求和 */ Integer accResult2 Stream.of(1, 2, 3, 4) .reduce(0,(acc, item) - { //第一个参数0是统计结果初始值第二个参数是累加器跟上面一样 System.out.println(acc2 : acc); //统计结果第一次执行是初始值0 acc item; System.out.println(item2: item); //流里面的元素第一次是第1个元素 System.out.println(acc2 : acc); //统计结果 System.out.println(--------); return acc; }); System.out.println(7.2、reduce 归约 使用有两个入参的情况 统计结果2: accResult2); System.out.println(--------); /* * 8.1、Collectors.groupingBy * 需求根据姓名分组 * return MapString, ListStudent key姓名value该姓名对应的对象列表 */ MapString, ListStudent groupList list.stream() .collect(Collectors.groupingBy(Student::getName)); System.out.println(8.1、Collectors.groupingBy 根据姓名分组:groupList); /* * 8.2、Collectors.groupingBy * 需求根据姓名分组并统计每个分组有多少个元素count * return MapString, Long key:姓名value该组有多少个元素 * 例{李四2, 张三2, 麻子2} */ MapString, Long groupCount list.stream() .collect(Collectors.groupingBy(Student::getName,Collectors.counting())); System.out.println(8.2、Collectors.groupingBy 根据姓名分组并统计每个分组有多少个count:groupCount); /* * 8.3、Collectors.groupingBy * 需求根据姓名分组并统计每个分组各科平均分 * return MapString, Double key:姓名value平均分 * 例{李四88.0, 张三92.0, 麻子90.0} */ MapString, Double groupAvg list.stream() .collect(Collectors.groupingBy(Student::getName,Collectors.averagingDouble(Student::getScore))); System.out.println(8.3、Collectors.groupingBy 根据姓名分组并统计每个分组各科平均分:groupAvg); /* * 8.4、Collectors.groupingBy * 需求根据姓名分组并统计每个分组总分 * return MapString, Double key:姓名value总分 * 例{李四176.0, 张三184.0, 麻子180.0} */ MapString, Double groupSum list.stream() .collect(Collectors.groupingBy(Student::getName,Collectors.summingDouble(Student::getScore))); System.out.println(8.4、Collectors.groupingBy 根据姓名分组并统计每个分组总分:groupSum); /* * 8.5、Collectors.groupingBy 多字段分组 * 需求根据姓名学科分组 * return MapString, MapString, ListStudent key:姓名valuemap(key:学科value列表) * 例{李四{数学[Student [name李四, subject数学, score86.0]], 语文[Student [name李四, subject语文, score90.0]]}, 张三{数学[Student [name张三, subject数学, score99.0]], 语文[Student [name张三, subject语文, score85.0]]}, 麻子{语文[Student [name麻子, subject语文, score82.0]], 英语[Student [name麻子, subject英语, score98.0]]}} */ MapString, MapString, ListStudent groups list.stream() .collect(Collectors.groupingBy(Student::getName,Collectors.groupingBy(Student::getSubject))); System.out.println(8.5、Collectors.groupingBy 多字段分组-根据姓名学科分组:groups); } private static class Student{ private int id; //id private String name; //姓名 private int age; //年龄 private String subject; //学科 private float score; //分数 public Student(int id,String name,int age,String subject,float score){ this.idid; this.namename; this.ageage; this.subjectsubject; this.scorescore; } public int getId() { return id; } SuppressWarnings(unused) public void setId(int id) { this.id id; } public String getName() { return name; } SuppressWarnings(unused) public void setName(String name) { this.name name; } SuppressWarnings(unused) public int getAge() { return age; } SuppressWarnings(unused) public void setAge(int age) { this.age age; } public float getScore() { return score; } SuppressWarnings(unused) public void setScore(float score) { this.score score; } Override public String toString() { return Student [name name , subject subject , score score ]; } public String getSubject() { return subject; } SuppressWarnings(unused) public void setSubject(String subject) { this.subject subject; } Override public int hashCode() { final int prime 31; int result 1; result prime * result ((name null) ? 0 : name.hashCode()); result prime * result ((subject null) ? 0 : subject.hashCode()); return result; } Override public boolean equals(Object obj) { if (this obj) return true; if (obj null) return false; if (getClass() ! obj.getClass()) return false; Student other (Student) obj; if (name null) { if (other.name ! null) return false; } else if (!name.equals(other.name)) return false; if (subject null) { if (other.subject ! null) return false; } else if (!subject.equals(other.subject)) return false; return true; } } }