Stream流的一些使用方法

ljwdhxd發表於2024-08-17

一、建立Stream資料流

  1. Stream流建立

    Stream<Integer> stream = Stream.of(0, 1, 2, 3, 4, 5);
  2. Collection建立

    List<Integer> integerList = new ArrayList<>();
    integerList.add(0);
    integerList.add(1);
    integerList.add(2);
    integerList.add(3);
    integerList.add(4);
    integerList.add(5);
    Stream<Integer> listStream = integerList.stream();
  3. Arrays建立

    int[] intArr = {0, 1, 2, 3, 4, 5};
    IntStream arrayStream = Arrays.stream(intArr);
  4. 檔案建立

    try {
         Stream<String> fileStream = Files.lines(Paths.get("data.txt"), Charset.defaultCharset());
    } catch (IOException e) {
         e.printStackTrace();
    }
  5. 函式建立(無限流)

    Stream.iterator() 方法接受兩個引數,第一個為初始化值,第二個為進行的函式操作,因為 iterator 生成的流為無限流,透過 limit 方法對流進行了截斷

    Stream<Integer> iterateStream = Stream.iterate(0, n -> n + 2).limit(5);

    Stream.generate() 方法接受一個引數,方法引數型別為 Supplier ,由它為流提供值。generate 生成的流也是無限流,因此透過 limit 對流進行了截斷

    Stream<Double> generateStream = Stream.generate(Math::random).limit(5);

二、Stream流中間操作

  1. filter過濾

    // filter:輸出ID大於6的user物件
    List<User> filetrUserList = userList.stream().filter(user -> user.getId() > 6).collect(Collectors.toList());
    filetrUserList.forEach(System.out::println);
    //查詢列表中以B開頭的第一個字串
    String result2=names.stream().filter(name->name.startsWith("B")).findFirst().orElse("未找到");
  2. map對映

    map 元素對映,提供一個對映規則,將流中的每一個元素替換成指定的元素

    // map
    List<String> mapUserList = userList.stream().map(user -> user.getName() + "使用者").collect(Collectors.toList());
    mapUserList.forEach(System.out::println);
  3. distinct去重

    distinct 去重,去除流中的重複的資料,這個方法是沒有引數的,去重的規則與 hashSet 相同

    // 去重
    dataSource.distinct().forEach(System.out::println); 
  4. sorted排序

    sorted 排序,將流中的資料,按照其對應的類實現的 Comparable 介面提供的比較規則進行排序

    // sorted:排序,根據名字倒序
    userList.stream().sorted(Comparator.comparing(User::getName).reversed()).collect(Collectors.toList()).forEach(System.out::println);
    //將集合中所有元素排序並大寫輸出
    List<String> words= Arrays.asList("banana","apple","orange");
    words.stream().sorted().map(String::toUpperCase).forEach(System.out::println);
  5. limit & skip 限制 & 跳過

    • limit 限制,表示擷取流中的指定數量的資料(從第0開始),丟棄剩餘部分

    • skip 跳過,表示跳過指定數量的資料,擷取剩餘部分

    // 獲取成績的[3,5]名
    dataSource.sorted((s1,s2) -> s2.score - s1.score).distinct() 
                .limit(5)
                .skip(2)
                .forEach(System.out::println);
  6. flatMap扁平化對映

    使用 flatMap 方法的效果是,各個陣列並不是分別對映成一個流,而是對映成流的內容。所有使用 map(Arrays::stream) 時生成的單個流都被合併起來,即扁平化為一個流

    // 一般是用在map對映完成後,流中的資料是一個容器,而我們需要再對容器中的資料進行處理,此時使用扁平化對映
    // 將字串陣列中的資料讀取到流中
    Stream<String> stream = Arrays.stream(s);  
    // 統計字串陣列中所有出現的字元
    stream.map(e -> e.split("")) 
                .flatMap(Arrays::stream)
                .distinct()
                .forEach(System.out::print);
  7. peek對元素進行遍歷處理

    // peek:對元素進行遍歷處理,每個使用者ID加1輸出
    userList.stream().peek(user -> user.setId(user.getId()+1)).forEach(System.out::println);

三、Stream流終端操作

Stream 流執行完終端操作之後,無法再執行其他動作,否則會報狀態異常,提示該流已經被執行操作或者被關閉,想要再次執行操作必須重新建立 Stream 流

一個流有且只能有一個終端操作,當這個操作執行後,流就被關閉了,無法再被操作,因此一個流只能被遍歷一次,若想在遍歷需要透過源資料在生成流。

