JDK8新特性(二)Stream

 Java8中有两大最为重要的改变。第一个是Lambda 表达式;另外一个则是Stream API(java.util.stream.*)。
Stream 是Java8 中处理集合的关键抽象概念,它可以指定你希望对集合进行的操作,可以执行非常复杂的查找、过滤和映射数据等操作。使用Stream API 对集合数据进行操作,就类似于使用SQL 执行的数据库查询。也可以使用Stream API 来并行执行操作。简而言之,Stream API 提供了一种高效且易于使用的处理数据的方式。

流(Stream) 到底是什么呢?
    是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。“集合讲的是数据,流讲的是计算!”
注意:

  1. 无存储。stream不是一种数据结构,它只是某种数据源的一个视图,数据源可以是一个数组,Java容器或I/O channel等
  2. 为函数式编程而生。对stream的任何修改都不会修改背后的数据源,比如对stream执行过滤操作并不会删除被过滤的元素,而是会产生一个不包含被过滤元素的新stream。
  3. 惰式执行。stream上的操作并不会立即执行,只有等到用户真正需要结果的时候才会执行。
  4. 可消费性。stream只能被“消费”一次,一旦遍历过就会失效,就像容器的迭代器那样,想要再次遍历必须重新生成

Java8 中的Collection 接口被扩展,提供了两个获取流的方法:

/**
 *返回一个顺序流
 */
default Stream<E> stream() : 
/**
 *返回一个并行流
 */
default Stream<E> parallelStream() : 

 Java8 中的Arrays 的静态方法stream() 可以获取数组流:

/**
 *返回一个流
 */
static <T> Stream<T> stream(T[] array): 

 maps不支持流。然而现在maps包括了许多新的非常有用的方法用于执行通用任务,这部分内容在一篇博客中进行讲解。

创建流

    // 1、数组
    String[] arr = new String[]{"大仙", "半仙", "朱大仙"};
    Stream<String> arrStream = Arrays.stream(arr);
    // 2、集合
    List<String> list = Arrays.asList("大仙", "半仙", "朱大仙");
    Stream<String> colStream = list.stream();
    // 3、值
    Stream<String> stream = Stream.of("大仙", "半仙", "朱大仙");

下面我们准备一些数据进行说明,前期准备如下内容:

public class Test {
	/**
	 * 人的实体类
	 * @author 大仙
	 *
	 */
	@Data
	static class People{
		String name;
		Integer age;
		public People(String name, Integer age) {
			super();
			this.name = name;
			this.age = age;
		}
		
	}
	
	List<People> list = Arrays.asList(
			new People("大仙",2),
			new People("朱半仙",15),
			new People("半仙",8),
			new People("大神",10),
			new People("超神",9));
	
	public static void main(String[] args) {


	}
}

1、findFirst() :使用该方法获取第一个元素 

    /**
     * findFirst 获取第一个元素.
     */
    public void FindFirstEle(){
      People people = list.stream().findFirst().get();
      System.out.println(people);
    }

2、forEach() 方法

	/**
	 * forEach() 迭代输出每条数据.
	 */
	public void forEachEle() {
	    // java 8 前
	    System.out.println("java 8 前");
	    for(People people: list){
	      System.out.println(people);
	    }
	    // java 8 lambda
	    System.out.println("java 8 lambda");
	    list.forEach(people -> System.out.println(people));
	 
	    // java 8 stream lambda
	    System.out.println("java 8 stream lambda");
	    list.stream().forEach(people -> System.out.println(people));

	}

