01 流创建

1 流支持

Java 8 通过在接口中添加被 default(默认)修饰的方法,进而将流式(stream)方法平滑地嵌入到现有类中。流操作的类型有三种:创建流,修改流元素(中间操作,Intermediate Operations),消费流元素(终端操作,Terminal Operations)。

2 流创建

(1)Stream.of()

public static<T> Stream<T> of(T t) {
        return StreamSupport.stream(new Streams.StreamBuilderImpl<>(t), false);
}
package com.hcong.streams;

import java.util.stream.Stream;

/**
 * @Classname StreamOf
 * @Date 2023/4/14 9:43
 * @Created by HCong
 */
public class StreamOf {
    public static void main(String[] args) {
        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);
    }
}

It's a wonderful day for pie!
3.14159
2.718
1.618

(2)调用每个集合的 stream() 方法

package com.hcong.streams;

import java.util.*;

/**
 * @Classname CollectionToStream
 * @Date 2023/4/14 9:45
 * @Created by HCong
 */
public class CollectionToStream {
    public static void main(String[] args) {
        Set<String> w = new HashSet<>(Arrays.asList("It's a wonderful day for pie!".split(" ")));
        w.stream()
                .map(x -> x + " ")
                .forEach(System.out::print);
        System.out.println();

        Map<String, Double> m = new HashMap<>();
        m.put("pi", 3.14159);
        m.put("e", 2.718);
        m.put("phi", 1.618);
        m.entrySet().stream()
                .map(e -> e.getKey() + ": " + e.getValue())
                .forEach(System.out::println);

    }
}

a pie! It's for wonderful day 
phi: 1.618
e: 2.718
pi: 3.14159

3 其他流创建方法

3.1 随机数流

package com.hcong.streams;

import java.util.Random;
import java.util.stream.Stream;

/**
 * @Classname RandomGenerators
 * @Date 2023/4/14 9:54
 * @Created by HCong
 */
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());
        // 控制上限和下限:
        show(rand.ints(10, 20).boxed());
        show(rand.longs(50, 100).boxed());
        show(rand.doubles(20, 30).boxed());
        // 控制流大小:
        show(rand.ints(2).boxed());
        show(rand.longs(2).boxed());
        show(rand.doubles(2).boxed());
        // 控制流的大小和界限
        show(rand.ints(3, 3, 9).boxed());
        show(rand.longs(3, 12, 22).boxed());
        show(rand.doubles(3, 11.5, 12.3).boxed());
    }
}

3.2 repeat()

实用小功能 repeat() 可以用来替换简单的 for 循环。

package com.hcong.utils;

import java.util.stream.IntStream;

/**
 * @Classname Repeat
 * @Date 2023/4/14 13:53
 * @Created by HCong
 */
public class Repeat {
    public static void repeat(int n, Runnable r) {
        IntStream.range(0, n).forEach(i -> r.run());
    }
}

package com.hcong.streams;

import com.hcong.utils.Repeat;

/**
 * @Classname Looping
 * @Date 2023/4/14 13:55
 * @Created by HCong
 */
public class Looping {
    static void hi() {
        System.out.println("Hi!");
    }

    public static void main(String[] args) {
        Repeat.repeat(3, () -> System.out.println("Hello"));
        Repeat.repeat(3, Looping::hi);
    }
}

Hello
Hello
Hello
Hi!
Hi!
Hi!

3.3 Stream.generate()

Stream.generate() 的用法,它可以把任意 Supplier 用于生成 T 类型的流。

    public static<T> Stream<T> generate(Supplier<? extends T> s) {
        Objects.requireNonNull(s);
        return StreamSupport.stream(
                new StreamSpliterators.InfiniteSupplyingSpliterator.OfRef<>(Long.MAX_VALUE, s), false);
    }
package com.hcong.streams;

import java.util.Random;
import java.util.function.Supplier;
import java.util.stream.Collectors;
import java.util.stream.Stream;

