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