Java8Stream流操作

熟悉了java.util.function下的各种函数式接口后,我们就可以学习下Stream流操作,它使用了各种函数式接口,下面我们来熟悉下它的API。

Stream的获取

static <T> Stream<T>of(T... values)

Returns a sequential ordered stream whose elements are the specified values.

static <T> Stream<T>of(T t)

Returns a sequential Stream containing a single element.

数组转换

Object[]toArray()

Returns an array containing the elements of this stream.

<A> A[]toArray(IntFunction<A[]> generator)

Returns an array containing the elements of this stream, using the provided generator function to allocate the returned array, as well as any additional arrays that might be required for a partitioned execution or for resizing.

 

 排序 

Stream<T>sorted()

Returns a stream consisting of the elements of this stream, sorted according to natural order.

Stream<T>sorted(Comparator<? super T> comparator)

Returns a stream consisting of the elements of this stream, sorted according to the provided Comparator.

 

 去重

Stream<T>distinct()

Returns a stream consisting of the distinct elements (according to Object.equals(Object)) of this stream.

 

计数

longcount()

Returns the count of elements in this stream.

 

 

过滤

Stream<T>filter(Predicate<? super T> predicate)

Returns a stream consisting of the elements of this stream that match the given predicate.

 

 遍历

voidforEach(Consumer<? super T> action)

Performs an action for each element of this stream.

voidforEachOrdered(Consumer<? super T> action)

Performs an action for each element of this stream, in the encounter order of the stream if the stream has a defined

 

最值 

Optional<T>max(Comparator<? super T> comparator)

Returns the maximum element of this stream according to the provided Comparator.

Optional<T>min(Comparator<? super T> comparator)

Returns the minimum element of this stream according to the provided Comparator.

 

 规约

规约操作又被称作折叠操作,是通过某个连接动作将所有元素汇总成一个汇总结果的过程

Optional<T>reduce(BinaryOperator<T> accumulator)

Performs a reduction on the elements of this stream, using an associative accumulation function, and returns an Optional describing the reduced value, if any.

Treduce(T identity, BinaryOperator<T> accumulator)

Performs a reduction on the elements of this stream, using the provided identity value and an associative accumulation function, and returns the reduced value.

<U> Ureduce(U identity, BiFunction<U,? super T,U> accumulator, BinaryOperator<U> combiner)

Performs a reduction on the elements of this stream, using the provided identity, accumulation and combining functions.

 

 map

对Stream每个元素都应用mapper函数

<R> Stream<R>map(Function<? super T,? extends R> mapper)

Returns a stream consisting of the results of applying the given function to the elements of this stream.

DoubleStreammapToDouble(ToDoubleFunction<? super T> mapper)

Returns a DoubleStream consisting of the results of applying the given function to the elements of this stream.

IntStreammapToInt(ToIntFunction<? super T> mapper)

Returns an IntStream consisting of the results of applying the given function to the elements of this stream.

LongStreammapToLong(ToLongFunction<? super T> mapper)

Returns a LongStream consisting of the results of applying the given function to the elements of this stream.

 

flatMap

<R> Stream<R>flatMap(Function<? super T,? extends Stream<? extends R>> mapper)

Returns a stream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.

DoubleStreamflatMapToDouble(Function<? super T,? extends DoubleStream> mapper)

Returns an DoubleStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.

IntStreamflatMapToInt(Function<? super T,? extends IntStream> mapper)

Returns an IntStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.

LongStreamflatMapToLong(Function<? super T,? extends LongStream> mapper)

Returns an LongStream consisting of the results of replacing each element of this stream with the contents of a mapped stream produced by applying the provided mapping function to each element.

 

collect操作

结合Collector完成更加复杂的操作

<R,A> Rcollect(Collector<? super T,A,R> collector)

Performs a mutable reduction operation on the elements of this stream using a Collector.

<R> Rcollect(Supplier<R> supplier, BiConsumer<R,? super T> accumulator, BiConsumer<R,R> combiner)

Performs a mutable reduction operation on the elements of this stream.

 

 案例

