Stream API主要方法汇总

Stream

Stream 是Java8的新特性,并在后期版本进行了优化与扩展
是数据渠道,用于操作数据源(集合、数组等)所生成的元素序列。Stream 讲的是计算!

特点

  • Stream 自己不会存储元素。
  • Stream 不会改变源对象。相反,他们会返回一个持有结果的新Stream。
  • Stream 操作是延迟执行的。这意味着他们会等到需要结果的时候才执行。

Steam 执行流程:

① Steam的实例化
② Steam中间操作----对数据源的数据进行处理,是一个中间操作
③ Steam 终止操作----一旦执行终止操作,就执行中间操作,是延迟操作,并产生结果,之后不能再被使用

流的实例化方式

1:通过集合

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

2:通过数组

  •    static <T> Stream<T> stream(T[] array):
    

3:通过Stream.of()创建

  •  public static<T> Stream<T> of(T... values) :  Stream.of()
    

4:创建无限流

  •  迭代---public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)
    
  •  生成---public static<T> Stream<T> generate(Supplier<T> s)
    

5:使用Stream.builder()–构建流,需要指定类型

  •  Stream.Builder<String> add = Stream.<String>builder().add("a").add("b").add("c");
    
  •  add.build().forEach(System.out::println);
    

    6:IntStream/LongStream/DoubleStream

  • IntStream.range(1,3)
    
  • LongStream.rangeClosed(1, 3);
    
  • DoubleStream doubleStream= new Random().doubles(3);
    

7:创建一个空的流–使用静态方法Stream.empty()创建一个空的流:

  • Stream stream = Stream.empty();

单元测试


 //创建Steam的方式一:集合
    @Test
    public void test(){
        List<Employee> employees=EmployeeData.getEmployees();
        Stream<Employee> stream = employees.stream();//顺行流
        Stream<Employee> parallel = employees.stream().parallel();//并行流
        Stream<Employee> employeeStream = employees.parallelStream();//并行流
        parallel.forEach(System.out::println);
        System.out.println("*****************************");
        stream.forEach(System.out::println);

    }

    //创建Steam的方式二:数组
    @Test
    public void test1(){
        int[] arr=new  int[]{1,2,3,9};
        IntStream stream = Arrays.stream(arr);
        System.out.println("*****************************");
        stream.forEach(System.out::println);

    }

     //创建Steam的方式三:of()方法
     @Test
     public void test2(){

         Stream<Integer> integerStream = Stream.of(1, 2, 3, 6, 9);
     }

     //创建Steam的方式四:创建无限流
     @Test
     public void test3(){

      //迭代
       Stream.iterate(0,t->t+2).limit(10).forEach(System.out::println);

      //生成
     Stream.generate(Math::random).limit(10).forEachOrdered(System.out::println);

     }

     //使用Stream.builder()构建流-要指定类型
     @Test
     public  void test4(){
         Stream.Builder<String> add = Stream.<String>builder().add("a").add("b").add("c");
         add.build().forEach(System.out::println);
     }

Stream的中间操作

1 筛选与切片

  • filter(Predicate p) 接收 Lambda , 从流中排除某些元素
  • distinct() 筛选,通过流所生成元素的 hashCode() 和 equals() 去除重复元素
  • limit(long maxSize) 截断流,使其元素不超过给定数量
  • skip(long n) 跳过元素,返回一个扔掉了前 n 个元素的流。若流中元素不足 n 个,则返回一个空流。与 limit(n) 互补。