終端操作的執行,才會真正開始流的遍歷。如 count、collect 等

  1. collect收集器

    collect 將流中的資料整合起來

    // collect:收集器,將流轉換為其他形式
    Set set = userList.stream().collect(Collectors.toSet());
    set.forEach(System.out::println);
    System.out.println("--------------------------");
    List list = userList.stream().collect(Collectors.toList());
    list.forEach(System.out::println);
  2. forEach 遍歷流

    forEach 遍歷流中資料

    // forEach:遍歷流
    userList.stream().forEach(user -> System.out.println(user));
    userList.stream().filter(user -> "上海".equals(user.getCity())).forEach(System.out::println);
  3. findFirst & findAny 獲取流中的元素

    findFirst 獲取流中的一個元素,獲取的是流中的首元素,在進行元素獲取的時候,無論是序列流還是並行流,獲取的都是首元素

    // findFirst:返回第一個元素
    User firstUser = userList.stream().findFirst().get();
    User firstUser1 = userList.stream().filter(user -> "上海".equals(user.getCity())).findFirst().get();

    findAny 獲取流中的一個元素,通常是首元素,但在並行流中,獲取的可能不是首元素。在進行元素獲取的時候,序列流一定獲取到的是流中的首元素,並行流獲取到的可能是首元素,也可能不是

    // findAny:將返回當前流中的任意元素
    User findUser = userList.stream().findAny().get();
    User findUser1 = userList.stream().filter(user -> "上海".equals(user.getCity())).findAny().get();
  4. count總數

    count 返回流中元素總數

    // count:返回流中元素總數
    long count = userList.stream().filter(user -> user.getAge() > 20).count();
    System.out.println(count);
  5. sum求和

    // sum:求和
    int sum = userList.stream().mapToInt(User::getId).sum();
    //對集合元素求和
    List<Integer> numbers= Arrays.asList(3,7,2,8,10,1,5,6);
    //第一種方法
    Integer r1=numbers.stream().mapToInt(Integer::intValue).sum();
    //第二種方法
    Integer reduce = numbers.stream().reduce(0, Integer::sum);
  6. max & min 最大 & 最小

    // max:最大值
    int max = userList.stream().max(Comparator.comparingInt(User::getId)).get().getId();
    // min:最小值
    int min = userList.stream().min(Comparator.comparingInt(User::getId)).get().getId();
  7. reduce 聚合

    reduce 將流中的資料按照一定的規則聚合起來

    // reduce:將流中元素反覆結合起來,得到一個值
    Optional reduce = userList.stream().reduce((user, user2) -> {
          return user+user2;
    });
    if(reduce.isPresent()) System.out.println(reduce.get());
  8. allMatch & anyMatch & noneMatch

    allMatch: 只有當流中所有的元素都匹配指定的規則,才會返回 true

    anyMatch: 只要流中的任意資料滿足指定的規則,就會返回 true

    noneMatch: 只有當流中所有的元素都不滿足指定的規則,才會返回 true

    // allMatch:檢查是否匹配所有元素
    boolean matchAll = userList.stream().allMatch(user -> "北京".equals(user.getCity()));
    // anyMatch:檢查是否至少匹配一個元素
    boolean matchAny = userList.stream().anyMatch(user -> "北京".equals(user.getCity()));
    // noneMatch:檢查是否沒有匹配所有元素,返回 boolean
    boolean nonaMatch = userList.stream().allMatch(user -> "北京".equals(user.getCity()));

四、Collect收集

Collector:結果收集策略的核心介面,具備將指定元素累加存放到結果容器中的能力;並在Collectors工具中提供了Collector介面的實現類

  1. toList

    將使用者 ID 存放到 List 集合中

    List<Integer> idList = userList.stream().map(User::getId).collect(Collectors.toList()) ;
  2. toMap

    將使用者 ID 和 Name 以 Key-Value 形式存放到 Map 集合中

    Map<Integer,String> userMap = userList.stream().collect(Collectors.toMap(User::getId,User::getName));
  3. toSet

    將使用者所在城市存放到 Set 集合中

    Set<String> citySet = userList.stream().map(User::getCity).collect(Collectors.toSet());
  4. counting

    符合條件的使用者總數

    long count = userList.stream().filter(user -> user.getId()>1).collect(Collectors.counting());
  5. sumingInt

    對結果元素即使用者 ID 求和

    Integer sumInt = userList.stream().filter(user -> user.getId()>2).collect(Collectors.summingInt(User::getId)) ;

    對集合元素求和

    List<Integer> numbers= Arrays.asList(3,7,2,8,10,1,5,6);
    Integer r=numbers.stream().collect(Collectors.summingInt(Integer::intValue));
  6. minBy

    篩選元素中 ID 最小的使用者

    User maxId = userList.stream().collect(Collectors.minBy(Comparator.comparingInt(User::getId))).get() ;
  7. joining

    將使用者所在城市,以指定分隔符連結成字串

    String joinCity = userList.stream().map(User::getCity).collect(Collectors.joining("||"));
  8. groupingBy

    按條件分組,以城市對使用者進行分組;

    Map<String,List<User>> groupCity = userList.stream().collect(Collectors.groupingBy(User::getCity));

相關文章