StreamAPI

Stream API把真正的函数式变成风格引入到Java中。这是目前为止对Java类库最好的补充,因为Stream API可以极大提高Java程序员的生产力,让程序员写出高效、干净、简洁的代码。

StreamCollection集合的区别:Collection是一种静态的内存数据结构,而Stream是有关计算的。

注意:

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

创建stream

@Test
public void createStreamTest() {
    List<String> list = new ArrayList<>();
    // 创建Stream
    Stream<String> stream = list.stream();
    // 创建并行stream
    Stream<String> parallelStream = list.parallelStream();

    int[] arr = new int[10];
    // 通过数组创建stream
    IntStream intStream = Arrays.stream(arr);
    // 通过Stream.of创建stream
    Stream<Integer> integerStream = Stream.of(1, 2, 3, 4, 5);
    // 创建无限流
    Stream.iterate(0, t -> t + 2).limit(10).forEach(System.out::println);
    // 创建无限流
    Stream.generate(UUID.randomUUID()::toString).limit(10).forEach(System.out::println);
}

filter:过滤元素

@Test
public void test2() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(i);
    }
    // filter 过滤某些元素
    list.stream().filter(t -> t % 2 == 0).collect(Collectors.toList()).forEach(System.out::println);
}

limit:只收集前N个元素

@Test
public void test2() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(i);
    }
    // limit 限制元素个数
    list.stream().limit(5).forEach(System.out::println);
}

skip:跳过前N个元素

@Test
public void test2() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(i);
    }
    // skip 跳过前N个元素
    list.stream().skip(5).forEach(System.out::println);
}

distinct:去重

@Test
public void test2() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(i);
    }
    for (int i = 0; i < 10; i++) {
        list.add(i);
    }
    // distinct 去重
    list.stream().distinct().forEach(System.out::println);
}

map:映射

@Test
public void test2() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(i);
    }
    // map 映射(y = x + 2),对输入的每一个元素,做一定的处理
    list.stream().map(t -> t + 2).forEach(System.out::println);
}

flatMap: 接收一个函数作为参数,将流中的每个值都换成另一个流,然后把所有流连接成一个流

@Test
public void test4() {
    List<Person> personList = Person.getPersonList();
    // flatMap 将person的name转换后,再收集
    long count = personList.stream().flatMap(person -> {
        List<Character> list = new ArrayList<>();
        for (char c : person.getName().toCharArray()) {
            list.add(c);
        }
        return list.stream();
    }).count();
    System.out.println(count);
}

mapToIntmapToDoublemapToLong:接收一个函数作为参数,该函数会被应用到每个元素上,产生一个新的IntStreamDoubleStreamLongStream

@Test
public void test5() {
    List<String> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(String.valueOf(i));
    }
    int sum = list.stream().mapToInt(Integer::parseInt).sum();
    System.out.println(sum);
}

sorted:排序

@Test
public void test6() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(new Random().nextInt(100));
    }
    list.stream().sorted().forEach(System.out::println);
    list.stream().sorted((o1, o2) -> o2 - o1).forEach(System.out::println);
  
  	List<Person> personList = Person.getPersonList();
    personList.stream().sorted(Comparator.comparingInt(Person::getAge)).forEach(System.out::println);
    personList.stream().sorted((p1, p2) -> p2.getAge() - p1.getAge()).forEach(System.out::println);
}

查找与匹配:

@Test
public void test7() {
    List<Person> personList = Person.getPersonList();
    // 检查是否匹配所有元素
    boolean allMatch = personList.stream().allMatch(person -> person.getAge() > 0);
    System.out.println("allMatch = " + allMatch);

    // 检查是否至少匹配一个元素
    boolean anyMatch = personList.stream().anyMatch(person -> person.getAge() < 10);
    System.out.println("anyMatch = " + anyMatch);

    // 检查是否没有匹配所有元素
    boolean noneMatch = personList.stream().noneMatch(person -> person.getAge() > 100);
    System.out.println("noneMatch = " + noneMatch);

    // 返回第一个元素
    personList.stream().findFirst().ifPresent(System.out::println);
    // 返回当前流中的任意元素
    personList.stream().findAny().ifPresent(System.out::println);
}