import java.util.*;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import java.util.stream.IntStream;
import java.util.stream.LongStream;
import java.util.stream.Stream;

public class StreamTest {
    public static void main(String[] args) {
        flatMapToInt();
    }

    private static void toMap() {
        List<String> list = new ArrayList<>();
        list.add("Mohan");
        list.add("Sohan");
        list.add("Mahesh");

        Map<String, String> collect = list.stream().collect(Collectors.toMap(Function.identity(), s -> s));
        System.out.println(collect);

        List<Book> bookList = new ArrayList<>();
        bookList.add(new Book("Core Java", 200));
        bookList.add(new Book("Learning Freemarker", 150));
        bookList.add(new Book("Spring MVC", 300));

        // 如果key对应多个value ,Collectors.toMap会报错
        Map<String, Integer> bookMap = bookList.stream().collect(Collectors.toMap(Book::getName, Book::getPrice));
        System.out.println(bookMap);

        // 模拟key对应多个值
        bookList.add(new Book("Spring MVC", 300));
        bookList.add(new Book("Core Java", 200));
        // toMap使用Merge Function (v1, v2) -> v1 + "," + v2) 将key对应的多个值以逗号隔开
        Map<Integer, String> priceKeyNameValueMap = bookList.stream()
                .collect(Collectors.toMap(Book::getPrice, Book::getName, (v1, v2) -> v1 + "," + v2));
        System.out.println(priceKeyNameValueMap);

        // 使用Map Supplier 指定返回的Map的类型
        LinkedHashMap<Integer, String> linkedHashMap = bookList.stream()
                .collect(Collectors.toMap(Book::getPrice, Book::getName, (v1, v2) -> v1 + "," + v2, LinkedHashMap::new));
    }

    private static void mapToLong() {
        LongStream longStream = Stream.of("1", "2", "3").mapToLong(Long::valueOf);
        long sum = longStream.sum();
        System.out.println(sum);
    }

    private static void mapToInt() {
        IntStream intStream = Stream.of("1", "2", "3").mapToInt(Integer::valueOf);
        List<Integer> collect = intStream.collect(ArrayList::new, ArrayList::add, ArrayList::addAll);
        System.out.println(collect);

        int sum = Stream.of("1", "2", "3").mapToInt(Integer::valueOf).sum();
        System.out.println(sum);
    }

    private static void sorted() {
        Map<Integer, String> map = new HashMap<>();
        map.put(1, "BBBB");
        map.put(2, "AAAA");
        map.put(3, "CCCC");

        System.out.println("---Sort by Map Value---");
        map.entrySet().stream().sorted(Comparator.comparing(Map.Entry::getValue))
                .forEach(e -> System.out.println("Key: " + e.getKey() + ", Value: " + e.getValue()));
    }

    private static void reduce() {
        int[] array = {3, 5, 10, 15};
        IntStream intStream = Arrays.stream(array);
        int sum = intStream.reduce(0, (x, y) -> x + y);
        System.out.println("Sum:" + sum);

        OptionalInt intOptional = Arrays.stream(array).reduce(Integer::sum);
        intOptional.ifPresent(System.out::println);

        List<Integer> list2 = Arrays.asList(5, 6, 7);
        Stream<Integer> integerStream = list2.parallelStream();
        Integer reduce = integerStream.reduce(0, Integer::sum, (p, q) -> p * q);
        System.out.println(reduce);

    }

    private static void flatMapToInt(){
        int[][] data = {{1,2},{3,4},{5,6}};
        IntStream intStream = Arrays.stream(data).flatMapToInt(row -> Arrays.stream(row));
        int sum = intStream.sum();
        System.out.println(sum);
    }

    private static void flatMap() {
        Integer[][] data = {{1, 2}, {3, 4}, {5, 6}};
        Stream<Integer> integerStream = Arrays.stream(data).flatMap(row -> Arrays.stream(row));
        integerStream.filter(num -> num % 2 == 1)
                .forEach(s -> System.out.print(s + " "));
    }

