• Java8流Stream的创建和操作


    1. 流的创建方法

    import java.util.stream.*;
    
    public class StreamOf {
      public static void main(String[] args) {
        Stream.of(
          new Bubble(1), new Bubble(2), new Bubble(3))
          .forEach(System.out::println);
        Stream.of("It's ", "a ", "wonderful ",
          "day ", "for ", "pie!")
          .forEach(System.out::print);
        System.out.println();
        Stream.of(3.14159, 2.718, 1.618)
          .forEach(System.out::println);
      }
    }
    /* Output:
    Bubble(1)
    Bubble(2)
    Bubble(3)
    It's a wonderful day for pie!
    3.14159
    2.718
    1.618
    */
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    1.1 随机数流

    import java.util.*;
    import java.util.stream.*;
    
    public class RandomGenerators {
      public static <T> void show(Stream<T> stream) {
        stream
          .limit(4)
          .forEach(System.out::println);
        System.out.println("++++++++");
      }
      public static void main(String[] args) {
        Random rand = new Random(47);
        show(rand.ints().boxed());
        show(rand.longs().boxed());
        show(rand.doubles().boxed());
        // Control the lower and upper bounds:
        show(rand.ints(10, 20).boxed());
        show(rand.longs(50, 100).boxed());
        show(rand.doubles(20, 30).boxed());
        // Control the stream size:
        show(rand.ints(2).boxed());
        show(rand.longs(2).boxed());
        show(rand.doubles(2).boxed());
        // Control the stream size and bounds:
        show(rand.ints(3, 3, 9).boxed());
        show(rand.longs(3, 12, 22).boxed());
        show(rand.doubles(3, 11.5, 12.3).boxed());
      }
    }
    
    • 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

    1.2 int类型流

    import static java.util.stream.IntStream.*;
    
    public class Ranges {
      public static void main(String[] args) {
        // The traditional way:
        int result = 0;
        for(int i = 10; i < 20; i++)
          result += i;
        System.out.println(result);
    
        // for-in with a range:
        result = 0;
        for(int i : range(10, 20).toArray())
          result += i;
        System.out.println(result);
    
        // Use streams:
        System.out.println(range(10, 20).sum());
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20

    1.3 generate()

    import java.util.*;
    import java.util.function.*;
    import java.util.stream.*;
    
    public class Generator implements Supplier<String> {
      Random rand = new Random(47);
      char[] letters =
        "ABCDEFGHIJKLMNOPQRSTUVWXYZ".toCharArray();
      @Override public String get() {
        return "" + letters[rand.nextInt(letters.length)];
      }
      public static void main(String[] args) {
        String word = Stream.generate(new Generator())
          .limit(30)
          .collect(Collectors.joining());
        System.out.println(word);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    1.4 iterate()

    import java.util.stream.*;
    
    public class Fibonacci {
      int x = 1;
      Stream<Integer> numbers() {
        return Stream.iterate(0, i -> {
          int result = x + i;
          x = i;
          return result;
        });
      }
      public static void main(String[] args) {
        new Fibonacci().numbers()
          .skip(20) // Don't use the first 20
          .limit(10) // Then take 10 of them
          .forEach(System.out::println);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    1.5 流的建造者模式

    import java.io.*;
    import java.nio.file.*;
    import java.util.stream.*;
    
    public class FileToWordsBuilder {
      Stream.Builder<String> builder = Stream.builder();
      public FileToWordsBuilder(String filePath)
      throws Exception {
        Files.lines(Paths.get(filePath))
          .skip(1) // Skip the comment line at the beginning
          .forEach(line -> {
            for(String w : line.split("[ .?,]+"))
              builder.add(w);
          });
      }
      Stream<String> stream() { return builder.build(); }
      public static void
      main(String[] args) throws Exception {
        new FileToWordsBuilder("Cheese.dat").stream()
          .limit(7)
          .map(w -> w + " ")
          .forEach(System.out::print);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24

    1.6 Arrays

    import java.util.*;
    import onjava.Operation;
    
    public class MetalWork2 {
      public static void main(String[] args) {
        Arrays.stream(new Operation[] {
          () -> Operation.show("Heat"),
          () -> Operation.show("Hammer"),
          () -> Operation.show("Twist"),
          () -> Operation.show("Anneal")
        }).forEach(Operation::execute);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    1.7 正则表达式

    import java.io.*;
    import java.nio.file.*;
    import java.util.stream.*;
    import java.util.regex.Pattern;
    
    public class FileToWordsRegexp {
      private String all;
      public FileToWordsRegexp(String filePath)
      throws Exception {
        all = Files.lines(Paths.get(filePath))
          .skip(1) // First (comment) line
          .collect(Collectors.joining(" "));
      }
      public Stream<String> stream() {
        return Pattern
          .compile("[ .,?]+").splitAsStream(all);
      }
      public static void
      main(String[] args) throws Exception {
        FileToWordsRegexp fw =
          new FileToWordsRegexp("Cheese.dat");
        fw.stream()
          .limit(7)
          .map(w -> w + " ")
          .forEach(System.out::print);
        fw.stream()
          .skip(7)
          .limit(2)
          .map(w -> w + " ")
          .forEach(System.out::print);
      }
    }
    
    • 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

    2. 流的中间操作

    2.1 跟踪和调试

    class Peeking  {
      public static void
      main(String[] args) throws Exception {
        FileToWords.stream("Cheese.dat")
          .skip(21)
          .limit(4)
          .map(w -> w + " ")
          .peek(System.out::print)
          .map(String::toUpperCase)
          .peek(System.out::print)
          .map(String::toLowerCase)
          .forEach(System.out::print);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.2 排序

    import java.util.*;
    
    public class SortedComparator {
      public static void
      main(String[] args) throws Exception {
        FileToWords.stream("Cheese.dat")
          .skip(10)
          .limit(10)
          .sorted(Comparator.reverseOrder())
          .map(w -> w + " ")
          .forEach(System.out::print);
      }
    }
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    2.3 移除元素

    import java.util.stream.*;
    import static java.util.stream.LongStream.*;
    
    public class Prime {
      public static boolean isPrime(long n) {
        return rangeClosed(2, (long)Math.sqrt(n))
          .noneMatch(i -> n % i == 0);
      }
      public LongStream numbers() {
        return iterate(2, i -> i + 1)
          .filter(Prime::isPrime);
      }
      public static void main(String[] args) {
        new Prime().numbers()
          .limit(10)
          .forEach(n -> System.out.format("%d ", n));
        System.out.println();
        new Prime().numbers()
          .skip(90)
          .limit(10)
          .forEach(n -> System.out.format("%d ", n));
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23

    2.5 应用函数到每个元素

    import java.util.*;
    import java.util.stream.*;
    
    class Numbered {
      final int n;
      Numbered(int n) { this.n = n; }
      @Override public String toString() {
        return "Numbered(" + n + ")";
      }
    }
    
    class FunctionMap2 {
      public static void main(String[] args) {
        Stream.of(1, 5, 7, 9, 11, 13)
          .map(Numbered::new)
          .forEach(System.out::println);
      }
    }
    class FunctionMap3 {
      public static void main(String[] args) {
        Stream.of("5", "7", "9")
          .mapToInt(Integer::parseInt)
          .forEach(n -> System.out.format("%d ", n));
        System.out.println();
        Stream.of("17", "19", "23")
          .mapToLong(Long::parseLong)
          .forEach(n -> System.out.format("%d ", n));
        System.out.println();
        Stream.of("17", "1.9", ".23")
          .mapToDouble(Double::parseDouble)
          .forEach(n -> System.out.format("%f ", n));
      }
    }
    
    • 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

    2.6 在map()中组合流

    import java.util.stream.*;
    
    public class StreamOfStreams {
      public static void main(String[] args) {
        Stream.of(1, 2, 3)
          .map(i -> Stream.of("Gonzo", "Kermit", "Beaker"))
          .map(e-> e.getClass().getName())
          .forEach(System.out::println);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    import java.util.*;
    import java.util.stream.*;
    
    public class StreamOfRandoms {
      static Random rand = new Random(47);
      public static void main(String[] args) {
        Stream.of(1, 2, 3, 4, 5)
          .flatMapToInt(i -> IntStream.concat(
            rand.ints(0, 100).limit(i), IntStream.of(-1)))
          .forEach(n -> System.out.format("%d ", n));
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    import java.nio.file.*;
    import java.util.stream.*;
    import java.util.regex.Pattern;
    
    public class FileToWords {
      public static Stream<String> stream(String filePath)
      throws Exception {
        return Files.lines(Paths.get(filePath))
          .skip(1) // First (comment) line
          .flatMap(line ->
            Pattern.compile("\\W+").splitAsStream(line));
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13

    3. 终端或订阅操作

    3.1 输出为数组

    • toArray()
    • toArray(generator): 特殊情况下,生成自定义类型的数组
    import java.util.*;
    import java.util.stream.*;
    
    public class RandInts {
      private static int[] rints =
        new Random(47).ints(0, 1000).limit(100).toArray();
      public static IntStream rands() {
        return Arrays.stream(rints);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10

    3.2 循环

    • forEach(Consumer):在Collection中可以改变值,但是stream不应该修改值。因为流式要求non-interfering。
    • forEachOrdered(Consumer): 保证forEach按照原始流顺序返回
      Collection.forEach和Collection.stream().forEach区别:
      https://www.baeldung.com/java-collection-stream-foreach

    3.3 集合

    • collect(Collector)
    • collect(Supplier, BiConsumer, BiConsumer): 第一个参数Supplier创建一个新的结果集合,第二个参数BiConsumer将下一个元素收集到结果集合,第三个参数BiConsumer用于将两个结果集合合并起来。
    import java.util.*;
    import java.nio.file.*;
    import java.util.stream.*;
    public class TreeSetOfWords {
      public static void
      main(String[] args) throws Exception {
        Set<String> words2 =
          Files.lines(Paths.get("TreeSetOfWords.java"))
            .flatMap(s -> Arrays.stream(s.split("\\W+")))
            .filter(s -> !s.matches("\\d+")) // No numbers
            .map(String::trim)
            .filter(s -> s.length() > 2)
            .limit(100)
            .collect(Collectors.toCollection(TreeSet::new));
        System.out.println(words2);
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    import java.util.*;
    import java.util.stream.*;
    
    class Pair {
      public final Character c;
      public final Integer i;
      Pair(Character c, Integer i) {
        this.c = c;
        this.i = i;
      }
      public Character getC() { return c; }
      public Integer getI() { return i; }
      @Override public String toString() {
        return "Pair(" + c + ", " + i + ")";
      }
    }
    
    class RandomPair {
      Random rand = new Random(47);
      // An infinite iterator of random capital letters:
      Iterator<Character> capChars = rand.ints(65,91)
        .mapToObj(i -> (char)i)
        .iterator();
      public Stream<Pair> stream() {
        return rand.ints(100, 1000).distinct()
          .mapToObj(i -> new Pair(capChars.next(), i));
      }
    }
    
    public class MapCollector {
      public static void main(String[] args) {
        Map<Integer, Character> map =
          new RandomPair().stream()
            .limit(8)
            .collect(
              Collectors.toMap(Pair::getI, Pair::getC));
        System.out.println(map);
      }
    }
    
    • 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

    3.4 组合

    • reduce(BinaryOperator)
    • reduce(identity, BinaryOperator)
    • reduce(identity, BiFunction, BinaryOperator)
    import java.util.*;
    import java.util.stream.*;
    
    class Frobnitz {
      int size;
      Frobnitz(int sz) { size = sz; }
      @Override public String toString() {
        return "Frobnitz(" + size + ")";
      }
      // Generator:
      static Random rand = new Random(47);
      static final int BOUND = 100;
      static Frobnitz supply() {
        return new Frobnitz(rand.nextInt(BOUND));
      }
    }
    
    public class Reduce {
      public static void main(String[] args) {
        Stream.generate(Frobnitz::supply)
          .limit(10)
          .peek(System.out::println)
          .reduce((fr0, fr1) -> fr0.size < 50 ? fr0 : fr1)
          .ifPresent(System.out::println);
      }
    }
    
    • 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

    3.5 匹配

    • allMatch(Predicate)
    • anyMatch(Predicate)
    • noneMatch(Predicate)
    import java.util.stream.*;
    import java.util.function.*;
    import static streams.RandInts.*;
    
    interface Matcher extends
      BiPredicate<Stream<Integer>, Predicate<Integer>> {}
    
    public class Matching {
      static void show(Matcher match, int val) {
        System.out.println(
          match.test(
            IntStream.rangeClosed(1, 9)
              .boxed()
              .peek(n -> System.out.format("%d ", n)),
            n -> n < val));
      }
      public static void main(String[] args) {
        show(Stream::allMatch, 10);
        show(Stream::allMatch, 4);
        show(Stream::anyMatch, 2);
        show(Stream::anyMatch, 0);
        show(Stream::noneMatch, 5);
        show(Stream::noneMatch, 0);
      }
    }
    
    • 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

    3.6 查找

    • findFirst()
    • findAny()
    import java.util.*;
    import java.util.stream.*;
    import static streams.RandInts.*;
    
    public class SelectElement {
      public static void main(String[] args) {
        System.out.println(rands().findFirst().getAsInt());
        System.out.println(
          rands().parallel().findFirst().getAsInt());
        System.out.println(rands().findAny().getAsInt());
        System.out.println(
          rands().parallel().findAny().getAsInt());
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14

    3.7 信息

    • count()
    • max(Comparator)
    • min(Comparator)
    import java.util.stream.*;
    import java.util.function.*;
    
    public class Informational {
      public static void
      main(String[] args) throws Exception {
          System.out.println(
            FileToWords.stream("Cheese.dat").count());
          System.out.println(
            FileToWords.stream("Cheese.dat")
            .min(String.CASE_INSENSITIVE_ORDER)
            .orElse("NONE"));
          System.out.println(
            FileToWords.stream("Cheese.dat")
            .max(String.CASE_INSENSITIVE_ORDER)
            .orElse("NONE"));
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    3.8 数字流信息

    • avarage()
    • max() min()
    • sum()
    • summaryStatistics()
    import java.util.stream.*;
    import static streams.RandInts.*;
    
    public class NumericStreamInfo {
      public static void main(String[] args) {
        System.out.println(rands().average().getAsDouble());
        System.out.println(rands().max().getAsInt());
        System.out.println(rands().min().getAsInt());
        System.out.println(rands().sum());
        System.out.println(rands().summaryStatistics());
      }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
  • 相关阅读:
    web前端期末大作业 html+css古诗词主题网页设计
    GitHub爬虫项目详解
    解决所有二叉树路径问题
    React Native 环境搭建
    CentOS 6服务器升级Git时, 下载依赖包失败,需配置国外Yum源
    使用宝塔面板安装mysql
    【PTA-训练day10】L2-022 重排链表 + L1-043 阅览室
    java高级编程day23【谷】
    flume框架原理
    springboot+springsecurity+jwt+elementui图书管理系统
  • 原文地址:https://blog.csdn.net/Fire_to_cheat_/article/details/126837265