admin管理员组

文章数量:1026989

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.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 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.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.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.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 voidmain(String[] args) throws Exception {new FileToWordsBuilder("Cheese.dat").stream().limit(7).map(w -> w + " ").forEach(System.out::print);}
}

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.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 Patternpile("[ .,?]+").splitAsStream(all);}public static voidmain(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);}
}

2. 流的中间操作

2.1 跟踪和调试

class Peeking  {public static voidmain(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);}
}

2.2 排序

import java.util.*;public class SortedComparator {public static voidmain(String[] args) throws Exception {FileToWords.stream("Cheese.dat").skip(10).limit(10).sorted(Comparator.reverseOrder()).map(w -> w + " ").forEach(System.out::print);}
}

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));}
}

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));}
}

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);}
}
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));}
}
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 ->Patternpile("\\W+").splitAsStream(line));}
}

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);}
}

3.2 循环

  • forEach(Consumer):在Collection中可以改变值,但是stream不应该修改值。因为流式要求non-interfering。
  • forEachOrdered(Consumer): 保证forEach按照原始流顺序返回
    Collection.forEach和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 voidmain(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);}
}
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);}
}

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);}
}

3.5 匹配

  • allMatch(Predicate)
  • anyMatch(Predicate)
  • noneMatch(Predicate)
import java.util.stream.*;
import java.util.function.*;
import static streams.RandInts.*;interface Matcher extendsBiPredicate<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);}
}

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());}
}

3.7 信息

  • count()
  • max(Comparator)
  • min(Comparator)
import java.util.stream.*;
import java.util.function.*;public class Informational {public static voidmain(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"));}
}

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());}
}

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.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 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.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.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.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 voidmain(String[] args) throws Exception {new FileToWordsBuilder("Cheese.dat").stream().limit(7).map(w -> w + " ").forEach(System.out::print);}
}

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.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 Patternpile("[ .,?]+").splitAsStream(all);}public static voidmain(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);}
}

2. 流的中间操作

2.1 跟踪和调试

class Peeking  {public static voidmain(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);}
}

2.2 排序

import java.util.*;public class SortedComparator {public static voidmain(String[] args) throws Exception {FileToWords.stream("Cheese.dat").skip(10).limit(10).sorted(Comparator.reverseOrder()).map(w -> w + " ").forEach(System.out::print);}
}

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));}
}

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));}
}

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);}
}
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));}
}
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 ->Patternpile("\\W+").splitAsStream(line));}
}

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);}
}

3.2 循环

  • forEach(Consumer):在Collection中可以改变值,但是stream不应该修改值。因为流式要求non-interfering。
  • forEachOrdered(Consumer): 保证forEach按照原始流顺序返回
    Collection.forEach和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 voidmain(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);}
}
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);}
}

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);}
}

3.5 匹配

  • allMatch(Predicate)
  • anyMatch(Predicate)
  • noneMatch(Predicate)
import java.util.stream.*;
import java.util.function.*;
import static streams.RandInts.*;interface Matcher extendsBiPredicate<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);}
}

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());}
}

3.7 信息

  • count()
  • max(Comparator)
  • min(Comparator)
import java.util.stream.*;
import java.util.function.*;public class Informational {public static voidmain(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"));}
}

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());}
}

本文标签: Java8流Stream的创建和操作