Java8 Stream 使用简介

简介

Java 8 的提供的Stream类可以很方便的操作集合,同时可以很好的应用Lambda表达式。使用Stream可以使代码变得简洁,可以很明显的表达出代码的意思,比如 Stream.of(1, 2, 3).filter(i -> i > 1).collect(Collectors.toList()),根据单词的意思,将这个Stream过滤,过滤条件是元素大于1,然后生成一个List。

常用集合转换

  • 定义一个会使用到的对象 User

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    public class User {
    private Long id;
    private String name;
    public User() {}
    public User(Long id, String name) {
    this.id = id;
    this.name = name;
    }
    @Override
    public String toString() {
    return "User(" + name + ")";
    }
    // setter getter omitted
    }
  • List -> List
    通过: map、Collectors.toList()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    // List<String> 转 List<Integer>
    List<String> stringList = Arrays.asList("1000", "2000", "3000");
    // 这里的 Integer::valueOf 是Lambda表达式的另一种写法,
    // 表示 i -> String.valueOf(i),下面这样的方法如 User::getId 表示 u -> u.getId()
    List<Integer> intList = stringList.stream()
    .map(Integer::valueOf)
    .collect(Collectors.toList());

    System.out.println(intList); // 输出 [1000, 2000, 3000]

    // 将一个List<User>的id提取出来生成 List<Long>
    List<User> users = Arrays.asList(new User(1004L, "Jerry"), new User(1001L, "Nick"), new User(1032L, "Gray"));
    List<Long> idList = users.stream()
    .map(User::getId)
    .collect(Collectors.toList());

    System.out.println(idList); // 输出 [1004, 1001, 1032]
  • List -> Map
    通过: map、Collectors.toMap()

    1
    2
    3
    4
    5
    6
    7
    // 将 List<User> 生成 Map<Long, User> key为user的id,value为user
    List<User> users = Arrays.asList(new User(1004L, "Jerry"), new User(1001L, "Nick"), new User(1032L, "Gray"));
    Map<Long, User> userMap = users.stream()
    .collect(Collectors.toMap(User::getId, Function.identity()));

    System.out.println(userMap);
    // 输出 {1032=User(Gray), 1001=User(Nick), 1004=User(Jerry)}
  • List<List> -> List
    方法: flatMap、Collectors.toMap()

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     // 将 字符串集合中的字符串按空格分开形成新的单词集合,最后生成一个单词集合
    List<String> list = Arrays.asList("Hello world", "Java welcome good good study");
    List<String> words = list.stream().map(s -> Arrays.asList(s.split(" ")))
    // peek只是输出一下元素在目前的情况
    .peek(i -> System.out.println("item -> " + i))
    .flatMap(Collection::stream)
    .collect(Collectors.toList());

    System.out.println("words -> " + words);
    // 输出如下:
    // item -> [Hello, world]
    // item -> [Java, welcome, good, good, study]
    // words -> [Hello, world, Java, welcome, good, good, study]

IntStream

  • 打印 [0, 100) 的数字

    1
    IntStream.range(0, 100).forEach(System.out::println);
  • 生成 [0, 100) 范围内的奇数集合

    1
    List<Integer> oddList = IntStream.range(0, 100).filter(i -> (i & 1 ) == 1).boxed().collect(Collectors.toList());

常用方法解释

  • map
    map方法相当于一个加工器,传入一个元素,返回一个元素,比如传入Integer类型,返回 String类型,这样Stream中的元素类型就变成String
  • filter
    过滤,传入当前Steam的元素,返回bool值,留下返回为true的元素
  • collect
    将Stream生成集合或者String,常用的操作 Collectors.toList()、Collectors.toMap()、Collectors.toSet()、 Collectors.joining(String delimiter)(将Stream中的字符串通过delimiter拼接)
  • anyMatch
    传入元素,返回bool值,当有一个true返回则整个方法返回true
  • parallel
    使用并行的方法操作Stream,注意并发的问题,会在不同的线程执行,如下:
    1
    2
    3
    4
    5
    6
    IntStream.range(0, 5).parallel().forEach(i -> System.out.println(Thread.currentThread().getName() + " -> " + i));
    // ForkJoinPool.commonPool-worker-1 -> 1
    // ForkJoinPool.commonPool-worker-3 -> 0
    // ForkJoinPool.commonPool-worker-1 -> 4
    // ForkJoinPool.commonPool-worker-3 -> 3
    // main -> 2