java--streams流

目录

概述

Stream操作的步骤

创建Stream

中间操作

终止操作

stream练习


概述

流是数据渠道,用于操作数据源(集合,数组等) 所生成的元素序列,集合讲究的是数据,流讲究的是计算!

  1.   stream 自己不会存储元素
  2.   stream 不会改变原来的数据对象,他会返回一个持有结果的信streams
  3.   stream 操作是延迟加载的,他们会等到需要结果的时候才会需要

Stream操作的步骤

  1. 创建Stream: 一个数据源(集合,数组),获取一个流
  2. 中间操作: 对数据源的数据进行数据处理
  3. 终止操作: 返回一个新的需要的结果

码云地址:https://gitee.com/bufanli/java8-demo.git

创建Stream

package cn.bufanli.stream;

import cn.bufanli.pojo.Employee;
import org.junit.Test;

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Stream;
/**
 * @author BuShuangLi
 * @date 2019/3/11
 * 一、Stream的操作步骤
 * 1.创建stream
 * 2.中间操作
 * 3.终止操作(产生所需要的结果)
 */
public class StreamTest01 {
     /**
      * 创建Stream的方法
      */
     @Test
     public void test02() {
          //1.可以通过Collection 系列集合提供的  串行流 -->Stream() 或 并行流-->parallelStream();
          ArrayList<String> objects = new ArrayList<>();
          Stream<String> stream = objects.stream();
          //2.通过arrays 中的静态方法
          Employee[] emps=new Employee[10];
          Arrays.stream(emps);
          //3.通过Stream类中的静态方法
          Stream<String> aa = Stream.of("aa", "bb", "cc");
          //创建无限流
          //迭代 从0 开始进行+2操作 只需要前10个如果把limit去掉就会无限的输出
          Stream<Integer> iterate = Stream.iterate(0, x -> x + 2);
          iterate.limit(10).forEach(System.out::println);
          //生成
          Stream.generate(()->Math.random()*19).limit(5).forEach(System.out::println);
     }
}

中间操作

  /**
      * 数据集合
      */
     List<Employee> employees = Arrays.asList(
              new Employee("张三", 36, 8899.99, Employee.Status.FREE),
              new Employee("李四", 25, 4499.99, Employee.Status.BUSY),
              new Employee("王五", 15, 5599.99, Employee.Status.VOCATION),
              new Employee("王五", 15, 5599.99, Employee.Status.FREE),
              new Employee("赵六", 35, 3399.99, Employee.Status.BUSY)

     );
     /*--------------------中间操作start--------------------*/

     /**
      * 中间操作
      * 内部迭代:Stream API完成
      * 筛选与切片
      * filter--接受lambda,从流中排出某些元素
      * limit--截断流,使其元素不超过指定数量
      * skip(n)--跳过元素,返回一个扔掉了n个元素的流,若流中的元素不足n个,则返回一个空流,与limit互补
      * distinct--筛选,通过流所生成的hashCode() 和equals() 去出重复元素
      */
     @Test
     public void test02() {
          //filter年龄大于38取前四个
          employees.stream()
                   //中间操作 如果没有终止操作,中间操作不会执行
                   .filter(employee -> employee.getAge() > 22)
                   //终止操作 在终止操作执行后一次性全部处理,成为惰性求值
                   .forEach(System.out::println);
          System.out.println("-----------------");

          //limit 年龄大于222 取前2个
          employees.stream().filter(e -> e.getAge() > 2).limit(2).forEach(System.out::println);
          System.out.println("-----------------");

          //skip  年龄大于2 取前四个 跳过前两个
          employees.stream().filter(e -> e.getAge() > 2).limit(4).skip(2).forEach(System.out::println);
          System.out.println("-----------------");

          //distinct 去重 通过hashCode() 和equals()来去重,需要重写实体的hashCode() 和equals()方法
          employees.stream().filter(e -> e.getAge() > 2).limit(6).skip(2).distinct().forEach(System.out::println);


     }

     /**
      * 映射
      * map--接受lambda,将元素转换为其他形式或提取信息.接受一个函数作为参数,
      * 该函数会被应用到每个元素上并将其映射成一个新的元素
      * flatMap--接受一个函数作为参数,将流中的每个值都换成另一个流,然后把所有的流连接成一个流
      */
     @Test
     public void test03() {
          List<String> strings = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
          strings.stream().map(str -> str.toUpperCase()).forEach(System.out::println);
          System.out.println("-----------------");
          employees.stream().map(Employee::getName).distinct().forEach(System.out::println);
          System.out.println("-----------------");
          Stream<Stream<Character>> streamStream = strings.stream().map(x -> getCharacterStream(x));
          streamStream.forEach(s -> {
               s.forEach(System.out::println);
          });
          System.out.println("-----------------");
          //相当于上面
          strings.stream().flatMap(x -> getCharacterStream(x)).forEach(System.out::println);
     }

     public Stream<Character> getCharacterStream(String str) {
          ArrayList<Character> strings = new ArrayList<>();
          for (Character c : str.toCharArray()) {
               strings.add(c);
          }
          return strings.stream();
     }

     /**
      * 排序
      * sorted()--自然排序(Comparable)
      * sorted(Comparator com)--定制排序
      */
     @Test
     public void test04() {
          List<String> strings = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
          //自然排序
          strings.stream().sorted().forEach(System.out::println);
          System.out.println("-----------------");
          //定制排序
          employees.stream().sorted((e1, e2) -> {
               if (e1.getAge().equals(e2.getAge())) {
                    return e1.getName().compareTo(e2.getName());
               } else {
                    return e1.getAge().compareTo(e2.getAge());
               }
          }).forEach(System.out::println);


     }
     

