SteamAPI

文章目录

        • 1 stream的创建
          • 1.1 通过Collection stream() 与 parallelStream()
          • 1.2 通过 Arrays 中的 静态方法stream() 获取一个数组流
          • 1.3 通过 Stream 类中静态方法 of()
          • 1.4 创建无限流(无穷)
        • 2 stream的中间操作
          • 2.1 筛选与切片
            • 2.1.1 filter:接收 Lambda , 从流中过滤某些元素。
            • 2.1.2 limit: 截断流,使其元素不超过给定数量。
            • 2.1.3 skip(n) :跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
            • 2.1.4 distinct:去重 必须重写hashCode() 和 equals() (可以生成)才能去重
          • 2.2 映射
            • 2.2.1 map 接收lamda
            • 2.2.2 flatMap 把多个流归总成一个流
            • 2.2.3 reduce
            • 2.2.4 collect
        • 3 终止操作
          • 3.1 各种查找的方法
        • 4 并行流与串行流

1 stream的创建

1.1 通过Collection stream() 与 parallelStream()
List<String> list = new ArrayList<>();
Stream<String> stream = list.stream(); //获取一个顺序流
Stream<String> parallelStream = list.parallelStream(); //获取一个并行流
1.2 通过 Arrays 中的 静态方法stream() 获取一个数组流
Integer[] nums = new Integer[10];
Stream<Integer> stream1 = Arrays.stream(nums);
1.3 通过 Stream 类中静态方法 of()
Stream<Integer> stream2 = Stream.of(1,2,3,4,5,6);
1.4 创建无限流(无穷)

流无穷无尽,一直产生,这里用了limit,就不会无限了

//迭代
Stream<Integer> stream3 = Stream.iterate(0, (x) -> x + 2).limit(10);
stream3.forEach(System.out::println);
//生成
Stream<Double> stream4 = Stream.generate(Math::random).limit(2);
stream4.forEach(System.out::println);

2 stream的中间操作

List<Employee> emps = Arrays.asList(
			new Employee(102, "李四", 59, 6666.66),
			new Employee(101, "张三", 18, 9999.99),
			new Employee(103, "王五", 28, 3333.33),
			new Employee(104, "赵六", 8, 7777.77),
			new Employee(104, "赵六", 8, 7777.77),
			new Employee(104, "赵六", 8, 7777.77),
			new Employee(105, "田七", 38, 5555.55)
	);
2.1 筛选与切片
2.1.1 filter:接收 Lambda , 从流中过滤某些元素。
 //所有的中间操作不会做任何的处理
 Stream<Employee> stream = emps.stream().filter((e) -> {
            System.out.println("测试中间操作");//先输出了这个
            return e.getAge() <= 35;//再过滤这个
  });

//只有当做终止操作时,中间操作才会执行,称为“惰性求值”
 stream.forEach(System.out::println);

效果
SteamAPI_第1张图片

2.1.2 limit: 截断流,使其元素不超过给定数量。

短路(找到满足条件的数据且数量达到给定的就不再找了)

 emps.stream().filter((e) -> {
                    System.out.println("短路!"); // &&  ||
                    return e.getSalary() >= 5000;
                }).limit(4)
                .forEach(System.out::println);

效果
SteamAPI_第2张图片

2.1.3 skip(n) :跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补
//扔掉 最先找到的2个
 emps.parallelStream()
       .filter((e) -> e.getSalary() >= 5000)
          .skip(2)
          .forEach(System.out::println);

SteamAPI_第3张图片

2.1.4 distinct:去重 必须重写hashCode() 和 equals() (可以生成)才能去重

SteamAPI_第4张图片

2.2 映射
2.2.1 map 接收lamda

接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
这里 toUpperCase这个函数应用到每个元素上,使每个元素都变为大写,最后输出结果

 List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");

        Stream<String> stream = strList.stream()
                .map(String::toUpperCase);

        stream.forEach(System.out::println);

SteamAPI_第5张图片
又比如 提取名字
SteamAPI_第6张图片

2.2.2 flatMap 把多个流归总成一个流

TestStreamAPI1.java中的一个方法

