Java基础知识复习(十四)-- 集合的聚合操作

Stream和管道的概念

要了解聚合操作,首先要建立Stream和管道的概念,Stream 和Collection结构化的数据不一样,Stream是一系列的元素,就像是生产线上的罐头一样,一串串的出来。管道指的是一系列的聚合操作。

管道又分3个部分

管道源:源是一个List

中间操作: 每个中间操作,又会返回一个Stream,比如.filter()又返回一个Stream,
中间操作是“懒”操作,并不会真正进行遍历。

管道源

把Collection切换成管道源很简单,调用stream()就行了。

中间操作主要分两类

1)对元素进行筛选:

  1. filter 匹配
  2. distinct 去除重复(根据equals判断)distinct 去除重复(根据equals判断)
  3. sorted 自然排序sorted 自然排序
  4. sorted(Comparator) 指定排序sorted(Comparator) 指定排序
  5. limit 保留limit 保留
  6. skip 忽略skip 忽略

2)转换为其他形式的流

  1. mapToDouble 转换为double的流
  2. map 转换为任意类型的流map 转换为任意类型的流.

结束操作

结束操作:当这个操作执行后,流就被使用“光”了,无法再被操作。所以这必定是流的最后一个操作。
结束操作不会返回Stream,但是会返回int、float、String、 Collection或者像forEach,什么都不返回,
结束操作才进行真正的遍历行为,在遍历的时候,才会去进行中间操作的相关判断
常见结束操作如下:

  1. forEach() 遍历每个元素
  2. toArray() 转换为数组
  3. min(Comparator) 取最小的元素
  4. max(Comparator) 取最大的元素
  5. count() 总数
  6. findFirst() 第一个元素

注: 这个Stream和I/O章节的InputStream,OutputStream是不一样的概念。

测试代码(中间操作)

Hero.java

package stack;

public class Hero {
	private String name;
	private float hp;
	
	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}

	public Hero(String name, float hp) {
		super();
		this.name = name;
		this.hp = hp;
	}

	public float getHp() {
		return hp;
	}

	public void setHp(float hp) {
		this.hp = hp;
	}

	@Override
	public String toString() {
		return "[name=" + name + ", hp=" + hp + "]";
	}
	
	
}

package review5;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import stack.Hero;

public class TestAggregate {
	public static void main(String[] args) {
		  Random r = new Random();
	        List<Hero> heros = new ArrayList<Hero>();
	        for (int i = 0; i < 5; i++) {
	            heros.add(new Hero("hero " + i, r.nextInt(1000)));
	        }
	        //制造一个重复数据
	        heros.add(heros.get(0));
	        System.out.println("初始化集合后的数据 (最后一个数据重复):");
	        System.out.println(heros);
	        System.out.println("满足条件hp>100的数据");
	          
	        heros
	            .stream()
	            .filter(h->h.getHp()>100)
	            .forEach(h->System.out.print(h));
	        System.out.println();
	        System.out.println("去除重复的数据,去除标准是看equals");
	        heros
	            .stream()
	            .distinct()
	            .forEach(h->System.out.print(h));
	        System.out.println();
	        System.out.println("按照血量排序");
	        heros
	            .stream()
	            .sorted((h1,h2)->h1.getHp()>=h2.getHp()?1:-1)
	            .forEach(h->System.out.print(h));
	       System.out.println();   
	        System.out.println("保留3个");
	        heros
	            .stream()
	            .limit(3)
	            .forEach(h->System.out.print(h));
	         System.out.println();
	        System.out.println("忽略前3个");
	        heros
	            .stream()
	            .skip(3)
	            .forEach(h->System.out.print(h));
	        System.out.println();
	        System.out.println("转换为double的Stream");
	        heros
	            .stream()
	            .mapToDouble(Hero::getHp)
	            .forEach(h->System.out.println(h));
	        System.out.println();
	        System.out.println("转换任意类型的Stream");
	        heros
	            .stream()
	            .map((h)-> h.getName() + " - " + h.getHp())
	            .forEach(h->System.out.println(h));
	}
}

测试代码(结束操作)

package review5;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Random;

import stack.Hero;

public class TestAggregate {
	public static void main(String[] args) {
		 Random r = new Random();
	        List<Hero> heros = new ArrayList<Hero>();
	        for (int i = 0; i < 5; i++) {
	            heros.add(new Hero("hero " + i, r.nextInt(1000)));
	        }
	        System.out.println("遍历集合中的每个数据");
	        heros
	            .stream()
	            .forEach(h->System.out.print(h));
	        System.out.println();
	        System.out.println("返回一个数组");
	        Object[] hs= heros
	            .stream()
	            .toArray();
	        System.out.println(Arrays.toString(hs));
	        System.out.print("返回血量最低的那个英雄:");
	        Hero minHpHero =
	        heros
	            .stream()
	            .min((h1,h2)->(int)h1.getHp() - (int)h2.getHp())
	            .get();
	        System.out.println(minHpHero);
	        System.out.print("返回血量最高的那个英雄:");
	 
	        Hero maxHpHero =
	                heros
	                .stream()
	                .max((h1,h2)->(int)h1.getHp()-(int)h2.getHp())
	                .get();
	        System.out.println(maxHpHero);     
	         
	        System.out.print("流中数据的总数:");
	        long count = heros
	                .stream()
	                .count();
	        System.out.println(count);
	 
	        System.out.print("第一个英雄:");
	        Hero firstHero =
	                heros
	                .stream()
	                .findFirst()
	                .get();
	         
	        System.out.println(firstHero);
	}
}

练习-聚合操作

首先准备10个Hero对象,hp是随机数。
分别用传统方式和聚合操作的方式,把hp第三高的英雄名称打印出来

package review5;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Random;
import java.util.stream.Stream;

import stack.Hero;

public class TestAggregate {
	public static void main(String[] args) {
		 Random r = new Random();
	        List<Hero> heros = new ArrayList<Hero>();
	        for (int i = 0; i < 10; i++) {
	            heros.add(new Hero("hero " + i, r.nextInt(1000)));
	        }
	        //聚合操作的方式,把hp第三高的英雄名称打印出来
	        heros.stream()
	        .sorted((h1,h2) -> h1.getHp() > h2.getHp() ? -1 :h1.getHp() < h2.getHp() ? 1 : 0 )
	        	.forEach(h -> System.out.println(h));
	        
	       Stream<Hero> hero = heros.stream()
	    		 //倒排
	       		.sorted((h1,h2) -> h1.getHp() > h2.getHp() ? -1 :h1.getHp() < h2.getHp() ? 1 : 0 )
	       		//忽略前两个
	       		.skip(2);

	       System.out.println("聚合操作的方式,把hp第三高的英雄名称打印出来:"+hero.findFirst());	
	       
	       //传统操作的方式,把hp第三高的英雄名称打印出来
	       Collections.sort(heros,(h1,h2) -> h1.getHp() > h2.getHp() ? -1 :h1.getHp() < h2.getHp() ? 1 : 0 );
	       System.out.println("传统操作的方式,把hp第三高的英雄名称打印出来:"+heros.get(2));
	       
	}
}

你可能感兴趣的:(Java基础)