终止操作

/**
      * 终止操作
      */
     /**
      * 查找与匹配
      * allMatch-检查是否匹配所有元素
      * anyMatch-检查是否至少匹配一个元素
      * noneMatch-检查是否没有匹配所有元素
      * findFirst-返回第一个元素
      * findAny-返回当前流中的任意元素
      * count-返回流中元素的总个数
      * max-返回流中的最大值
      * min-返回流中最小值
      */
     @Test
     public void test05() {
          //是不是匹配所有值
          boolean b = employees.stream()
                   .allMatch(e -> e.getStatus().equals(Employee.Status.BUSY));
          System.out.println(b);
          //至少匹配一个元素
          boolean b1 = employees.stream().anyMatch(e -> e.getStatus().equals(Employee.Status.BUSY));
          System.out.println(b1);
          //没有匹配所有元素
          boolean b2 = employees.stream().noneMatch(e -> e.getStatus().equals(Employee.Status.BUSY));
          System.out.println(b2);
          //返回第一个元素   .sorted((eOne, eTwo) -> -Double.compare(eOne.getSalary()  " - " 排序的顺序
          Optional<Employee> first = employees.stream()
                   .sorted((eOne, eTwo) -> -Double.compare(eOne.getSalary(), eTwo.getSalary()))
                   .findFirst();
          System.out.println(first.get());

     }
     @Test
     public void test06(){
          //count
          System.out.println(employees.stream().count());
          //max
          Optional<Employee> max = employees.stream().max((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));
          System.out.println(max.get());
          //min
          Optional<Double> min = employees.stream().map(Employee::getSalary).min(Double::compareTo);
          System.out.println(min.get());
     }
     /**
      * 归约
      * reduce(T identity,BinaryOperator) /reduce(BinaryOperator) -可以将流中元素元素反复结合起来,得到一个值
      */
     @Test
     public void test07(){
          List<Integer> integers = Arrays.asList(1, 2, 3, 4, 5, 6, 23, 43, 66);
          Integer reduce = integers
                   .stream()
                   //先把0,作为x再从流中取出一个数据为y,然后将结果最为x再从流中去....
                   .reduce(0, (x, y) -> x + y);
          System.out.println(reduce);

          //累计算出当前工资的总和 因为没有起始值
          Optional<Double> reduce1 = employees.stream().map(Employee::getSalary).reduce(Double::sum);
          System.out.println(reduce1.get());
     }
     /**
      * 收集
      * collect--将流转换为其他形式,接受一个Collector接口实现,用于Stream中元素做汇总的方法
      */
     @Test
     public void test08(){
          //收集当前员工所有的名字收集然后放到集合当中
          List<String> collect = employees.stream().map(Employee::getName).collect(Collectors.toList());
          collect.forEach(System.out::println);
          //总和
          Double sum = employees.stream().collect(Collectors.summingDouble(Employee::getSalary));
          System.out.println(sum);
          //最大值
          Optional<Employee> max = employees.stream()
                   .collect(Collectors.maxBy((a, b) -> Double.compare(a.getSalary(), b.getSalary())));
          System.out.println(max.get());
          //最小值
          Optional<Double> min = employees.stream().map(Employee::getSalary)
                   .collect(Collectors.minBy(Double::compareTo));
          System.out.println(min.get());
          //分组
          Map<Employee.Status, List<Employee>> group = employees.stream().collect(Collectors.groupingBy(Employee::getStatus));
          System.out.println(group);
          //多几分组
          Map<Employee.Status, Map<String, List<Employee>>> groups = employees.stream()
                   .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
                        if (e.getAge() >= 35) {
                             return "青年";
                        } else if (e.getAge() <= 50) {
                             return "青年";
                        } else {
                             return "老年";

                        }
                   })));

          System.out.println(groups);
          //分区 满足条件一个区,不满足条件的一个区
          Map<Boolean, List<Employee>> collect1 = employees.stream().collect(Collectors.partitioningBy(e -> e.getSalary() > 5000));
          System.out.println(collect1);

          //获取总和 平均 ..其他方式
          DoubleSummaryStatistics collect2 = employees.stream().collect(Collectors.summarizingDouble(Employee::getSalary));
          System.out.println(collect2.getAverage());
          System.out.println(collect2.getCount());
          System.out.println(collect2.getMax());
          //.....
          //连接
          String collect3 = employees.stream()
                   .map(Employee::getName)
                   //[张三,李四,王五,王五,赵六]
                   .collect(Collectors.joining(",","[","]"));
          System.out.println(collect3);

     }