    private static void map() {

        List<Integer> list = Arrays.asList(1, 2, 3, 4);
        list.stream().map(i -> i * i)
                .forEach(s -> System.out.print(s + " "));

        Integer[][] data = {{1, 2}, {3, 4}, {5, 6}};
        Stream<Stream<Integer>> streamStream = Arrays.stream(data).map(row -> Arrays.stream(row));
        streamStream.map(inner -> inner.filter(num -> num % 2 == 1))
                .forEach(inner -> inner.forEach(s -> System.out.print(s + " ")));
    }

    private static void distinct() {
        List<Book> list = new ArrayList<>();
        {
            list.add(new Book("Core Java", 200));
            list.add(new Book("Core Java", 200));
            list.add(new Book("Learning Freemarker", 150));
            list.add(new Book("Spring MVC", 300));
            list.add(new Book("Spring MVC", 300));
        }

        long l = list.stream().distinct().count();
        System.out.println("No. of distinct books:" + l);
        // 自定义对象Book,重写了equal和hashCode方法
        System.out.println("-----distinct------");
        list.stream().distinct().forEach(b -> System.out.println(b.getName() + "," + b.getPrice()));

        // 自定义去重:根据姓名去重
        System.out.println("----distinctByByName-----");
        list.stream().filter(distinctByKey(book -> book.getName()))
                .forEach(System.out::println);

        // 自定义去重:根据价格去重
        System.out.println("-----distinctByByPrice-----");
        list.stream().filter(distinctByKey(book -> book.getPrice()))
                .forEach(System.out::println);
    }

    // distinct是按照equal和hashCode比较元素是否相等,我们也可以自定义比较相等规则
    private static <T> Predicate<T> distinctByKey(Function<? super T, ?> keyExtractor) {
        Map<Object, Boolean> map = new HashMap<>();
        return t -> map.putIfAbsent(keyExtractor.apply(t), Boolean.TRUE) == null;
    }

    static class Book {
        private String name;
        private int price;

        public Book(String name, int price) {
            this.name = name;
            this.price = price;
        }

        public String getName() {
            return name;
        }

        public int getPrice() {
            return price;
        }

        @Override
        public boolean equals(final Object obj) {
            if (obj == null) {
                return false;
            }
            final Book book = (Book) obj;
            if (this == book) {
                return true;
            } else {
                return (this.name.equals(book.name) && this.price == book.price);
            }
        }

        @Override
        public int hashCode() {
            int hashno = 7;
            hashno = 13 * hashno + (name == null ? 0 : name.hashCode());
            return hashno;
        }

        @Override
        public String toString() {
            return "Book{" +
                    "name='" + name + '\'' +
                    ", price=" + price +
                    '}';
        }
    }

    private static void concat() {
        Stream<String> concatStream = Stream.concat(Stream.of("a", "b", "c"), Stream.of("b", "c", "d"))
                .distinct();
        concatStream.forEach(System.out::print);
    }

    private static void findAny() {
        List<String> list = Arrays.asList("Mahesh", "Suresh", "Mohit");
        String output = list.stream()
                .filter(e -> e.startsWith("M"))
                .findAny()
                .orElse("NA");
        System.out.println(output);

        List<Integer> numList = Arrays.asList(21, 22, 23, 24);
        numList.stream()
                .filter(n -> n % 2 == 0)
                .findAny()
                .ifPresent(e -> System.out.println(e));
    }

    private static void findFirst() {
        Stream.of(50, 60, 70).findFirst()
                .ifPresent(s -> System.out.println(s));

        List<String> list = Arrays.asList("Vijay", "Suresh", "Vinod");
        String output = list.stream()
                .filter(e -> e.startsWith("V")) // Vijay, Vinod
                .findFirst() //Vijay
                .orElse("NA");
        System.out.println(output);

        List<Integer> numList = Arrays.asList(31, 32, 33, 34);
        numList.stream()
                .filter(n -> n % 2 == 0) // 32, 34
                .findFirst() //32
                .ifPresent(e -> System.out.println(e));
    }