2 映射

  • map(Function f) 接收一个函数作为参数,该函数会被应用到每个元素上,并将其映射成一个新的元素。
  • mapToDouble(ToDoubleFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 DoubleStream。
  • mapToInt(ToIntFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 IntStream。
  • mapToLong(ToLongFunction f) 接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的 LongStream。
  • flatMap(Function f) 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

3 排序

  • sorted()—产生一个新的流并按自然排序
  • sorted(Comparator com)----产生一个新的流,按比较器顺序定制排序

测试类

 
public class Employee {

	private int id;
	private String name;
	private int age;
	private double salary;
	private  String sex;

	public int getId() {
		return id;
	}

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

	public String isSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	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 Employee() {
		System.out.println("Employee().....");
	}

	public Employee(int id) {
		this.id = id;
		System.out.println("Employee(int id).....");
	}

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

	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,String sex, int age, double salary) {

		this.id = id;
		this.name = name;
		this.age = age;
		this.salary = salary;
		this.sex = sex;
	}

	@Override
	public String toString() {
		return "Employee{" +
				"id=" + id +
				", name='" + name + '\'' +
				", age=" + age +
				", salary=" + salary +
				", sex=" + sex +
				'}';
	}

	@Override
	public boolean equals(Object o) {
		if (this == o)
			return true;
		if (o == null || getClass() != o.getClass())
			return false;

		Employee employee = (Employee) o;

		if (id != employee.id)
			return false;
		if (age != employee.age)
			return false;
		if (Double.compare(employee.salary, salary) != 0)
			return false;
		return name != null ? name.equals(employee.name) : employee.name == null;
	}

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

测试数据

import java.util.ArrayList;
import java.util.List;
 
 
public class EmployeeData {
	
	public static List<Employee> getEmployees(){
		List<Employee> list = new ArrayList<>();
		
		list.add(new Employee(1001, "马化腾","男",34, 6000.38));
		list.add(new Employee(1002, "马云", "男",12, 9876.12));
		list.add(new Employee(1003, "刘强东","男", 33, 3000.82));
		list.add(new Employee(1004, "雷军","男", 26, 7657.37));
		list.add(new Employee(1005, "李彦宏","男", 65, 5555.32));
		list.add(new Employee(1006, "比尔盖茨","男", 42, 9500.43));
		list.add(new Employee(1007, "任正非", "男",26, 4333.32));
		list.add(new Employee(1008, "扎克伯格", "男",35, 2500.32));
		list.add(new Employee(1009, "董明珠", "女",55, 9500.32));
		list.add(new Employee(1010, "卢忠芳", "女",85, 7500.32));
		list.add(new Employee(1011, "杨惠妍", "女",45, 2500.32));
		list.add(new Employee(1012, "孙亚芳", "女",65, 10500.32));

		return list;
	}
	
}

单元测试

 //筛选与切片
    @Test
    public void test(){
        List<Employee> list=EmployeeData.getEmployees();

        //过滤流--接收 Lambda,从流中排除某些元素
        list.stream().filter(e->e.getSalary()>7000).forEach(System.out::println);

        System.out.println("************************");
        //截断流--使元素不超过指定数量
        list.stream().limit(3).forEach(System.out::println);
        System.out.println("************************");
        //跳过元素--若流中元素不足 n 个,则返回一个空流。与limit()方法互补
        list.stream().skip(3).forEach(System.out::println);

        //筛选--通过流所生成元素的 hashCode() 和 equals() 去除重复元素
        System.out.println("************************");
        list.add(new Employee(1012,"刘强东",40,8522.00));
        list.add(new Employee(1012,"刘强东",40,8522.00));
        list.add(new Employee(1012,"刘强东",40,8522.00));
        list.stream().distinct().forEach(System.out::println);
    }

   //映射
    @Test
    public  void test1(){

        //map操作
        String[] strings=new String[]{"a","b","c","d"};
        Arrays.stream(strings).map(String::toUpperCase).forEach(System.out::println);
        System.out.println("************************");
        //获取员工姓名长度大于3的姓名--先过滤按长度过滤名字的对象,然后映射出名字
        List<Employee> list=EmployeeData.getEmployees();
        list.stream().filter(e->e.getName().length()>3).map(Employee::getName).forEach(System.out::println);

        //flatMap--流扁平化处理--接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流
        //常常用来处理流里面嵌套流的处理
        System.out.println("************************");
        Arrays.stream(strings).flatMap(StreamCenterOptionTest::fromStringStream).forEach(System.out::println);
    }

    public  static Stream<Character> fromStringStream(String str){
        ArrayList<Character> list=new ArrayList<>();
        for (Character character : str.toCharArray()) {
            list.add(character);
        }
        return  list.stream();
    }

    //排序
    @Test
    public void test2(){
        //sorted()---自然排序
        List<Integer> list = Arrays.asList(12, 43, 65, 34, 87, 0, -98, 7);
        list.stream().sorted().forEach(System.out::println);

        System.out.println("************************");

      //sorted(Comparator com)——定制排序
        List<Employee> employees = EmployeeData.getEmployees();
        employees.stream().sorted( (e1,e2) -> {

            int ageValue = Integer.compare(e1.getAge(),e2.getAge());
            if(ageValue != 0){
                return ageValue;
            }else{
                return -Double.compare(e1.getSalary(),e2.getSalary());
            }

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

Stream 的终止操作

1 匹配与查找

终端操作会从流的流水线生成结果。其结果可以是任何不是流的值;流进行了终止操作后,不能再次使用。

  • allMatch(Predicate p) 检查是否匹配所有元素
  • anyMatch(Predicate p) 检查是否至少匹配一个元素
  • noneMatch(Predicate p) 检查是否没有匹配所有元素
  • findFirst() 返回第一个元素
  • findAny() 返回当前流中的任意元素
  • count() 返回流中元素总数
  • max(Comparator c) 返回流中最大值
  • min(Comparator c) 返回流中最小值
  • forEach(Consumer c)内部迭代(使用 Collection 接口需要用户去做迭代,称为外部迭代。相反,Stream API 使用内部迭代——它帮你把迭代做了)
  • 此迭代是并行的效率高
  • forEachOrdered(Consumer c)内部迭代–按顺序迭代,此迭代是顺行的,效率较低

2- 归约

  • reduce(T iden, BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回 T
  • reduce(BinaryOperator b)可以将流中元素反复结合起来,得到一个值。返回 Optional
    备注:map 和 reduce 的连接通常称为 map-reduce 模式,因 Google用它来进行网络搜索而出名。

3-收集

  • Collector 接口中方法的实现决定了如何对流执行收集的操作(如收集到 List、Set、Map)。
    另外, Collectors 实用类提供了很多静态方法,可以方便地创建常见收集器实例,
  • collect(Collector c)将流转换为其他形式。接收一个 Collector接口的实现,用于给Stream中元素做汇总的方法

单元测试

  //匹配与查找
    @Test
    public  void test(){
      //allMatch()--检查是否匹配所有元素
        List<Employee> employees = EmployeeData.getEmployees();
        boolean b = employees.stream().allMatch(e -> e.getAge() > 18);
        System.out.println(b);
        System.out.println("**********************");
        //anyMatch()--检查是否匹配一个元素
        boolean b1 = employees.stream().anyMatch(e -> e.getSalary() > 5000);
        System.out.println(b1);
        System.out.println("**********************");
        //noneMatch()--检查是否没有匹配元素
        boolean b2 = employees.stream().noneMatch(e ->e.getName().startsWith("刘"));
        System.out.println(b2);
        System.out.println("**********************");
        //findFirst()--返回流的第一个元素
         employees.stream().findFirst().ifPresent(System.out::println);
        System.out.println("**********************");
        //findAny()---返回当前流中的任意元素
        //非并行流中,在大多数情况下,两者都可能返回流的第一个元素,但是findAny()不提供此行为的任何保证。使用findAny()可以更快地从任何并行流中获取任何元素
        Employee employee = employees.parallelStream().findAny().orElse(null);
        System.out.println(employee);
        System.out.println("**********************");
        // count——返回流中元素的总个数
        long count = employees.stream().filter(e -> e.getSalary() > 5000).count();
        System.out.println(count);
        System.out.println("**********************");
        //max(Comparator c)——返回流中最大值--返回最高的工资
        Optional<Double> max = employees.stream().map(Employee::getSalary).max(Double::compare);
        System.out.println(max.orElse(null));
        System.out.println("**********************");
        //min(Comparator c)——返回流中最小值--返回最低工资的员工
        employees.stream().min(Comparator.comparingDouble(Employee::getSalary)).ifPresent(System.out::println);

    }

    //归约
    @Test
    public void test1(){
    //归约可以将流中元素反复结合起来,得到一个值。返回 T,经常和map映射操作搭配使用

        int[] list=new int[]{1,2,3,8,0,78};

        int reduce = Arrays.stream(list).reduce(0, Integer::sum);
        System.out.println(reduce);
        System.out.println("**********************");
        List<Employee> employees = EmployeeData.getEmployees();
        //employees.stream().map(Employee::getSalary).reduce(Double::sum).ifPresent(System.out::println);
        employees.stream().map(Employee::getSalary).reduce((d1,d2)->d1+d2).ifPresent(System.out::println);

    }
    //收集
    @Test
    public void test2(){
        List<Employee> employees = EmployeeData.getEmployees();
        employees.stream().filter(e->e.getSalary()>6000).collect(Collectors.toList()).forEach(System.out::println);
        System.out.println("**********************");
        employees.stream().filter(e->e.getSalary()>6000).collect(Collectors.toSet()).forEach(System.out::println);
    }

Collector 接口中方法:

  • 1 List toList() 把流中元素收集到List
    举例: List<Employee> emps= list.stream().collect(Collectors.toList());

  • 2 Set toSet() 把流中元素收集到Set
    举例: Set<Employee> emps= list.stream().collect(Collectors.toSet());

  • 3 Collection toCollection() 把流中元素收集到创建的集合
    举例: Collection<Employee>emps=list.stream().collect(Collectors.toCollection(ArrayList::new));

  • 4 Long counting() 计算流中元素的个数
    举例: long count = list.stream().collect(Collectors.counting());

  • 5 Integer summingInt() 对流中元素的整数属性求和
    举例: int total=list.stream().collect(Collectors.summingInt(Employee::getAge));

  • 6 Double averagingInt() 计算流中元素Integer属性的平均值
    举例: double avg = list.stream().collect(Collectors.averagingInt(Employee::getAge));

  • 7 IntSummaryStatistics summarizingInt() 收集流中Integer属性的统计值。如:平均值
    举例: int SummaryStatisticsiss= list.stream().collect(Collectors.summarizingInt(Employee::getAge));

    1. String joining() String 连接流中每个字符串
      举例:String str= list.stream().map(Employee::getName).collect(Collectors.joining());
      举例:String str= list.stream().map(Employee::getName).collect(Collectors.joining(",", "{", "}")));
      举例:String str= list.stream().map(Employee::getName).collect(Collectors.joining(","));
  • 9: Optional maxBy() 根据比较器选择最大值
    举例:Optional<Emp>max= list.stream().collect(Collectors.maxBy(Comparator.comparingDouble(Employee::getSalary)));

  • 10:Optional minBy() 根据比较器选择最小值
    举例:Optional<Emp> min = list.stream().collect(Collectors.minBy(Comparator.comparingDouble(Employee::getSalary)));

  • 11:reducing() 从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值
    举例: int total=list.stream().collect(Collectors.reducing(0, Employee::getAge, Integer::sum));

  • 12:collectingAndThen() 转换函数返回的类型 包裹另一个收集器,对其结果转换函数
    举例:int how= list.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size));

  • 13:Map<K, List> groupingBy() 根据某属性值对流分组,属性为K,结果为V
    举例:Map<String, List<Employee>> map= list.stream().collect(Collectors.groupingBy(Employee::getName));

  • 14:Map<Boolean, List> partitioningBy() 收集后根据true或false进行分区
    举例: employees.stream().collect(Collectors.partitioningBy(employee -> employee.getSalary()>8000, Collectors.mapping(Employee::getName,Collectors.counting()))).forEach((Key, value)-> System.out.println(Key+"----"+value));

  • 15:mapping()方法会将结果应用到另一个收集器上。
    举例:employees.stream().collect(Collectors.partitioningBy(employee -> employee.getSalary()>8000, Collectors.mapping(Employee::getName,Collectors.toList()))).forEach((Key, value)-> System.out.println(Key+"----"+value));

  • 16:flatMapping()–类似于Collectors.mapping() 方法,但粒度更细。两者都带一个函数和一个收集器参数用于收集元素,但flatMapping函数接收元素流,然后通过收集器进行累积操作,一般用于collect()里对嵌套流的处理

  • 17:filtering()–类似Stream filter()方法,用于过滤输入元素,常和groupingBy/partitioningBy搭配使用

  • 18:toUnmodifiableMap()–将元素聚集到一个不可修改的Map,Map中的对象地址不可修改,里面的对象若支持修改的话,其实也还是可以修改的。

  • 19:toUnmodifiableSet()—将元素聚集到一个不可修改的HashSet

  • 20:toMap()—将元素聚集到一个map中

  • 21:toConcurrentMap()—将元素聚集到一个支持并发的concurrentHashMap中

  • 22:toUnmodifiableList()—将元素聚集到一个不可修改的ArrayList

  • 23:groupingByConcurrent()—类似groupingBy(),但其聚集的集合是concurrentHashMap支持并发,可以提高并行流分组的效率

  • 24:teeing()–返回一个由两个下游收集器组成的收集器。传递给生成的收集器的每个元素都由下游收集器处理,然后使用指定的合并函数将它们的结果合并到最终结果中。
    支持使用两个独立的收集器收集流,然后使用提供的双功能合并结果。

单元测试

 //Collectors methods
    @Test
    public void test3() {
        List<Employee> employees = EmployeeData.getEmployees();

        //Collectors.reducing()--从一个作为累加器的初始值开始,利用BinaryOperator与流中元素逐个结合,从而归约成单个值
        int total = employees.stream().collect(Collectors.reducing(0, Employee::getAge, Integer::sum));
        System.out.println(total);

        System.out.println("**********************");
        //Collectors.collectingAndThen()--转换函数返回的类型 包裹另一个收集器,对其结果转换函数
        int how = employees.stream().collect(Collectors.collectingAndThen(Collectors.toList(), List::size));
        System.out.println(how);

        System.out.println("**********************");
        //Collectors.groupingBy()---分组
        Map<String, Long> collect = employees.stream().collect(Collectors.groupingBy(e -> {
            if (e.getAge() > 60)
                return "老年人";
            else if (e.getAge() > 40)
                return "中年人";
            else
                return "青年人";

        }, Collectors.counting()));

        collect.forEach((Key, value) -> System.out.println(Key + "----" + value));
        System.out.println("**********************");

        //Collectors.partitioningBy() 收集后根据true或false进行分区
        // Collectors.mapping() 方法会将结果应用到另一个收集器上。
        //----按工资大于8000的用户进行分组,分成2组,大于8000的为true,小于的为false并映射出姓名放入list集合中
        employees.stream().collect(Collectors.partitioningBy(employee -> employee.getSalary() > 8000, Collectors.mapping(Employee::getName, Collectors.toList()))).forEach((Key, value) -> System.out.println(Key + "----" + value));

        System.out.println("**********************");
        //Collectors.filtering()--过滤输出元素--按男女分组过滤出工资大于5000的员工姓名
        employees.stream().collect(Collectors.groupingBy(Employee::isSex, Collectors.filtering(employee -> employee.getSalary() > 5000, Collectors.mapping(Employee::getName, Collectors.toList())))).forEach((Key, value) -> System.out.println(Key + "----" + value));

        System.out.println("**********************");
        //Collectors.flatMapping()--对collect里嵌套流的处理
        employees.stream().collect(Collectors.partitioningBy(employee -> employee.getSalary() > 8000, Collectors.flatMapping(s -> Stream.of(s.getName()), Collectors.joining(";", "{", "}")))).forEach((Key, value) -> System.out.println(Key + "----" + value));

        System.out.println("**********************");
        //Collectors.groupingByConcurrent()--并行分组处理
        employees.stream().collect(Collectors.groupingByConcurrent(Employee::isSex, Collectors.counting())).forEach((Key, value) -> System.out.println(Key + "----" + value));
        System.out.println("**********************");

        //Collectors.toUnmodifiableSet()--将元素聚集到一个不可修改的HashSet
        employees.stream().collect(Collectors.mapping(Employee::getName, Collectors.toUnmodifiableSet())).forEach(System.out::println);
        System.out.println("**********************");

        //Collectors.toUnmodifiableList()--将元素聚集到一个不可修改的ArrayList
        employees.stream().map(Employee::getName).collect(Collectors.toUnmodifiableList()).forEach(System.out::println);
        System.out.println("**********************");

        //Collectors.toUnmodifiableMap()--将元素聚集到一个不可修改的HashMap
        employees.stream().collect(Collectors.toUnmodifiableMap(Employee::getId, employee -> {
            List<Employee> employeeList = new ArrayList<>();
            employeeList.add(employee);
            return employeeList;
        })).forEach((Key, value) -> System.out.println(Key + "----" + value));

        System.out.println("**********************");
        //Collectors.teeing()-返回一个由两个收集器组成的收集器。传递给生成的收集器的每个元素都由两个子收集器处理,然后使用指定的合并函数将它们的结果合并到最终结果中。
        Double collect1 = employees.stream().collect(Collectors.teeing(Collectors.averagingDouble(Employee::getSalary),Collectors.summingDouble(Employee::getSalary),Double::max));
        System.out.println(collect1);

    }

流的其他操作

  • concat()–
    此方法创建一个延迟连接的流,其元素是firstStream的所有元素,后跟secondStream的所有元素。 如果两个输入流都是有序的,则对所得到的流进行排序。如果任一输入流是并行的,则得到的流是平行的。
  • peek()(Consumer<? super T> action)-------stream.peek的操作是返回一个新的stream的,主要是用来debug调试的,因此使用steam.peek()必须对流进行一次处理再产生一个新的stream
  • ofNullable(T t)-如果此流不为null,则ofNullable(T)方法将返回包含单个元素的顺序Stream,否则该方法将返回空Stream。
  • takeWhile()(Predicate<? super T> predicate)–takeWhile() 方法使用一个断言作为参数,获取满足断言条件的元素直到断言为false为止。丢弃后面的元素,如果第一个值不满足断言条件,将返回一个空的 Stream。
  • dropWhile()(Predicate<? super T> predicate)—dropWhile 方法和 takeWhile 作用相反的,使用一个断言作为参数,从Stream中依次删除满足断言条件的元素,直到不满足条件为止结束删除

Spliterator接口
–Spliterator用来遍历和分割序列,它是为了并行执行而设计的;集合实现了 Spliterator 接口,提供了一个 spliterator()方法

  • tryAdvance() 方法的行为类似于普通的 Iterator ,因为它会按顺序一个一个使用 Spliterator 中的元素,并且如果还有其他元素要遍历就返回 true,否则返回false
  • trySplit() --Spliterator最核心的方法;把一些元素划出去分给第二个 Spliterator (由该方法返回且装载已分割的元素),分割的Spliterator被用于每个子线程进行处理,从而达到并发处理的效果。当分割器Spliterator不能继续分割,则返回null。
    如果两个或多个线程在同一个spliterator上并发运行,则拆分和遍历的行为是不确定的。如果原始线程将一个spliterator移交给另一个线程进行处理,最好是在使用tryAdvance()消费任何元素之前进行切换
    理想的trySplit()方法有效地(无遍历)将其元素精确地分成两半,允许平衡并行计算。许多偏离这种理想仍然非常有效;
  • forEachRemaining()–在当前线程中串行对剩余元素执行迭代操作,直到所有元素都被处理或抛出异常。 如果是串行的,则按相关顺序执行操作。异常被转发给调用者。
  • estimateSize()—该接口是返回forEachRemaining遍历所遇到的元素数量的估计值,如果为无穷大,未知数或计算成本太高,则返回Long.MAX_VALUE。

单元测试

 //Stream other methods test
    @Test
    public void test4(){
       //concat()--两个数字类型的stream进行合并
        Stream<Integer> resultingStream = Stream.concat(Stream.of(1, 2, 3), Stream.of(4, 5, 6));
        System.out.println("**********************");

        //peek()
        Stream.of("one", "two", "three","four").filter(e -> e.length() > 3)
                .peek(e -> System.out.println("Filtered value: " + e))
                .map(String::toUpperCase)
                .peek(e -> System.out.println("Mapped value: " + e))
                .collect(Collectors.toList());
        System.out.println("**********************");

        //takeWhile()方法使用一个断言作为参数,获取满足断言条件的元素直到断言为false为止。丢弃后面的元素,如果第一个值不满足断言条件,将返回一个空的 Stream。
        Stream.of("a","b","c","","e","f").takeWhile(s->!s.isEmpty()).forEach(System.out::print);
        System.out.println();
        System.out.println("**********************");
        //dropWhile方法和takeWhile方法作用相反的,使用一个断言作为参数,从Stream中依次删除满足断言条件的元素,直到不满足条件为止结束删除
        Stream.of("a","b","c","","e","f").dropWhile(s->!s.isEmpty()).forEach(System.out::print);
        System.out.println();
        System.out.println("**********************");

        //spliterator().tryAdvance()
        Arrays.asList("leo", "ben", "jack").spliterator().tryAdvance(System.out::println);
        System.out.println("**********************");

        //spliterator().trySplit()---支持并发
        ArrayList<Integer> list = new ArrayList<>();
        for (int i = 0; i < 20; i++) list.add(i + 1);
        Spliterator<Integer> spliterator1  = list.spliterator();//spliterator1 有20个元素(1-20)
        Spliterator<Integer> spliterator2 = spliterator1.trySplit(); //spliterator1中有10个元素(11-20),spliterator2中有10个元素(1-10)
        Spliterator<Integer> spliterator3 = spliterator1.trySplit(); //spliterator1中有5个元素(16-20),spliterator2中有10个元素(1-10),spliterator3中有5个元素(11-15)
        Spliterator<Integer> spliterator4 = spliterator2.trySplit();//spliterator1中有5个元素(16-20),spliterator2中有5个元素(6-10);spliterator3中有5个元素(11-15),spliterator4中有5个元素(1-5)
        Spliterator<Integer> spliterator5 = spliterator2.trySplit();//spliterator1中有5个元素(16-20),spliterator2中有3个元素(8-10);spliterator3中有5个元素(11-15),spliterator4中有5个元素(1-5),spliterator5中有2个元素(6-7)

        int i = 1;
        for (Spliterator<Integer> numThread : Arrays.asList(spliterator1, spliterator2,spliterator3,spliterator4,spliterator5)) {
            Thread thread = new Thread(() -> numThread.forEachRemaining(System.out::println));
            thread.setName("spliterator"+i);
            System.out.println("剩余元素个数:"+numThread.getExactSizeIfKnown());
            System.out.println("该对象具有的特征值:"+numThread.characteristics());
            //如果Spliterator的list是通过Comparator排序的,则返回Comparator
            //如果Spliterator的list是自然排序的 ,则返回null
            //其他情况下抛错
            //System.out.println("返回该对象的比较器:"+numThread.getComparator());
            thread.start();
            try {
                thread.join();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(thread.getName()+"---------------------------");
            i++;
        }
    }
  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值