//将串变为流
public static Stream<Character> filterCharacter(String str){
		List<Character> list = new ArrayList<>();
		
		for (Character ch : str.toCharArray()) {
			list.add(ch);
		}
		
		return list.stream();
	}
 List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
      
        Stream<Stream<Character>> stream2 = strList.stream()
                .map(TestStreamAPI1::filterCharacter);
                
        stream2.forEach((sm) -> {
            sm.forEach(System.out::println);
        });

SteamAPI_第7张图片
效果同下

List<String> strList = Arrays.asList("aaa", "bbb", "ccc", "ddd", "eee");
 Stream<Character> stream3 = strList.stream()
                .flatMap(TestStreamAPI1::filterCharacter);

        stream3.forEach(System.out::println);
2.2.3 reduce
  List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
			//起始值 0 作为x ;y为list中1  累加结果为1 ;第二次x为1;y为2;依此累加
        Integer sum = list.stream()
                .reduce(0, (x, y) -> x + y);

        System.out.println(sum);//55
 List<Employee> emps = Arrays.asList(
                new Employee(102, "李四", 59, 6666.66, Employee.Status.BUSY),
                new Employee(101, "张三", 18, 9999.99, Employee.Status.FREE),
                new Employee(103, "王五", 28, 3333.33, Employee.Status.VOCATION),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.BUSY),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(105, "田七", 38, 5555.55, Employee.Status.BUSY)
        );
Optional<Double> op = emps.stream()
                .map(Employee::getSalary)
                .reduce(Double::sum);

 System.out.println(op.get());//48888.84000000001
2.2.4 collect

Employee.java以3.1中的为准
收集

List<String> list = emps.stream()
			.map(Employee::getName)
			.collect(Collectors.toList());
		
list.forEach(System.out::println);
//将名字收集起来 放在list中
    List<String> list = emps.stream()
                .map(Employee::getName)
                .collect(Collectors.toList());

     list.forEach(System.out::println);

 //将名字收集起来 放在set中
    Set<String> set = emps.stream()
             .map(Employee::getName)
             .collect(Collectors.toSet());

     set.forEach(System.out::println);
 //将名字收集起来 放在HashSet中
    HashSet<String> hs = emps.stream()
             .map(Employee::getName)
             .collect(Collectors.toCollection(HashSet::new));

     hs.forEach(System.out::println);

聚合

   // 集合数
 long count = emps.stream().collect(Collectors.counting());
   System.out.println(count);//7

    //求工资平均值
   Double avg = emps.stream().collect(Collectors.averagingDouble(Employee::getSalary));
     System.out.println(avg);
   //求工资总和
   Double sum = emps.stream() .collect(Collectors.summingDouble(Employee::getSalary));
  System.out.println(sum);//48888.84000000001
  
   Optional<Double> sum = emps.stream()
               .map(Employee::getSalary)
               .collect(Collectors.reducing(Double::sum));

       System.out.println(sum.get());//48888.84000000001
       
   //求工资最小的那个人信息
  Optional<Employee> op = emps.stream()
           .collect(Collectors.minBy((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())));

   System.out.println(op.get());
   //Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]
     
//求最大工资
   Optional<Double> max = emps.stream()
             .map(Employee::getSalary)
             .collect(Collectors.maxBy(Double::compare));

     System.out.println(max.get());//9999.99
		DoubleSummaryStatistics dss = emps.stream()
               .collect(Collectors.summarizingDouble(Employee::getSalary));

       System.out.println(dss.getMax());//9999.99