count:返回处理后,流中的元素总数

@Test
public void countTest() {
    List<Person> personList = Person.getPersonList();
    long count = personList.stream().filter(person -> person.getAge() % 2 == 0).count();
    System.out.println("count = " + count);
}

max:返回流中的最大值

@Test
public void maxTest() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(new Random().nextInt(100));
    }
    list.stream().max(Integer::compareTo).ifPresent(System.out::println);
}

min:返回流中的最小值

@Test
public void minTest() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(new Random().nextInt(100));
    }
    list.stream().min(Integer::compareTo).ifPresent(System.out::println);
}

forEach:迭代

@Test
public void foreachTest() {
  	Person.getPersonList().stream().forEach(System.out::println);
}

reduce:计算

@Test
public void reduceTest() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(i);
    }

    System.out.println(list.stream().reduce(0, Integer::sum).intValue());

    List<Person> personList = Person.getPersonList();
    personList.stream().map(Person::getSalary).reduce(Double::sum).ifPresent(System.out::println);
    personList.stream().map(Person::getSalary).reduce((s1, s2) -> s1 + s2).ifPresent(System.out::println);
}

collector:

@Test
public void collectorTest() {
    List<Person> personList = Person.getPersonList();
    Stream<Person> personStream = personList.stream().filter(person -> person.getAge() % 2 == 0);
    personStream.collect(Collectors.toList()).forEach(System.out::println);
    personStream.collect(Collectors.toSet()).forEach(System.out::println);
}

在Collector中进行计算:

@Test
public void calcTest() {
    List<Integer> list = new ArrayList<>();
    for (int i = 0; i < 10; i++) {
        list.add(new Random().nextInt(100));
    }
    list.stream().count();
    list.stream().collect(Collectors.counting()).intValue();
    // 收集流中int属性的统计值:求和、平均值、最大、最小、个数等
    IntSummaryStatistics intSummaryStatistics = list.stream().collect(Collectors.summarizingInt(Integer::intValue));
    System.out.println(intSummaryStatistics.getSum());
    System.out.println(intSummaryStatistics.getAverage());
    System.out.println(intSummaryStatistics.getMax());
    System.out.println(intSummaryStatistics.getMin());
    System.out.println(intSummaryStatistics.getCount());

    // 计算流中元素int属性的平均值
    System.out.println(list.stream().collect(Collectors.averagingInt(Integer::intValue)).intValue());
    // 对流中元素的整数属性进行求和
    System.out.println(list.stream().collect(Collectors.summingInt(Integer::intValue)).intValue());
  
      List<Person> personList = Person.getPersonList();
    Stream<Person> stream = personList.stream();
    Map<String, List<Person>> map = stream.collect(Collectors.groupingBy(Person::getName));
    ConcurrentMap<String, List<Person>> concurrentMap = stream.collect(Collectors.groupingByConcurrent(Person::getName));
    Map<String, Person> personMap = stream.collect(Collectors.toMap(Person::getId, person -> person));
}

分组:

@Test
public void groupTest() {
    List<Person> personList = Person.getPersonList();
    Stream<Person> stream = personList.stream();
    // 分组
    Map<String, List<Person>> map = stream.collect(Collectors.groupingBy(Person::getName));
    ConcurrentMap<String, List<Person>> concurrentMap =
        stream.collect(Collectors.groupingByConcurrent(Person::getName));
}

toMap:

@Test
public void groupTest() {
    List<Person> personList = Person.getPersonList();
    Stream<Person> stream = personList.stream();
    Map<String, Person> map = stream.collect(Collectors.toMap(Person::getId, person -> person));
}

intStream:

@Test
public void intStreamTest() {
    // 左闭右开
    IntStream.range(1, 10).forEach(System.out::println);
    // 左闭右闭
    IntStream.rangeClosed(1, 10).forEach(System.out::println);
    IntStream.of(1, 2, 3).forEach(System.out::println);
    // 连接两个流
    IntStream.concat(IntStream.rangeClosed(1, 10), IntStream.rangeClosed(11, 20));
}
Logo

CSDN联合极客时间,共同打造面向开发者的精品内容学习社区,助力成长!

更多推荐