java8 Stream 史上最全總結

java8 Stream 史上最全總結

溫馨提醒:在電腦上看更方便

(一)stream的特點

一、 流操作都支持 lambda 表達式作爲參數 ,函數式編程,充分利用了pipeline 思想

二、無修改 ,無儲存

對原始數據無修改,對流和流的中間結果無儲存

三 、 惰性執行

四、可以併發執行 , paralleStream

五、 默認只消費一次

1) 巧妙避免代碼重複的方式 Supplier


 
  1. Supplier<Stream<String>> streamSupplier = () -> Stream.of("1", "2").filter(t -> t.equals("1"));

  2. final Optional<String> any = streamSupplier.get().findAny();//1

  3. final Optional<String> first = streamSupplier.get().findFirst();//2

六、Map 不支持 stream 流

(二)函數接口簡介

1)一元函數式接口

接口 參數 返回類型 描述
Predicate T boolean 斷言型接口
Consumer T void 消費型接口
Function T R 函數式接口
Supplier None T 供給型接口

2) 二元函數接口

接口 參數 返回類型 描述
BiFunction T, U R Function的變體
BiConsumer T, U void Consumer的變體
BiPredicate T, U boolean Predicate的變體

BiConsumer


 
  1. final HashMap<Object, Object> objectObjectHashMap = Maps.newHashMap();

  2. final BiConsumer biConsumer = (k, v) -> {

  3. System.out.println(k);

  4. System.out.println(v);

  5. };

  6. objectObjectHashMap.forEach(biConsumer);

BiPredicate


 
  1. Path testPath = Paths.get("/Users/qiaozhy/data");

  2. //finding files containing 'items' in name

  3. final BiPredicate<Path, BasicFileAttributes> items = (path, basicFileAttributes) -> {

  4. File file = path.toFile();

  5. return !file.isDirectory() &&

  6. file.getName().contains("items");

  7. };

  8. Stream<Path> stream =

  9. Files.find(testPath, 100,items

  10. );

  11. stream.forEach(System.out::println);

3) 擴展的運算符

BinaryOperator 繼承BiFunction


 

  1. BinaryOperator<Integer> add = (n1, n2) -> n1 + n2;

UnaryOperator 繼承Function


 
  1. UnaryOperator<Integer> dda = x -> x + 1;

(三)stream的操作

一、 流的創建 (最終都是依賴底層的StreamSupport類來完成Stream創建)

1) Collection 和數組

Collection.stream()

Collection.parallelStream()

  •  
  •  
  •  
  •  
  •  
final Stream<String> stream = Arrays.asList("11", "22").stream();final ArrayList<String> list = Lists.newArrayList();list.add("33");final Stream<String> stream3 = list.stream();final Stream<String> stringStream2 = list.parallelStream();

2) BufferedReader

java.io.BufferedReader.lines()

  •  
  •  
  •  
  •  
  •  
  •  
File file = new File("/Users/qiaozhy/data/qiao.txt");Reader reader  = new FileReader(file);BufferedReader bufferedReader = new BufferedReader(reader);final Stream<String> lines = bufferedReader.lines();final long count = lines.count();System.out.println(count);//2

 

3) 靜態工廠

Arrays.stream(T array)

Stream.of()、iterate()、generate()

java.util.stream.IntStream.range()

java.nio.file.Files.list、find、walk等

Stream.builder()


 
  1. final IntStream intStream1 = Arrays.stream(new int[]{1, 2, 3});

  2.  

  3.  

  4. final Stream<String> stringStream = Stream.of("11", "22");

  5.  

  6. final Stream<Integer> iterate = Stream.iterate(5, t -> t + 1);

  7. iterate.limit(4).forEach(System.out::println);//5,6,7,8

  8.  

  9. //supplier 函數式接口的簡化 (Math::random)

  10. Stream.generate(Math::random).limit(1).forEach(System.out::println);

  11. // 0.48158792725573907

  12.  

  13. final IntStream intStream = IntStream.range(1, 3);

  14.  

  15.  

  16. final Optional<Path> first = Files.walk(Paths.get("/Users/qiaozhy/data"))

  17. .peek(System.out::println).skip(2).findAny();

  18. first.orElseThrow(()-> new RuntimeException("結果爲空"));

  19. System.out.println(first.get());//Users/qiaozhy/data/工作注意.txt

  20.  

  21. final Stream.Builder<Object> builder1 = Stream.builder();

  22. builder1.accept(66);

  23. builder1.add(2).add(3);

  24. builder1.build().forEach(System.out::println); // 66,2,3

