zoukankan      html  css  js  c++  java
  • 【Java】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

    1. Collection stream(): 获得单线程的Stream
    2. Collection parallelStream():获得并发的Stream
    3. Arrays.stream(T[]) Stream
    4. Files.lines(Path) Stream 读取文本文件,并把每行文本放入Stream

    例:
    Stream s = Files.lines(Paths.get("a.txt")); 、、处理英文
    Stream s = Files.lines(Paths.get("a.txt") , Charset.forName("GBK")); 处理中文

    (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
    获得原始特化流的方法:

    1. Stream 调用 mapToInt(T->int)
    2. IntStream.range(a,b) a ---> b-1
      IntStream.rangeClosed(a,b) a ---> b
    3. IntStream.generate(()->int ) 由函数生成每个元素
    4. 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 + "]";}
    }
    
  • 相关阅读:
    内部类
    三大修饰符:static、final、abstract
    面向对象三大特性
    类和方法
    Vue-创建工程+element UI
    xshell连接虚拟机较慢问题 -----已解决
    Hbase配置
    Hive的安装配置
    Hive内容+配置
    Redis全局命令
  • 原文地址:https://www.cnblogs.com/jwnming/p/13093826.html
Copyright © 2011-2022 走看看