分组

 //根据状态分组
        Map<Employee.Status, List<Employee>> map = emps.stream()
                .collect(Collectors.groupingBy(Employee::getStatus));

        System.out.println(map);
    //{BUSY=[Employee [id=102, name=李四, age=59, salary=6666.66, status=BUSY], Employee [id=104, name=赵六, age=8, salary=7777.77, status=BUSY], Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]], 
    // FREE=[Employee [id=101, name=张三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE]], 
    // VOCATION=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]]}

    //先按照状态分再按照年龄分
     Map<Employee.Status, Map<String, List<Employee>>> map = emps.stream()
                .collect(Collectors.groupingBy(Employee::getStatus, Collectors.groupingBy((e) -> {
                    if(e.getAge() >= 60)
                        return "老年";
                    else if(e.getAge() >= 35)
                        return "中年";
                    else
                        return "成年";
                })));

        System.out.println(map);
      //  {VOCATION={成年=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]]}, 
        // BUSY={成年=[Employee [id=104, name=赵六, age=8, salary=7777.77, status=BUSY]], 中年=[Employee [id=102, name=李四, age=59, salary=6666.66, status=BUSY], Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]]}, 
        // FREE={成年=[Employee [id=101, name=张三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE]]}}

		//分区
 	 //按照工资分成两区
        Map<Boolean, List<Employee>> map = emps.stream()
                .collect(Collectors.partitioningBy((e) -> e.getSalary() >= 5000));
        System.out.println(map);

        //{false=[Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]], 
        // true=[Employee [id=102, name=李四, age=59, salary=6666.66, status=BUSY], Employee [id=101, name=张三, age=18, salary=9999.99, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=BUSY], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=104, name=赵六, age=8, salary=7777.77, status=FREE], Employee [id=105, name=田七, age=38, salary=5555.55, status=BUSY]]}

 //连成字符串 
     String str = emps.stream()
              .map(Employee::getName)
              .collect(Collectors.joining("," , "----", "----"));

      System.out.println(str);
      //----李四,张三,王五,赵六,赵六,赵六,田七----

3 终止操作

3.1 各种查找的方法

Employee.java(以这个实体类为准)

public class Employee {

    private int id;
    private String name;
    private int age;
    private double salary;
    private Status status;

    public Employee() {
    }

    public Employee(String name) {
        this.name = name;
    }

    public Employee(String name, int age) {
        this.name = name;
        this.age = age;
    }

    public Employee(int id, String name, int age, double salary) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
    }

    public Employee(int id, String name, int age, double salary, Status status) {
        this.id = id;
        this.name = name;
        this.age = age;
        this.salary = salary;
        this.status = status;
    }

    public Status getStatus() {
        return status;
    }

    public void setStatus(Status status) {
        this.status = status;
    }

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    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 getSalary() {
        return salary;
    }

    public void setSalary(double salary) {
        this.salary = salary;
    }

    public String show() {
        return "测试方法引用!";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result + age;
        result = prime * result + id;
        result = prime * result + ((name == null) ? 0 : name.hashCode());
        long temp;
        temp = Double.doubleToLongBits(salary);
        result = prime * result + (int) (temp ^ (temp >>> 32));
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (obj == null)
            return false;
        if (getClass() != obj.getClass())
            return false;
        Employee other = (Employee) obj;
        if (age != other.age)
            return false;
        if (id != other.id)
            return false;
        if (name == null) {
            if (other.name != null)
                return false;
        } else if (!name.equals(other.name))
            return false;
        if (Double.doubleToLongBits(salary) != Double.doubleToLongBits(other.salary))
            return false;
        return true;
    }

    @Override
    public String toString() {
        return "Employee [id=" + id + ", name=" + name + ", age=" + age + ", salary=" + salary + ", status=" + status
                + "]";
    }

    public enum Status {
        FREE, BUSY, VOCATION;
    }

}

allMatch——检查是否匹配所有元素
anyMatch——检查是否至少匹配一个元素
noneMatch——检查是否没有匹配的元素

 List<Employee> emps = Arrays.asList(
                new Employee(102, "李四", 59, 6666.66, Employee.Status.BUSY),
                new Employee(101, "张三", 18, 9999.99, Employee.Status.FREE),
                new Employee(103, "王五", 28, 3333.33, Employee.Status.VOCATION),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.BUSY),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(104, "赵六", 8, 7777.77, Employee.Status.FREE),
                new Employee(105, "田七", 38, 5555.55, Employee.Status.BUSY)
        );

        boolean bl = emps.stream()
                .allMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));

        System.out.println(bl);//false

        boolean bl1 = emps.stream()
                .anyMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));

        System.out.println(bl1);//true

        boolean bl2 = emps.stream()
                .noneMatch((e) -> e.getStatus().equals(Employee.Status.BUSY));

        System.out.println(bl2);//false