4)其他

Pattern.splitAsStream(java.lang.CharSequence)

Random.ints()

JarFile.stream()

BitSet.stream()


 
  1. final Pattern pattern = Pattern.compile(",");

  2. final Stream<String> stringStream1 = pattern.splitAsStream("a,y,u");

  3. stringStream1.forEach(System.out::println);// a,y,u

  4.  

  5. Random random = new Random();

  6. final IntStream intStream2 = random.ints(1,20);

  7. intStream2.limit(2).forEach(System.out::println); // 5,18

  8.  

  9. JarFile jarFile = new JarFile("/Users/qiaozhy/.m2/javacc-5.0.jar");

  10. final Stream<JarEntry> stream1 = jarFile.stream();

  11. stream1.limit(1).forEach(System.out::println); //META-INF/

  12.  

  13. BitSet bitSet = new BitSet();

  14. bitSet.set(1);

  15. bitSet.set(45);

  16. final IntStream stream2 = bitSet.stream();

  17. stream2.forEach(System.out::println); // 1,45

二、 中間操作

無狀態(Stateless)操作:每個數據的處理是獨立的,不會影響或依賴之前的數據。如

filter()flatMap()flatMapToDouble()flatMapToInt()flatMapToLong()map()mapToDouble()mapToInt()mapToLong()peek()unordered()

unordered操作不會進行任何顯式的打亂流的操作。它的工作是:消除流中必須保持的有序約束,因此允許之後的操作使用 不必考慮有序的優化

有狀態(Stateful)操作:處理時會記錄狀態,比如處理了幾個。後面元素的處理會依賴前面記錄的狀態,或者拿到所有元素才能繼續下去。如

distinct()sorted()sorted(comparator)limit()skip()


 
  1. String [] arr = {"a","b","ed","c"};

  2. final List<String> collect = Arrays.stream(arr).sorted(Comparator.comparing(String::length)).collect(Collectors.toList());

  3. System.out.println(collect);//[a, b, c, ed]

  4. final List<String> collect1 = Arrays.stream(arr).sorted(Comparator.reverseOrder()).collect(Collectors.toList());

  5. System.out.println(collect1);//[ed, c, b, a]

  6. final Optional<String> any = Arrays.stream(arr).distinct().skip(1).limit(1).findAny();

  7. any.orElseThrow(()-> new RuntimeException("結果爲空"));

  8. final String s = any.get();

  9. System.out.println(s);//b


 
  1. String[] words = new String[]{"Hello","World"};

  2. Arrays.stream(words)

  3. .map(word -> word.split(""))

  4. .flatMap(Arrays::stream)

  5. .forEach(System.out::print);

  6. //HelloWorld

  7. List<String> first= Arrays.asList("one", "two", "three", "four");

  8. List<String> second= Arrays.asList("A", "B", "C", "D");

  9. Stream.of(first,second).flatMap(Collection::stream).forEach(System.out::print);//onetwothreefourABCD


 
  1. Stream.of(1.0,2.0,3.0).mapToInt(Double::intValue).mapToObj(i->"a"+i).forEach(System.out::print);

三、終止操作

非短路操作:處理完所有數據才能得到結果。如

collect()count()forEach()forEachOrdered()max()min()reduce()toArray()等。

短路(short-circuiting)操作:拿到符合預期的結果就會停下來,不一定會處理完所有數據。如

