1. 程式人生 > >Java8:建立Stream

Java8:建立Stream

Stream是Java8的重要特性之一。那麼生成Stream的方式有哪些? 1, 通過Collections類,2,通過靜態方法,例如IntStream.range,Files.walk方法等, 3,藉助Java.util.Spliterator,有關stream的更詳細內容後面會介紹,這裡只是簡單給出生成stream的例子。

下面通過程式碼示例一一展示。

第一種,通過Collections類 

        List<String> stringCollection = new ArrayList<>();         stringCollection.add("ddd2");         stringCollection.add("aaa2");         stringCollection.add("bbb1");         stringCollection.add("aaa1");         stringCollection.add("bbb3");         stringCollection.add("ccc4");         stringCollection.add("bbb2");         stringCollection.add("ddd1");

        stringCollection         .stream()         .filter((s) -> s.startsWith("a"))         .forEach(System.out::println);

第二種,通過靜態方法

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

public class FilesWalk {     public static void main(String[] args) {         final Path path = Paths.get("C:\\Afolder");         int maxDepth = 5;         try( Stream<Path> entries = Files.walk(path, maxDepth) ) {             entries.onClose( () -> System.out.println("Done!") ).forEach(                 p -> {                          System.out.println(p.toFile().getAbsolutePath());                     }                  );         }         catch (IOException e) {             e.printStackTrace();         }     } } 第三種,藉助java.util.Spliterator;

import java.util.ArrayList; import java.util.Spliterator; import java.util.stream.StreamSupport; import java.util.stream.Stream;

public class SpliteratorDemo {

    public static void main(String[] args) {         ArrayList<Integer> number_List = new ArrayList<>();          Spliterator<Integer> mySpliterator, myParallelSpliterator;

        number_List.add(1);         number_List.add(2);         number_List.add(3);         number_List.add(4);         number_List.add(5);

        mySpliterator = number_List.spliterator();         myParallelSpliterator = number_List.spliterator();

        System.out.println("Characteristics Of Spliterator are : "+mySpliterator.characteristics());         System.out.println("estimateSize Of Spliterator is : "+mySpliterator.estimateSize());

        Stream<Integer> intStream = StreamSupport.stream(mySpliterator.trySplit(), false);         Stream<Integer> intStream2 = StreamSupport.stream(mySpliterator.trySplit(), false);         Stream<Integer> intStream3 = StreamSupport.stream(mySpliterator.trySplit(), false);         //Stream<Integer> intStream4 = StreamSupport.stream(mySpliterator.trySplit(), false);         Stream<Integer> intStream4 = StreamSupport.stream(myParallelSpliterator.trySplit(), true);         System.out.println("All elements");         intStream         .filter((p) -> (p < 9))         .forEach(System.out::println);

        System.out.println("All elements");         intStream2         .forEach(System.out::println);

        System.out.println("All elements");         intStream3         .forEach(System.out::println);

        System.out.println("All elements");         intStream4         .forEach(System.out::println);     } }  

列舉建立Stream<T>、IntStream(LongStream、DoubleStream)物件的一些常見例子。

1.by Values or Collection (1)因為Stream<T>的靜態方法of

    public static<T> Stream<T> of(T... values) {         return Arrays.stream(values);     }

通過一系列值建立流物件,與Arrays.stream(過載)一致,兩者放在一起。

Stream<T> of(T... values) 按照引數型別建立Stream<T> 物件。如Stream<String>、Stream<Integer>

Stream<T> of(T t)按照引數型別建立只有一個元素的流物件。

(2)Arrays.stream()

Arrays.stream(int[] array) 建立IntStream流物件(long[]、double[]類似),注意不是Stream<Integer>。

Arrays.stream(T[] array)物件陣列為引數建立Stream<T> ,如Stream<String>。

對於集合,使用Collection<E>的預設方法stream()

    default Stream<E> stream() {         return StreamSupport.stream(spliterator(), false);     }

    public static void fromValues() {         Stream<String> s = Stream.of("create", "Stream", "by", "Stream.of");         Stream<Integer> s2 = Stream.of(1,2,3);         int[] array = {1, 2, 3};         Stream<int[]> s3 = Stream.of(array);         s3.forEach(System.out::println); //[[email protected]     }       public static void fromCollection() {         int[] array = {1, 2, 3};         IntStream stream = Arrays.stream(array);//注意         int sum = stream.sum();         String[] strArray = {"a","b"};         Stream<String> stream1 = Arrays.stream(strArray);             List<String> myList = Arrays.asList("a1", "a2","a1");         Stream<String> stream2 = myList.stream();         stream2.forEach(System.out::print);                       //a1a2a1         System.out.println();         HashSet<String> set = new HashSet<>(myList);         Stream<String> stream3 = set.stream();         stream3.forEach(System.out::print);                         //a1a2     } 從值、陣列和List、Set等建立流物件,是最基本的。 2.無限流 Stream的靜態方法iterate和generate可以建立無限流,因此需要在適當的時候限制一下流元素的長度。

public static<T> Stream<T> iterate(final T seed, final UnaryOperator<T> f)

public static<T> Stream<T> generate(Supplier<T> s)

iterate的種子的型別決定了流的型別引數,一元操作不斷應用於前一個元素。

generate使用一個Supplier<T>作為產生無限流的依據。下面例子分別使用了

Supplier<String> supplier =()->{return "a";}; 

和Math的random()函式。

    public static void infiniteStream() {         Stream<Integer> stream_int = Stream.iterate(0, n -> n + 2);         stream_int.limit(5).forEach(s -> System.out.print(s + " "));         System.out.println();                  Stream<String> stream_str = Stream.iterate("a", s -> s + "a");         stream_str.limit(5).forEach(s -> System.out.print(s + " "));         System.out.println();                  Stream<Double> stream_double = Stream.generate(Math::random).limit(3);         stream_double.forEach(s -> System.out.print(s + " "));         System.out.println();         Supplier<String> supplier =()->{return "a";};         Stream<String> stream_str2 = Stream.generate(supplier).limit(3);         stream_str2.forEach(s -> System.out.print(s + " "));             } 輸出: 0 2 4 6 8  a aa aaa aaaa aaaaa  0.537544433840739 0.18913558672368358 0.007618540214730407  a a a

列印Fibonacci數列的前10項。iterate的種子new int[]{0, 1},產生 (0,1), (1, 1), (1,2), (2, 3), (3, 5), (5, 8), (8, 13), (13, 21)...流

        Stream<int[]> iterate = Stream.iterate(new int[]{0, 1},                 t -> new int[]{t[1], t[0] + t[1]});         iterate.limit(10).forEach(t -> Print.pln(t)); 注:Print有方法     public static void pln(int[] arr){         System.out.println(java.util.Arrays.toString(arr));     }

輸出:

[0, 1] [1, 1] [1, 2] [2, 3] [3, 5] [5, 8] [8, 13] [13, 21] [21, 34] [34, 55]

3.範圍 對於int和long資料,一個常見的用法是按照一個range,生成IntStream或LongStream物件。

rangeClosed(int startInclusive, int endInclusive)  數學上表示為[a,b];range(int a, int b) 數學上表示為[a,b)。

    public static void rangesStream() {         IntStream stream_int = IntStream.rangeClosed(1, 4);         stream_int.forEach(s -> System.out.print(s + " "));         System.out.println();         LongStream.range(1, 4).forEach(s -> System.out.print(s + " "));     } 輸出: 1 2 3 4  1 2 3