findFirst——返回第一个元素

 Optional<Employee> op = emps.stream()
                .sorted((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()))
                .findFirst();

        System.out.println(op.get());

Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]

findAny——返回当前流中的任意元素

        Optional<Employee> op2 = emps.parallelStream()//并行流,多线程同时找 谁找到算谁的 可能随机出现
                .filter((e) -> e.getStatus().equals(Employee.Status.FREE))
                .findAny();

        System.out.println(op2.get());

count——返回流中元素的总个数

  long count = emps.stream()
                .filter((e) -> e.getStatus().equals(Employee.Status.FREE))
                .count();

        System.out.println(count);//3

max——返回流中最大值

Optional<Double> op = emps.stream()
                .map(Employee::getSalary)
                .max(Double::compare);

        System.out.println(op.get());//9999.99

min——返回流中最小值

  Optional<Employee> op2 = emps.stream()
                .min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary()));

        System.out.println(op2.get());

Employee [id=103, name=王五, age=28, salary=3333.33, status=VOCATION]

注意:流进行了终止操作后,不能再次使用

        Stream<Employee> stream = emps.stream()
                .filter((e) -> e.getStatus().equals(Employee.Status.FREE));

        long count = stream.count();

        stream.map(Employee::getSalary)
                .max(Double::compare);

在这里插入图片描述

4 并行流与串行流

SteamAPI_第8张图片
继承RecursiveTask 重写compute()

import java.util.concurrent.RecursiveTask;

public class ForkJoinCalculate extends RecursiveTask<Long>{

	/**
	 * 
	 */
	private static final long serialVersionUID = 13475679780L;
	
	private long start;
	private long end;
	
	private static final long THRESHOLD = 10000L; //临界值
	
	public ForkJoinCalculate(long start, long end) {
		this.start = start;
		this.end = end;
	}
	
	@Override
	protected Long compute() {
		long length = end - start;

		if(length <= THRESHOLD){
			long sum = 0;

			for (long i = start; i <= end; i++) {
				sum += i;
			}

			return sum;
		}else{
			long middle = (start + end) / 2;

			ForkJoinCalculate left = new ForkJoinCalculate(start, middle);
			left.fork(); //拆分,并将该子任务压入线程队列

			ForkJoinCalculate right = new ForkJoinCalculate(middle+1, end);
			right.fork();

			return left.join() + right.join();
		}

	}

    public static void main(String[] args) {
	    //从10 累加到1000000
        ForkJoinCalculate f = new ForkJoinCalculate(10L,1000000L);
        System.out.println(f.compute());//500000499955
    }
}

import java.util.concurrent.ForkJoinPool;
import java.util.concurrent.ForkJoinTask;
import java.util.stream.LongStream;



public class TestForkJoin {


    public static void main(String[] args) {
        TestForkJoin t = new TestForkJoin();
        t.test1();
        t.test2();
        t.test3();



	}
	public void  test1() {
        long start = System.currentTimeMillis();

        ForkJoinPool pool = new ForkJoinPool();
        ForkJoinTask<Long> task = new ForkJoinCalculate(0L, 10000000000L);
        long sum = pool.invoke(task);
        System.out.println(sum);
        long end = System.currentTimeMillis();
        System.out.println("耗费的时间为: " + (end - start)); 


    }
    //普通for
	public void test2(){
        long start = System.currentTimeMillis();

        long sum = 0L;

        for (long i = 0L; i <= 10000000000L; i++) {
            sum += i;
        }

        System.out.println(sum);

        long end = System.currentTimeMillis();

        System.out.println("耗费的时间为: " + (end - start));
    }
	
	//并行流 方式 充分利用CPU 用时最少
	public void test3(){
		long start = System.currentTimeMillis();
		
		Long sum = LongStream.rangeClosed(0L, 10000000000L)
							 .parallel()
							 .sum();
		
		System.out.println(sum);
		
		long end = System.currentTimeMillis();
		
		System.out.println("耗费的时间为: " + (end - start));
	}

}

你可能感兴趣的:(java8)