java8 Stream-創建流的幾種方式

前面(《java8 Stream接口簡介》),我們已經對stream這個接口,做了簡單的介紹,下面,我們用幾個案例,來看看流的幾種創建方式

        String[] dd = { "a", "b", "c" };
        Arrays.stream(dd).forEach(System.out::print);// abc
        System.out.println();
        Stream.of(dd).forEach(System.out::print);// abc
        System.out.println();
        Arrays.asList(dd).stream().forEach(System.out::print);// abc
        System.out.println();
        Stream.iterate(0, x -> x + 1).limit(10).forEach(System.out::print);// 0123456789
        System.out.println();
        Stream.generate(() -> "x").limit(10).forEach(System.out::print);// xxxxxxxxxx

1.Arrays.stream,我們可以通過Arrays的靜態方法,傳入一個泛型數組,創建一個流

2.Stream.of,我們可以通過Stream的靜態方法,傳入一個泛型數組,或者多個參數,創建一個流,這個靜態方法,也是調用了Arrays的stream靜態方法,如下

@SafeVarargs
    @SuppressWarnings("varargs") // Creating a stream from an array is safe
    public static<T> Stream<T> of(T... values) {
        return Arrays.stream(values);
    }


3.Collection.stream,可以用過集合的接口的默認方法,創建一個流;使用這個方法,包括繼承Collection的接口,如:Set,List,Map,SortedSet 等等,詳細的,可以看Collection接口上的定義註釋,如下

/**
 * @author Josh Bloch
 * @author Neal Gafter
 * @see Set
 * @see List
 * @see Map
 * @see SortedSet
 * @see SortedMap
 * @see HashSet
 * @see TreeSet
 * @see ArrayList
 * @see LinkedList
 * @see Vector
 * @see Collections
 * @see Arrays
 * @see AbstractCollection
 * @since 1.2
 */
public interface Collection<E> extends Iterable<E> {
    default Stream<E> stream() {
        return StreamSupport.stream(spliterator(), false);
    }
}

4.Stream.iterate,是Stream接口下的一個靜態方法,從名字也可以看出,這個靜態方法,是以迭代器的形式,創建一個數據流,具體的靜態方法定義如下:

public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f) {
        Objects.requireNonNull(f);
        final Iterator<T> iterator = new Iterator<T>() {
            @SuppressWarnings("unchecked")
            T t = (T) Streams.NONE;
 
            @Override
            public boolean hasNext() {
                return true;
            }
 
            @Override
            public T next() {
                return t = (t == Streams.NONE) ? seed : f.apply(t);
            }
        };
        return StreamSupport.stream(Spliterators.spliteratorUnknownSize(
                iterator,
                Spliterator.ORDERED | Spliterator.IMMUTABLE), false);
    }

靜態方法定義以及代碼中,可以看到,傳入兩個參數,一個泛型T對象,表示數據的起始,一個函數式接口UnaryOperator(不知道這個接口的,JAVA8 UnaryOperator接口,有詳細介紹),從迭代器hasNext中,可以看到,返回一直爲true,表示迭代器,會一直執行下去,創建的數據集合的值爲泛型T對象;這樣一直創建無限個對象的流,也成爲無限流;

5.Stream.generate,也是stream中的一個靜態方法,靜態方法定義如下:

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

從靜態方法定義中,可以看到,傳入一個函數式接口Supplier(不知道這個接口是什麼意義的,可以移步這邊,JAVA8 Supplier接口有詳細介紹);這個靜態方法,也是無限生成對象的集合流,也是一個無限流;

最後介紹下,1-3,是根據具體的數組或者集合對象,創建的流,在創建流之前,這些對象的大小(長度)已經確認,所以這個種方式的流,也被成爲有限流,而4-5中,創建流的方式,是無限大小的流(generate 最大是Long.MAX_VALUE),也被成爲無限流,那麼我們不可能就這樣放任對象被無限創建,直到內存溢出,這樣的無限流,也是配合limit使用,指定這個流生成的元素的個數,對於無限流,下面再簡單講個案例,使用傳統的方式和無限流的方式,創建一個固定大小的ArrayList,這樣大家也會有比較清楚的認識;

應用場景:我們再做B端系統的時候,會遇到很多的統計類的需求,會用到百度的echarts插件,比如曲線圖,在x抽,固定的況下(按月統計 1號-31號,或者按年統計1月-12月,或者按天24個小時的刻度),那麼我就需要創建一個這個數組,或者集合,代碼如下:

public static void main(String[] args) {
        System.out.println(buildList(100));
        System.out.println(buildIterate(100));
    }
 
    public static List<Integer> buildList(final int size) {
        List<Integer> list = new ArrayList<>(size);
        for (int i = 1; i <= size; i++) {
            list.add(i);
        }
        return list;
    }
 
    public static List<Integer> buildIterate(final int size) {
        return Stream.iterate(1, x -> ++x).limit(size).collect(Collectors.toList());
    }

可以看到,使用流,可以更加簡便,也更加直觀的表現出代碼的功能

 

1.lambda表達式
《java8 Lambda表達式簡介》

《java8 lambda表達式,方法的引用以及構造器的引用》

2.函數式接口
《java8 函數式接口簡介》

《JAVA8 Function接口以及同類型的特化的接口》

《JAVA8 Consumer接口》

《JAVA8 Supplier接口》

《JAVA8 UnaryOperator接口》

《JAVA8 BiConsumer 接口》

3.stream接口操作

《java8 Stream接口簡介》

《 java8 Stream-創建流的幾種方式》

《JAVA8 stream接口 中間操作和終端操作》

《JAVA8 Stream接口,map操作,filter操作,flatMap操作》

《JAVA8 stream接口 distinct,sorted,peek,limit,skip》

《java8 stream接口 終端操作 forEachOrdered和forEach》

《java8 stream接口 終端操作 toArray操作》

《java8 stream接口 終端操作 min,max,findFirst,findAny操作》

《java8 stream接口終端操作 count,anyMatch,allMatch,noneMatch》

《java8 srteam接口終端操作reduce操作》

《java8 stream接口 終端操作 collect操作》

4.其他部分

《java8 Optional靜態類簡介,以及用法》

發佈了13 篇原創文章 · 獲贊 12 · 訪問量 4542
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章