3、sorted() 方法:代码注释里面有详细的说明,这里就不重复赘述了,注意一点,就是stream的操作不影响原集合。

	  /**
	   * sort 排序.
	   */
	public void sortEle() {
	    System.out.println("-----排序前-----");
	    list.forEach(people -> System.out.println(people));
	    System.out.println("-----排序后-----");
	    // java 8 前
//	    System.out.println("java 8 前");
//	    Collections.sort(list, new Comparator<People>() {
//	      @Override
//	      public int compare(People o1, People o2) {
//	        return o1.getAge().compareTo(o2.getAge());
//	      }
//	    });
//	    for (People people : list) {
//	      System.out.println(people);
//	    }
	    // java 8 stream 方法引用
	    System.out.println("java 8 stream 方法引用");
	    //Java 8 中我们可以通过 "::" 关键字来访问类的构造方法,对象方法,静态方法。
	    //这里拆分说明:
//	    //获取流
//	    Stream<People> streams = list.stream();
//	    //排序,传入自定义的比较器,比较规则是people的age值
//	    streams.sorted(Comparator.comparing(People::getAge));
//	    //循环迭代
//	    streams.forEach(people -> System.out.println(people));
	    //Java 8 中我们可以通过 "::" 关键字来访问类的构造方法,对象方法,静态方法。
	    list.stream().sorted(Comparator.comparing(People::getAge)).forEach(people -> System.out.println(people));
	    System.out.println("查看原集合,注意stream的特性");
	    //原list集合是不会改变的
	    for (People people : list) {
	    	System.out.println(people);
		}
	  }

4、filter()方法,主要用来过滤出特定条件下的子集合

    /**
	 * filter方法的使用
	 */
	public  void filterEle() {
		// 输出年龄大于8的人
	    System.out.println("-----过滤前-----");
	    list.forEach(people -> System.out.println(people));
	    System.out.println("-----过滤后-----");
	    // java 8 前
	    System.out.println("java 8 前");
	    for(People people: list){
	      if (people.getAge() > 8) {
	        System.out.println(people);
	      }
	    }
	    // java 8 stream
	    System.out.println("java 8 stream");
	    list.stream().filter((People people) -> people.getAge() > 8).forEach(people->     System.out.println(people));
	}

5、anyMatch,判断集合中是否有任意一个满足条件

    /**
     * anyMatch,判断集合中是否有任意一个满足条件
     */
    public void anyMatchEle() {
    	//判断集合中是否存在年龄==8的学生
    	 // java 8 前
    	System.out.println("java 8 前");
    	boolean flag = false;
    	for (People people : list) {
			if(people.getAge()==8) {
				flag = true;
				break;
			}
		}
    	System.out.println("是否存在年龄等于8的人:"+flag);
    	 System.out.println("java 8 stream");
    	// java 8 stream
    	flag = list.stream().anyMatch(people->people.age==8);
    	System.out.println("是否存在年龄等于8的人:"+flag);
    }

6、allMatch,判断集合中是否都满足条件,和anyMatch是个互斥操作

    /**
     * allMatch,判断集合中是否都满足条件
     */
    public void allMatchEle() {
    	//	判断集合中是否所有人年龄大于2
	   	// java 8 前
	   	System.out.println("java 8 前");
	   	boolean flag = true;
	   	for (People people : list) {
			if(people.getAge()<=2) {
				flag = false;
				break;
			}
		}
	   	System.out.println("判断集合中是否所有人年龄大于2:"+flag);
	   	System.out.println("java 8 stream");
	   	// java 8 stream
	   	flag = list.stream().allMatch(people->people.age>2);
	   	System.out.println("判断集合中是否所有人年龄大于2:"+flag);
    }

7、limit():使用该方法截断

	/**
	 * limit 截断.
	 */
	public void limitEle() {
	  // 从第三个开始截断,只输出前三个
	  System.out.println("-----截断前-----");
	  list.forEach(user -> System.out.println(user));
	  System.out.println("-----截断后-----");
	  // java 8 前
	  System.out.println("java 8 前");
	  for (int i = 0; i < 3; i++) {
	    System.out.println(list.get(i));
	  }
	  // java 8 stream
	  System.out.println("java 8 stream");
	  list.stream().limit(3).forEach(people -> System.out.println(people));
	}