stream练习

实体类

package cn.bufanli.pojo;
//交易员类
public class Trader {

	private String name;
	private String city;

	public Trader() {
	}

	public Trader(String name, String city) {
		this.name = name;
		this.city = city;
	}

	public String getName() {
		return name;
	}

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

	public String getCity() {
		return city;
	}

	public void setCity(String city) {
		this.city = city;
	}

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

}
package cn.bufanli.pojo;
//交易类
public class Transaction {

	private Trader trader;
	private int year;
	private int value;

	public Transaction() {
	}

	public Transaction(Trader trader, int year, int value) {
		this.trader = trader;
		this.year = year;
		this.value = value;
	}

	public Trader getTrader() {
		return trader;
	}

	public void setTrader(Trader trader) {
		this.trader = trader;
	}

	public int getYear() {
		return year;
	}

	public void setYear(int year) {
		this.year = year;
	}

	public int getValue() {
		return value;
	}

	public void setValue(int value) {
		this.value = value;
	}

	@Override
	public String toString() {
		return "Transaction [trader=" + trader + ", year=" + year + ", value="
				+ value + "]";
	}

}

练习类

package cn.bufanli.stream;

import cn.bufanli.pojo.Employee;
import cn.bufanli.pojo.Trader;
import cn.bufanli.pojo.Transaction;
import org.junit.Before;
import org.junit.Test;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.Optional;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @author BuShuangLi
 * @date 2019/3/12
 */
public class StreamAPI {
     /**
      * 1.给定一个数字列表,如何返回一个由每个数的平方构成的列表,
      * 给定1,2,3,4,5 返回 2,4,9,16,25
      */
     @Test
     public void test01() {
          List<Integer> nums = Arrays.asList(1, 2, 3, 4, 5);
          ArrayList<Integer> objects = new ArrayList<>();
          List<Integer> collect = nums.stream().map(x -> x * x).collect(Collectors.toList());
          System.out.println(collect);

     }

     /**
      * 数据集合
      */
     List<Employee> employees = Arrays.asList(
              new Employee("张三", 36, 8899.99, Employee.Status.FREE),
              new Employee("李四", 25, 4499.99, Employee.Status.BUSY),
              new Employee("王五", 15, 5599.99, Employee.Status.VOCATION),
              new Employee("王五", 15, 5599.99, Employee.Status.FREE),
              new Employee("赵六", 35, 3399.99, Employee.Status.BUSY)

     );

     /**
      * 怎样用map和reduce方法数一数流中有多少个Employee
      */
     @Test
     public void test02() {
          Optional<Integer> reduce = employees.stream()
                   .map(e -> 1)
                   .reduce(Integer::sum);
          System.out.println(reduce.get());
     }

     List<Transaction> transactions = null;

     @Before
     public void before() {
          Trader raoul = new Trader("Raoul", "Cambridge");
          Trader mario = new Trader("Mario", "Milan");
          Trader alan = new Trader("Alan", "Cambridge");
          Trader brian = new Trader("Brian", "Cambridge");

          transactions = Arrays.asList(
                   new Transaction(brian, 2011, 300),
                   new Transaction(raoul, 2012, 1000),
                   new Transaction(raoul, 2011, 400),
                   new Transaction(mario, 2012, 710),
                   new Transaction(mario, 2012, 700),
                   new Transaction(alan, 2012, 950)
          );
     }

     /**
      * //1. 找出2011年发生的所有交易, 并按交易额排序(从低到高)
      */
     @Test
     public void test03() {
          List<Transaction> collect = transactions.stream().filter(t -> t.getYear() == 2011)
                   .sorted((t1, t2) -> Integer.compare(t1.getValue(), t2.getValue()))
                   .collect(Collectors.toList());
          System.out.println(collect);
     }