/**
 * @Classname Generator
 * @Date 2023/4/14 14:01
 * @Created by HCong
 */
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);
    }
}

YNZBRNYGCFOWZNTCQRGSEGZMMJMROE

3.4 Stream.iterate()

Stream.iterate() 产生的流的第一个元素是种子(iterate 方法的第一个参数),然后将种子传递给方法(iterate 方法的第二个参数)。方法运行的结果被添加到流(作为流的下一个元素),并被存储起来,作为下次调用 iterate() 方法时的第一个参数,以此类推。

    public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
        Objects.requireNonNull(f);
        Spliterator<T> spliterator = new Spliterators.AbstractSpliterator<>(Long.MAX_VALUE,
               Spliterator.ORDERED | Spliterator.IMMUTABLE) {
            T prev;
            boolean started;

            @Override
            public boolean tryAdvance(Consumer<? super T> action) {
                Objects.requireNonNull(action);
                T t;
                if (started)
                    t = f.apply(prev);
                else {
                    t = seed;
                    started = true;
                }
                action.accept(prev = t);
                return true;
            }
        };
        return StreamSupport.stream(spliterator, false);
    }
package com.hcong.streams;

import java.util.stream.Stream;

/**
 * @Classname Fibonacci
 * @Date 2023/4/14 14:10
 * @Created by HCong
 */
public class Fibonacci {
    int x = 1;

    Stream<Integer> numbers() {
        return Stream.iterate(0, i -> {
            // iterate() 只能记忆结果,因此我们需要利用一个变量 x 追踪另外一个元素。
            int result = i + x;
            x = i;
            return result;
        });
    }

    public static void main(String[] args) {
        new Fibonacci().numbers()
                .skip(20)
                .limit(10)
                .forEach(System.out::println);
    }
}

3.5 流的建造者模式

在建造者模式(Builder design pattern)中,首先创建一个 builder 对象,然后将创建流所需的多个信息传递给它,最后 builder 对象执行”创建流的操作。

package com.hcong.streams;

import java.io.File;
import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.stream.Stream;

/**
 * @Classname FileToWordsBuilder
 * @Date 2023/4/14 14:17
 * @Created by HCong
 */
public class FileToWordsBuilder {
    Stream.Builder<String> builder = Stream.builder();

    public FileToWordsBuilder(String filePath) throws IOException {
        Files.lines(Paths.get(filePath))
                .skip(1)
                .forEach(line -> {
                    for (String w : line.split("[ .?,]+"))
                        builder.add(w);
                });
    }

    // 只要你不调用 stream() 方法,就可以继续向 builder 对象中添加单词。
    Stream<String> stream() {
        return builder.build();
    }

    public static void main(String[] args) throws IOException {
        new FileToWordsBuilder("E:\\Projects\\IdeaProjects\\OnJava\\src\\com\\hcong\\streams\\Cheese.dat")
                .stream()
                .limit(7)
                .map(w -> w + " ")
                .forEach(System.out::print);
    }

}

3.6 Arrays.stream()

Arrays 类中含有一个名为 stream() 的静态方法用于把数组转换成为流。

public static <T> Stream<T> stream(T[] array) {
        return stream(array, 0, array.length);
}
public static <T> Stream<T> stream(T[] array, int startInclusive, int endExclusive) {
        return StreamSupport.stream(spliterator(array, startInclusive, endExclusive), false);
}
package com.hcong.streams;

import com.hcong.utils.Operations;

import java.util.Arrays;

/**
 * @Classname Machine2
 * @Date 2023/4/14 14:21
 * @Created by HCong
 */
public class Machine2 {
    public static void main(String[] args) {
        Arrays.stream(new Operations[]{
                () -> Operations.show("Bing"),
                () -> Operations.show("Crack"),
                () -> Operations.show("Twist"),
                () -> Operations.show("Pop")
        }).forEach(Operations::execute);
    }
}

Bing
Crack
Twist
Pop

你可能感兴趣的:(OnJava,#,十四,流式编程,java)