8、skip():与limit互斥,使用该方法跳过元素

    /**
     * skip 跳过.
     */
    public void shipEle() {
      // 跳过前三个元素,从第四个开始输出
      System.out.println("-----跳过前-----");
      list.forEach(user -> System.out.println(user));
      System.out.println("-----跳过后-----");
      // java 8 前
      System.out.println("java 8 前");
      for (int i = 3; i < list.size(); i++) {
        System.out.println(list.get(i));
      }
      // java 8 stream
      System.out.println("java 8 stream");
      list.stream().skip(3).forEach(people -> System.out.println(people));
    }

9、distinct():使用该方法去重,注意:必须重写对应泛型的hashCode()和equals()方法

    /**
     * distinct 去重.
     */
    public void distinctEle() {
      // 为list去除重复数据
      System.out.println("-----去重前-----");
      list.forEach(user -> System.out.println(user));
      System.out.println("-----去重后-----");
      // java 8 前
      System.out.println("java 8 前,本人一般的做法是转存到set集合");
      Set<People> sets = new HashSet<Test.People>();
      for (People people : list) {
    	  sets.add(people);
	  }
      for (People people : sets) {
        System.out.println(people);
      }
      // java 8 stream
      System.out.println("java 8 stream");
      list.stream().distinct().forEach(user -> System.out.println(user));
    }

10、map():接收一个方法作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素

    /**
     * map():接收一个方法作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素
     */
    public void mapEle() {
    	//获取所有人的年龄集合
    	// java 8 前
	   	System.out.println("java 8 前");
	   	List<Integer> ages = new ArrayList<Integer>();
	   	for (People people : list) {
	   		ages.add(people.getAge());
		}
	   	ages.forEach(age->System.out.println(age));
	   	System.out.println("java 8 stream");
	   	// java 8 stream
	   	ages = list.stream().map(people->people.getAge()).collect(Collectors.toList());
	   	ages.forEach(age->System.out.println(age));
    }

11、flatMapEle() 将一个stream里面的集合元素展开,使用展开之后的元素组合成一个新的stream,其实说白了就是集合合并

    /**
     * flatMapEle() 将一个stream里面的集合元素展开,使用展开之后的元素组合成一个新的stream,其实说白了就是集合合并
     */
    public void flatMapEle() {
    	List<People> list2 = Arrays.asList(new People("李四", 10),new People("王五", 10));
    	//将list1和list2合并成一个新的集合
    	// java 8 前
	   	System.out.println("java 8 前");
	   	List<People> newList = new ArrayList<Test.People>();
	   	for (People people : list) {
	   		newList.add(people);
		}
	   	for (People people : list2) {
	   		newList.add(people);
		}
	   	newList.forEach(people->System.out.println(people));
	 	// java 8 stream
	    newList = new ArrayList<Test.People>();
	   	System.out.println("java 8 stream");
	   	newList = Stream.of(list,list2).flatMap(newPeoples->newPeoples.stream()).collect(Collectors.toList());
		newList.forEach(people->System.out.println(people));
    }

12、计算统计

    /**
     * 计算统计
     */
    public void numEle() {
      //前面我们知道了map方法,map返回的是Stream,如果我们知道数据类型,让偶们可以采用mapToInt返回IntStream进行一些数据计算操作
      //IntSummaryStatistics主要用于统计整形数组中元素的最大值,最小值,平均值,个数,元素总和等等
      IntSummaryStatistics num = list.stream().mapToInt(u -> u.getAge()).summaryStatistics();
      System.out.println("总共人数:" + num.getCount());
      System.out.println("平均年龄:" + num.getAverage());
      System.out.println("最大年龄:" + num.getMax());
      System.out.println("最小年龄:" + num.getMin());
      System.out.println("年龄之和:" + num.getSum());
    }


 

猜你喜欢

转载自blog.csdn.net/zhuwei_clark/article/details/85071471