anyMatch()allMatch()noneMatch()findFirst()findAny()


 
  1. List<String> strs = Arrays.asList("a", "a", "a", "a", "b");

  2. boolean aa = strs.stream().anyMatch(str -> str.equals("a"));

  3. System.out.println(aa);//true

  4. boolean bb = strs.stream().allMatch(str -> str.equals("a"));

  5. System.out.println(bb);//false

  6. boolean cc = strs.stream().noneMatch(str -> str.equals("a"));

  7. System.out.println(cc);//false


 
  1. String [] arr = {"a","b","ed","c"};

  2. final Optional<String> reduce = Arrays.stream(arr).reduce((a, b) -> a + b);

  3. reduce.orElseThrow(()-> new RuntimeException("結果爲空"));

  4. System.out.println(reduce.get());//abedc

  5.  

  6. List<Integer> numList = Arrays.asList(1,2,3,4,5);

  7. int result = numList.stream().reduce(0,(a,b) -> a + b );

  8. System.out.println(result);

  9.  

  10. List<Integer> numList1 = Arrays.asList(1, 2, 3, 4, 5, 6);

  11. ArrayList<String> result1 = numList1.stream().reduce(new ArrayList<String>(),

  12. (a, b) -> {

  13. a.add("element-" + Integer.toString(b));

  14. return a;

  15. }, (a, b) -> null);

  16. System.out.println(result1);

  17. /*

  18. 需要注意的是這個reduce的簽名還包含第三個參數,一個BinaryOperator<U>類型的表達式。

  19. 在常規情況下我們可以忽略這個參數,敷衍了事的隨便指定一個表達式即可,目的是爲了通過編譯器的檢查,

  20. 因爲在常規的stream中它並不會被執行到,然而, 雖然此表達式形同虛設,可是我們也不是把它設置爲null,

  21. 否者還是會報錯。 在並行stream中,此表達式則會被執行到,在這裏我們不進行講解,因爲我自己也沒用過

  22. */


 
  1. Supplier<Stream<String>> streamSupplier = () -> Stream.of("a","d","b");

  2. //輸出的順序與元素的順序嚴格一致

  3. streamSupplier.get().parallel().forEachOrdered(System.out::println);//a,d,b

  4. //主要的區別在並行流的處理上

  5. //輸出的順序不一定(效率更高)

  6. streamSupplier.get().parallel().forEach(System.out::println); // d,a,b

  7.  

  8. final String[] strings = streamSupplier.get().toArray(String[]::new);

  9. System.out.println(Arrays.toString(strings));//[a, d, b]


 
  1. final ArrayList<String> list = Lists.newArrayList();

  2. list.add("12");

  3. list.add("111");

  4. final List<String> collect = list.stream().collect(Collectors.toList());

  5. final Set<String> collect1 = list.stream().collect(Collectors.toSet());

  6. final Map<Integer, String> collect2 = list.stream().collect(Collectors.toMap(String::length, String::valueOf));

  7.  

  8. final Long lo = list.stream().collect(Collectors.counting());

  9.  

  10. final IntSummaryStatistics intSummaryStatistics = list.stream().collect(Collectors.summarizingInt(Integer::valueOf));

  11.  

  12. final String collect3 = list.stream().collect(Collectors.joining("--"));

  13.  

  14. final Optional<String> collect4 = list.stream().collect(Collectors.reducing((x, y) -> x + y));

  15.  

  16. final Map<Integer, List<String>> collect5 = list.stream().collect(Collectors.groupingBy(String::length));

  17.  

  18. final Optional<Integer> collect6 = list.stream().map(Integer::valueOf).collect(Collectors.maxBy(Integer::max));

(四 )、並行流

在創建Stream時,默認是創建串行流。但是可以使用parallelStream()來創建並行流或者parallel()將串行流轉換成並行流。並行流也可以通過sequential()轉換成串行流。

Java 8 Stream的並行流,本質上還是使用Fork/Join模型

(五)、特殊用法


 
  1. // map的循環方式

  2. final HashMap<Object, Object> objectObjectHashMap = Maps.newHashMap();

  3. objectObjectHashMap.put("1","2");

  4. objectObjectHashMap.put("5","77");

  5. objectObjectHashMap.forEach((a,b)->{

  6. System.out.println(a);

  7. System.out.println(b);

  8. });

 


如果喜歡,歡迎關注我的公衆號:喬志勇筆記

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章