ZB-032-02Stream的API

Stream的API-创建Stream

  • Collection.stream() 最常用

    1
    2
    3
    4
    5
    6
    7
    8
    9
    List<User> users = Arrays.asList(new User("张三",20),new User("张三疯",15),new User("李四",100));

    // 创建一个流
    // users.stream()

    users.stream().filter(user->user.name.startsWith("张"))
    .sorted(Comparator.comparing(User::getAge))
    .map(User::getName)
    .collect(Collectors.toList());
  • Stream.of(T … values) 接收若干个参数 把它变成一个流

  • String.chars() 把这个字符串包含的所有字符变成一个流
  • IntStream.range()
    1
    IntStream.range(0,2) // 包头不包尾

API

  • boolean allMatch(Predicate<? super T> predicate); 是否所有元素符合这个判定
  • boolean anyMatch(Predicate<? super T> predicate); 是否任何一个元素符合这个判定
  • noneMatch 任何元素都不满足这个判定
  • count() 统计个数
  • Stream<T> distinct(); 去重
  • empty() 清空流
  • filter 过滤
  • findAny 看看有没有任何一个元素在这个流里面
  • generate 返回一个无限的 类似生成器 “低频使用”
  • limit 限制这个流的长度
  • map 把一个流映射为另外一个流
  • max
  • min
  • of 创建一个流
  • peek 看看流最开始的元素是什么
  • reduce 把这个流变成新的元素
  • skip 跟 limit 很像
  • sorted 把流变成有序的流
  • toArray
  • findFirst/findAny

String.chars

统计大写字母次数

1
2
3
4
5
6
7
8
9
10
11
12
13
package com.github.hcsp.polymorphism;

public class Main2 {
public static void main(String[] args) {

int count = printUpperCaseLetters("ABCabcDEFdef");
System.out.println(count); // 6
}

public static int printUpperCaseLetters(String str){
return (int)str.chars().filter(Character::isUpperCase).count();
}
}

IntStream

返回 1 ~10 之间的偶数

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
import java.util.stream.IntStream;

public class Main2 {
public static void main(String[] args) {

printOddNumbersBetween(1,10);
}

public static void printOddNumbersBetween(int start,int end){
// 包头不包尾
// IntStream.range(0,2); // 0 , 1
IntStream.range(start, end + 1)
.filter(i -> i % 2 == 0) // 过滤
.mapToObj(i -> "加工后的数字为:" + i) // 对每个数据进行 一个映射 如 从 int --> String
.forEach(System.out::println); // 终结操作

}
}

anyMatch

是否含有姓 李 的用户

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
import java.util.*;
import java.util.stream.Collectors;

public class Main {
static class User{
private String name;
private int age;

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

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 static void main(String[] args) {
List<User> users = Arrays.asList(new User("张三",20),new User("张三疯",15),new User("李四",100));

// 获取姓 李 的用户
boolean hasLi = users
.stream()
.anyMatch(user->user.getName().startsWith("李"));
System.out.println(hasLi);
}
}

findAny

1
2
3
users.stream()
.filter(user -> user.getName().startsWith("张"))
.findAny();

联合 Optional 的正确使用方式

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
 public static void findZhangUser(){
List<User> users = Arrays.asList(new User("张三",20),new User("张三疯",15),new User("李四",100));

Optional<User> optionalUser = users.stream().filter(user -> user.getName().startsWith("张")).findAny();

// 最佳实践 Optional + 函数式
// 正确写法:不存在抛出错误
optionalUser.orElseThrow(IllegalStateException::new);
// 存在则打印
optionalUser.isPresent(System.out::println);

// 不好的写法 ,optionalUser这个用户存在就打印
if(optionalUser.isPresent()){
System.out.println(optionalUser.get().getName());
}else{
throw new IllegalStateException();
}
}

级联操作 Optional + 函数式的最佳用法

  • orElseThrow 参数是一个 Supplier 从无到有
  • isPresent 参数是 Consumer 接受一个东西把它吃掉
  • 不要把 Optional 当作空指针的替代品,当作参数传来传去
  • 应该把它当作返回值 对这个返回值进行函数式操作
1
2
3
4
5
6
7
 public static void findZhangUser(){
List<User> users = Arrays.asList(new User("张三",20),new User("张三疯",15),new User("李四",100));
// 最佳实践 Optional + 函数式
User zhang = users.stream().filter(user -> user.getName().startsWith("张")).findAny().orElseThrow(IllegalStateException::new);
System.out.println(zhang.getName());

}