Stream流式编程实战
Posted jwnming
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Stream流式编程实战相关的知识,希望对你有一定的参考价值。
JDK8引入Stream编程
函数式接口: 函数描述符
* Runnable ()-> Void
* Callable ()-> T
接口名 方法名 函数描述符 含义
| Predicate<T> | test() | T->boolean | 判断 |
| Consumer<T> | accept() | T->void | 消费 |
| Function<T,R> | apply() | T->R | 转换 |
| Supplier<T> | get() | ()->T | 供应商 |
| BiConsumer<T,U> | accept() | (T,U)->void | 复杂特化 |
| BiFunction<T,U,R> | apply() | (T,U)->R | |
| UnaryOperator<T> | apply() | T->T | |
| IntFunction<R> | apply() | int->R | 基本类型特化 |
| ToIntFunction<T> | applyAsInt | T->int | |
Stream 函数式数据处理
Stream: 处理集合中数据的运算
集合: 负责数据的存储
(1)获得Stream
- Collection stream(): 获得单线程的Stream
- Collection parallelStream():获得并发的Stream
- Arrays.stream(T[]) Stream
- Files.lines(Path) Stream
读取文本文件,并把每行文本放入Stream
例:
Stream
Stream
(2)中间操作
方法名 操作描述
| filter(Predicate) | 对流中的数据做过滤 |
| distinct() | 去掉流中的重复元素 |
| limit(int n) | 取流中的前n个元素 |
| skip(int n) | 跳过流中的前n个元素 |
| sorted(Comparator) | 排序 |
| map(Function<T,R>) T->R | Stream<R> 对每个元素应用函数,将T对象转换为R对象存入Stream |
例子:
List<Employee> list = new ArrayList<Employee>();
//打印所有雇员中年龄有小到大排序后的地第三到第六位的名字:
list.stream().sorted(Comparator.comparingInt(Employee::getAge)).skip(2).limit(4).map(Employee::getName).forEach(System.out::println);
(3)收集操作
方法名 返回值 操作描述
| allMatch/anyMatch/noneMatch (Predicate<T>) | boolean | 判断流中的元素是否能够匹配条件 |
| count() | long | 返回流中的元素数量 |
| forEach(Consumer<T>) T->void | void | 对流中的所有元素做遍历 |
| max/min (Comparator<T>) | Optional<T> | 找出最大的元素/最小的元素 |
| findAny()/findFirst() | Optional<T> | 从流中找出任一个/第一个元素 |
| collect() | | 收集元素 |
收集操作collect() ----> 收集器 Collector<T,A,R> Collectors 直接获得Collector
T:流中的元素类型、 A:中间类型、 R:收集之后的结果类型
方法 参数 第三泛型(R) 方法描述
| counting() | 无 | Long | 统计个数 |
| summingInt() | T->int | Integer | 对整数求和 |
| averagingInt() | T->int | Double | 对整数求平均数 |
| minBy()/maxBy() | (T,T)->int | Optional<T> | 求最小/最大值 |
| summarizingInt() | T->int | IntSummaryStatistics | 统计个数,总和,平均数,最大值,最小值 |
| toList()/toSet() | 无 | List<T>/Set<T> | 将Stream中的元素放入List/Set |
| toMap() | T->K,T->U | Map<K,U> | 将Stream中的元素放入Map |
| toConcurrentMap() | T->K,T->U | ConcurrentMap<K,U> | 将Stream中的元素放入ConcurrentMap |
| joining() | 无 | String | 将Stream中的字符串拼接成String |
| collectingAndThen() | Collector<T,?,R>, R->RR | RR | 先收集数据,然后对数据做转换 |
| mapping() | T->U,Collector<U,?,R> | R | 先对元素做转换,再收集数据 |
| groupingBy() | T->K | Map<K,List<T>> | 将每个元素转换为K对象,并以K对象作为分组依据,将所有元素分组,形成Map |
| groupingBy() | T->K,Collector<T,?,D> | Map<K,D> | 分组后,再对分组结果做收集 |
| partitioningBy() | T->boolean | Map<Boolean,List<T>> | 根据谓词条件,分成2组 |
| partitioningBy() | T->boolean,Collector<T,?,D> | Map<Boolean,D> | 分区后,在对分区结果做收集 |
原始流特化
IntStream LongStream DoubleStream
获得原始特化流的方法:
- Stream
调用 mapToInt(T->int) - IntStream.range(a,b) a ---> b-1
IntStream.rangeClosed(a,b) a ---> b - IntStream.generate(()->int ) 由函数生成每个元素
- IntStream.iterate(a,int->int) 第一个元素是a,利用函数,通过前一个元迭代计算后一个元素
方法:
- average() OptionalDouble 求平均数
- sum() int 求和
- boxed() Stream
案例:
public class Stream_Student {
public static void main(String[] args) throws IOException {
// 1.读取Student.txt 将Student对象放入List中
//文件中不能有空行
List<Student> list = Files.lines(Paths.get("D:\Student.txt"), Charset.forName("GBK")).map(Student::new).collect(Collectors.toList());
// 2.统计所有学生中大于18岁的学生人数
System.out.println("-------2.统计所有学生中大于18岁的学生人数--------");
long countOfAgeUp18 = list.stream().filter((s) -> s.getAge() >= 18).count();
System.out.println(countOfAgeUp18);
// 3.打印所有学生中成绩最高的三个学生的名字
System.out.println("-------3.打印所有学生中成绩最高的三个学生的名字--------");
list.stream().sorted(Comparator.comparingDouble(Student::getScore).reversed()).limit(3).forEach((s) -> System.out.println(s.getName()));
// 4.把所有学生的名字拼成字符串,用逗号隔开 打印出来
System.out.println("-------4.把所有学生的名字拼成字符串,用逗号隔开 打印出来--------");
String nameString = list.stream().map(Student::getName).collect(Collectors.joining(","));
System.out.println(nameString);
// 5.打印所有的院系名称,要求无重复
System.out.println("-------5.打印所有的院系名称,要求无重复--------");
//list.stream().collect(Collectors.groupingBy(Student::getDept)).forEach((k, v) -> System.out.println(k));
list.stream().map(Student::getDept).distinct().forEach(System.out::println);
// 6.把每个院系的学生名字,拼成字符串,用逗号隔开, 打印出来
System.out.println("-------6.把每个院系的学生名字,拼成字符串,用逗号隔开, 打印出来--------");
list.stream().collect(Collectors.groupingBy(Student::getDept)).forEach((k, v) ->
System.out.println(v.stream().map(Student::getName).collect(Collectors.joining(","))));
// 7.打印每个院系年龄最小的学生的名字
System.out.println("-------7.打印每个院系年龄最小的学生的名字--------");
list.stream().collect(Collectors.groupingBy(Student::getDept)).forEach((k, v) ->
System.out.println(k + ":" + v.stream().sorted(Comparator.comparingInt(Student::getAge)).limit(1).
collect(Collectors.toList()).get(0).getName()) );
// 8.打印每个院系的平均成绩
System.out.println("-------8.打印每个院系的平均成绩--------");
list.stream().collect(Collectors.groupingBy(Student::getDept)).forEach((k, v) ->
System.out.println(k + ":" + v.stream().collect(Collectors.averagingDouble(Student::getScore)).doubleValue()));
// 9.打印平均成绩最高的院系的名称
System.out.println("-------9.打印平均成绩最高的院系的名称--------");
Collection<List<Student>>collection = list.stream().collect(Collectors.groupingBy(Student::getDept)).values();
Optional<Dept> optional = collection.stream().map(Dept::new).max(Comparator.comparingDouble(Dept::getAvgScore));
System.out.println(optional.get().getName() + " " + optional.get().getAvgScore());
// 10.统计每个院系考试及格和考试不及格的学生人数
System.out.println("-------10.统计每个院系考试及格和考试不及格的学生人数--------");
list.stream().collect(Collectors.groupingBy(Student::getDept)).forEach((k, v) -> {
System.out.print(k + ": ");
Map<Boolean, Long> collect = v.stream().collect(Collectors.partitioningBy((s) ->
s.getScore() >= 60,Collectors.counting()));
System.out.print("及格:" + collect.get(true) + " ");
System.out.print("不及格:" + collect.get(false));
System.out.println();
});
}
}
---------------------------------------------------------
class Dept {
private String name;
private double avgScore;
public String getName() {return name;}
public void setName(String name) { this.name = name;}
public double getAvgScore() { return avgScore;}
public void setAvgScore(double avgScore) {this.avgScore = avgScore;}
public Dept(List<Student> list) {
this.name = list.get(0).getDept();
this.avgScore = list.stream().collect(Collectors.averagingDouble(Student::getScore));
}
}
-----------------------------------------------------
class Student {
private String name;
private int age;
private double score;
private String dept; //院系
public String getName() {return name;}
public void setName(String name) { this.name = name;}
public int getAge() {return age;}
public void setAge(int age) { this.age = age;}
public double getScore() {return score; }
public void setScore(double score) {this.score = score; }
public String getDept() {return dept;}
public void setDept(String dept) { this.dept = dept;}
public Student(String s) { //构造方法,参数为读取的文本中的一行,不能有空行,不然会有空指针异常
String[] tmp = s.split("/");
this.name = tmp[0];
this.age = Integer.parseInt(tmp[1]);
this.score = Double.parseDouble(tmp[2]);
this.dept = tmp[3];
}
public String toString() {return "Student [name=" + name + ", age=" + age + ", score=" + score + ", dept=" + dept + "]";}
}
以上是关于Stream流式编程实战的主要内容,如果未能解决你的问题,请参考以下文章