Home Java8(二):Stream
Post
Cancel

Java8(二):Stream

Stream是什么

Stream 不是集合元素,它不是数据结构并不保存数据,它是有关算法和计算的,它更像一个高级版本的 Iterator。原始版本的 Iterator,用户只能显式地一个一个遍历元素并对其执行某些操作;高级版本的 Stream,用户只要给出需要对其包含的元素执行什么操作,比如 “过滤掉长度大于 10 的字符串”、“获取每个字符串的首字母”等,Stream 会隐式地在内部进行遍历,做出相应的数据转换。

很多流操作本身就会返回一个流,所以多个操作可以直接连接起来。

Stream方法

1、stream()

将集合转换为流

1
2
List<String> list = Arrays.asList("Army", "Luna", "Elle", "Katherine");
Stream<String> stream = list.stream();

2、filter(T -> boolean)

保留lambda结果为true的元素

1
2
3
list = list.stream()
           .filter(name -> name.length() > 4)
           .collect(toList());

3、distinct()

去除重复元素,以类的equals方法作为判据

1
2
3
list = list.stream()
           .distinct()
           .collect(toList());

4、sorted() / sorted((T, T) -> int)

如果流中的元素的类实现了 Comparable 接口,即有自己的排序规则,那么可以直接调用 sorted() 方法对元素进行排序,如 Stream

否则, 需要调用 sorted((T, T) -> int) 实现 Comparator 接口。

1
2
3
list = list.stream()
           .sorted((p1, p2) -> p1.length() - p2.length())
           .collect(toList());

5、limit(long n)

返回前n个元素

1
2
3
list = list.stream()
           .limit(2)
           .collect(toList());

6、skip(long n)

去除前n个元素

1
2
3
list = list.stream()
            .skip(2)
            .collect(toList());

7、map(T -> R)

将流中的每一个元素T映射为R

1
List<String> newlist = list.stream().map(Person::getName).collect(toList());

8、flatMap(T -> Stream)

flat意思是:展平。把流中的每一个元素T转化为流,再合并为一个流。

1
2
3
4
5
6
7
8
9
List<String> list = new ArrayList<>();
list.add("aaa bbb ccc");
list.add("ddd eee fff");
list.add("ggg hhh iii");

list = list.stream()
           .map(s -> s.split(" "))
           .flatMap(Arrays::stream)
           .collect(toList());

9、anyMatch(T -> boolean)

流中是否有一个元素匹配给定条件。

1
boolean b = list.stream().anyMatch(person -> person.getAge() == 20);

10、allMatch(T -> boolean)

流中所有元素是否都匹配给定条件。

11、noneMatch(T -> boolean)

流中是否没有元素匹配给定条件。

12、findAny() 和 findFirst()

找到任意一个元素;找到第一个元素。

返回的是:**Optional **

13、reduce((T, T) -> T) 和 reduce(T, (T, T) -> T)

将流中元素两两组合,最后得到一个元素。组合的方法取决于lambda表达式。

1
2
3
4
5
6
7
8
// 计算年龄总和:
int sum = list.stream()
              .map(Person::getAge)
              .reduce(0, (a, b) -> a + b);
// 计算年龄总和:
int sum = list.stream()
              .map(Person::getAge)
              .reduce(0, Integer::sum);

使用reduce(T, (T, T) -> T)方法时,第一个参数为初始值,函数返回值类型为:T

使用reduce((T, T) -> T)方法是,函数返回值为:**Optional**

14、count()

计数

15、collect()

收集方法。

1
2
3
4
5
List newlist = list.stream
                   .collect(toList());

Map<Integer, Person> map = list.stream()
                               .collect(toMap(Person::getAge, p -> p));

16、forEach()

遍历

数值流

int sum = list.stream().map(Person::getAge).reduce(0, Integer::sum)有拆装箱成本。

使用数值流可以避免这个问题。

1、流转化为数值流

  • mapToInt(T -> int) : return IntStream
  • mapToDouble(T -> double) : return DoubleStream
  • mapToLong(T -> long) : return LongStream

2、数值流方法

  • sum()
  • max()
  • min()
  • average()

3、数值范围

  • rangeClosed(1, 100) :[1, 100]
  • range(1, 100) :[1, 100)

构建流

1、值创建

  • Stream.of(T)
  • Stream.of(T…)
  • Stream.empty()
1
Stream<String> stream = Stream.of("aaa", "bbb", "ccc");

2、数组创建

  • Arrays.stream(T[ ])
  • Arrays.stream(int[ ])
  • Arrays.stream(double[ ])
  • Arrays.stream(long[ ])
1
2
String[] ss = {"Army", "Luna", "Elle", "Katherine"};
Stream<String> stream = Arrays.stream(ss, 1, 3);

3、函数创建

函数创建为无限流。

  • Stream.iterate(T, UnaryOperator):在T基础上,依次对每个新生成的T应用函数

  • Stream.generate(Supplier) :按函数生成流

1
2
3
4
// 正偶数集的流
Stream.iterate(0, n -> n + 2);
// 随机数
Stream.generate(Math::random);
This post is licensed under CC BY 4.0 by the author.