    private static void count_min_max() {
        long count = Stream.of(10, 20, 30).count();
        System.out.println("Count:" + count);

        List<Integer> numList = Arrays.asList(42, 44, 43, 41);

        Comparator<Integer> comparator = Comparator.comparing(Integer::intValue);
        Optional<Integer> miOptional = numList.stream().min(comparator);
        miOptional.ifPresent(e -> System.out.println("Min:" + e));

        Optional<Integer> maxOptional = numList.stream().max(Integer::compare);
        maxOptional.ifPresent(e -> System.out.println("Max:" + e));
    }

    private static void iterate() {
        // 指定一个初始值, 作为UnaryOperator的入参, 生成一个无限的stream
        Stream<Integer> stream = Stream.iterate(1, n -> n * 2).limit(5);
        stream.forEach(s -> System.out.print(s + " "));
    }

    private static void generate() {
        List<Integer> collect = Stream.generate(new Random()::nextInt)
                .limit(3)
                .collect(Collectors.toList());
        collect.forEach(System.out::println);
    }

    private static void peek() {
        // peek是中间操作,在调用终止操作后,才会输出
        Stream.of(10, 20, 30).peek(e -> System.out.println(e));
        Stream.of(10, 20, 30).peek(e -> System.out.println(e))
                .collect(Collectors.toList());

        Stream.of(10, 11, 12, 13)
                .filter(n -> n % 2 == 0)
                .peek(e -> System.out.println("Debug filtered value: " + e))
                .map(n -> n * 10)
                .peek(e -> System.out.println("Debug mapped value: " + e))
                .collect(Collectors.toList());

        List<String> list = Arrays.asList("AA", "BB", "CC", "BB", "CC", "AA", "AA");
        String output = list.stream()
                .distinct()
                .peek(e -> System.out.println("Debug value: " + e))
                .collect(Collectors.joining(","));
        System.out.println(output);

        List<String> debugList = new ArrayList<>();
        List<String> names = Arrays.asList("Mahesh", "Suresh", "Mahendra");
        names.stream()
                .filter(el -> el.startsWith("M"))
                .peek(e -> debugList.add(e))
                .collect(Collectors.toList());
        System.out.println(debugList);
    }

    private static void skip_limit() {
        List<Integer> list = new ArrayList(Arrays.asList(1, 2, 3, 4, 5, 6, 7));
        List<Integer> afterLimit = list.stream().limit(4).collect(Collectors.toList());
        List<Integer> afterSkip = list.stream().skip(4).collect(Collectors.toList());

        System.out.println("Limit:" + afterLimit);
        System.out.println("Skip:" + afterSkip);
    }

    private static void toArray() {
        List<String> list = Arrays.asList("A", "B", "C", "D");
        String[] strings = list.stream().toArray(String[]::new);
        System.out.println(Arrays.toString(strings));

        strings = list.stream().toArray(size -> new String[size]);
        System.out.println(Arrays.toString(strings));

        int[] ints = IntStream.of(10, 20, 30, 50).toArray();
        System.out.println(Arrays.toString(ints));

        int[] ints1 = IntStream.range(10, 20).toArray();
        System.out.println(Arrays.toString(ints1));

        int[] ints2 = Stream.of(1, 3, 4).mapToInt(i -> i * 2).toArray();
        System.out.println(Arrays.toString(ints2));

        String[] strings1 = Stream.of("Java", "Angular", "Spring").collect(Collectors.toList()).toArray(new String[0]);
        System.out.println(Arrays.toString(strings1));
    }

    private static void forEachAndForEachOrdered() {
        Stream.of("A", "B", "C", "D").forEach(System.out::print);
        System.out.println();
        Stream.of("A", "B", "C", "D").forEachOrdered(System.out::print);
        System.out.println();

        // 在并行操作下forEach不能保证顺序
        Stream.of("A", "B", "C", "D").parallel().forEach(System.out::print);
        System.out.println();
        // forEachOrdered能保证顺序,不管是顺序流还是并行流
        Stream.of("A", "B", "C", "D").parallel().forEachOrdered(System.out::print);
    }
}

希望对大家熟悉api有一定的帮助

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

hello_中年人

你的鼓励是我最大的动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值