     /**
      * //2. 交易员都在哪些不同的城市工作过?
      */
     @Test
     public void test04() {
          List<String> collect = transactions.stream()
                   .map(t -> t.getTrader().getCity())
                   .distinct()
                   .collect(Collectors.toList());
          System.out.println(collect);

     }

     /**
      * //3. 查找所有来自剑桥的交易员,并按姓名排序
      */
     @Test
     public void test05() {
          // Cambridge
          List<Transaction> collect = transactions.stream()
                   .filter(x -> "Cambridge".equals(x.getTrader().getCity()))
                   .sorted((x, y) -> {
                        return x.getTrader().getName().compareTo(y.getTrader().getName());
                   }).distinct().collect(Collectors.toList());
          System.out.println(collect.size());
     }

     /**
      * //4. 返回所有交易员的姓名字符串,按字母顺序排序
      */
     @Test
     public void test06() {
          transactions.stream()
                   .map(x -> x.getTrader().getName())
                   .sorted()
                   .forEach(System.out::println);
          System.out.println("------------------");
          String collect = transactions.stream()
                   .map(x -> x.getTrader().getName())
                   .sorted()
                   .collect(Collectors.joining());
          System.out.println(collect);
          System.out.println("------------------");
          String collect1 = transactions.stream()
                   .flatMap(t -> filterCharacter(t.getTrader().getName()))
                   .sorted((x1, x2) -> x1.compareToIgnoreCase(x2)).collect(Collectors.joining());
          System.out.println(collect1);


     }

     public Stream<String> filterCharacter(String str){
          List<String> strings = new ArrayList<>();
          for (Character c : str.toCharArray()) {


               strings.add(c.toString());
          }
          return strings.stream();
     }
     /**
      * //5. 有没有交易员是在米兰工作的?
      */
     @Test
     public void test07() {
          boolean milan = transactions.stream().anyMatch(t -> t.getTrader().getCity().equals("Milan"));
          System.out.println(milan);
     }
     /**
      * //6. 打印生活在剑桥的交易员的所有交易额
      */
     @Test
     public void test08() {
          transactions.stream()
                   .filter(x->x.getTrader().getCity().equals("Cambridge"))
                   .map(t->t.getValue())
                   .forEach(System.out::println);

     }
     /**
      * //7. 所有交易中,最高的交易额是多少
      */
     @Test
     public void test09() {
          Optional<Integer> max = transactions.stream()
                   .map(x -> x.getValue())
                   .max((x1, x2) -> +Double.compare(x1, x2));
          System.out.println(max.get());

     }
     /**
      * //8. 找到交易额最小的交易
      */
     @Test
     public void test10() {
          Optional<Integer> min = transactions.stream()
                   .map(x -> x.getValue())
                   .min((x1, x2) -> +Double.compare(x1, x2));
          System.out.println(min.get());
          Optional<Integer> max = transactions.stream()
                   .map(x -> x.getValue())
                   .max((x1, x2) -> -Double.compare(x1, x2));
          System.out.println(max.get());

     }
}

并行流与顺序流

并行流就是把一个内容分成多块数据,并用不同的线程分别处理每个数据块的流

java 8 中进行了优化,我们可以很容易的数据对数据进行操作.,在数据量大的时候效率较高;

Stream API 可以声明性的通过parallel() 与 sequential() 在并行流与顺序流之间进行切换;底层是Frok/Join

package cn.bufanli.stream;

import org.junit.Test;

import java.time.Duration;
import java.time.Instant;
import java.util.stream.LongStream;

/**
 * @author BuShuangLi
 * @date 2019/3/12
 */
public class StreamParallel {
     /**
      * java 8 并行流
      */
     @Test
     public void test02() {
          Instant start = Instant.now();

          //顺序流
          LongStream.rangeClosed(0, 100000000000L)
                   .reduce(0, Long::sum);
          Instant end = Instant.now();
          System.out.println("串行流耗时:" + Duration.between(start, end).toMillis());
          //控制台打印--串行流耗时:133177

          Instant start2 = Instant.now();

          //并行流
          LongStream.rangeClosed(0, 100000000000L)
                   .parallel()
                   .reduce(0, Long::sum);
          Instant end2 = Instant.now();

          System.out.println("并行行流耗时:" + Duration.between(start2, end2).toMillis());
          //控制台打印--并行流耗时:73396

     }
}

猜你喜欢

转载自blog.csdn.net/adminBfl/article/details/88400948