package com.tdlx.springboot_shiro_jwt.syscommon.utils; import java.util.*; import java.util.function.Function; import java.util.stream.*; import static java.util.stream.Collectors.toList; //當循環遍歷中不須要進行數據庫操做時,使用stream()或普通循環來遍歷(根據實際業務狀況來選擇用哪一個)。 //當循環遍歷中(屢次循環,百次以上)須要進行數據庫操做時,使用parallelStream()來遍歷,可是要注意多線程安全 public class Streams { public static void main(String[] args) { streanFlatMap(); } //3.6 FlatMap 流的扁平化處理 public static void streanFlatMap() { List<List<Integer>> outer = new ArrayList<>(); List<Integer> inner1 = new ArrayList<>(); inner1.add(1); List<Integer> inner2 = new ArrayList<>(); inner1.add(2); List<Integer> inner3 = new ArrayList<>(); inner1.add(3); List<Integer> inner4 = new ArrayList<>(); inner1.add(4); List<Integer> inner5 = new ArrayList<>(); inner1.add(5); outer.add(inner1); outer.add(inner2); outer.add(inner3); outer.add(inner4); outer.add(inner5); //把流中集合裝換爲流 List<Integer> result = outer.stream().flatMap(inner -> inner.stream().map(i -> i + 1)).collect(toList()); System.out.println(result); System.out.println("############"); String[] strings = {"Hello", "World"}; //分步寫(流只能消費一次)(flatMap) Stream<String[]> stream1 = Arrays.asList(strings).stream(). map(str -> str.split("")); //把流中的String[]轉換成流 Stream<String> stringStream = stream1.flatMap(strings1 -> Arrays.stream(strings1)); List<String> stringList1 = stringStream.collect(toList()); stringList1.stream().forEach(System.out::println); System.out.println("############"); } //3.5 Collectors /*public static void streanCollectors() { Student s1 = new Student("aa", 10, 1); Student s2 = new Student("bb", 20, 2); Student s3 = new Student("cc", 10, 3); List<Student> list = Arrays.asList(s1, s2, s3); //裝成list List<Integer> ageList = list.stream().map(Student::getAge).collect(Collectors.toList()); // [10, 20, 10] //轉成set Set<Integer> ageSet = list.stream().map(Student::getAge).collect(Collectors.toSet()); // [20, 10] //轉成map,注:key不能相同,不然報錯 Map<String, Integer> studentMap = list.stream().collect(Collectors.toMap(Student::getName, Student::getAge)); // {cc=10, bb=20, aa=10} //字符串分隔符鏈接 String joinName = list.stream().map(Student::getName).collect(Collectors.joining(",", "(", ")")); // (aa,bb,cc) //聚合操做 //1.學生總數 Long count = list.stream().collect(Collectors.counting()); // 3 //2.最大年齡 (最小的minBy同理) Integer maxAge = list.stream().map(Student::getAge).collect(Collectors.maxBy(Integer::compare)).get(); // 20 //3.全部人的年齡 Integer sumAge = list.stream().collect(Collectors.summingInt(Student::getAge)); // 40 //4.平均年齡 Double averageAge = list.stream().collect(Collectors.averagingDouble(Student::getAge)); // 13.333333333333334 // 帶上以上全部方法 DoubleSummaryStatistics statistics = list.stream().collect(Collectors.summarizingDouble(Student::getAge)); System.out.println("count:" + statistics.getCount() + ",max:" + statistics.getMax() + ",sum:" + statistics.getSum() + ",average:" + statistics.getAverage()); //分組 Map<Integer, List<Student>> ageMap = list.stream().collect(Collectors.groupingBy(Student::getAge)); //多重分組,先根據類型分再根據年齡分 Map<Integer, Map<Integer, List<Student>>> typeAgeMap = list.stream().collect(Collectors.groupingBy(Student::getType, Collectors.groupingBy(Student::getAge))); //分區 //分紅兩部分,一部分大於10歲,一部分小於等於10歲 Map<Boolean, List<Student>> partMap = list.stream().collect(Collectors.partitioningBy(v -> v.getAge() > 10)); //規約 Integer allAge = list.stream().map(Student::getAge).collect(Collectors.reducing(Integer::sum)).get(); //4 }*/ //3.4 流的消費 如同於map,能獲得流中的每個元素。但map接收的是一個Function表達式,有返回值; // 而peek接收的是Consumer表達式,沒有返回值。 /*public static void streanMatch() { Student s1 = new Student("aa", 10); Student s2 = new Student("bb", 20); List<Student> studentList = Arrays.asList(s1, s2); studentList.stream() .peek(o -> o.setAge(100)) .forEach(System.out::println); //結果: Student{name='aa', age=100} Student{name='bb', age=100} }*/ //3.3 流的匹配 anyMatch(任何一個元素匹配,返回 true)、 // allMatch(全部元素匹配,返回 true)、noneMatch(沒有一個元素匹配,返回 true) public static void streanMatch() { boolean b = Stream.of(1, 2, 3, 4, 5, 10) .anyMatch(x -> x > 5); System.out.println(b); System.out.println("##################"); boolean b2 = Stream.of(1, 2, 3, 4, 5, 10) .allMatch(x -> x > 5); System.out.println(b2); System.out.println("##################"); boolean b3 = Stream.of(1, 2, 3, 4, 5, 10) .noneMatch(x -> x > 5); System.out.println(b3); } //3.2 流的查找 findFirst() findAny() public static void streanFind() { String[] strings = {"hello", "sihai", "hello", "Java8"}; Optional<String> first = Arrays.stream(strings) .findFirst(); System.out.println(first.get()); System.out.println("##################"); Optional<String> any = Arrays.stream(strings).findAny(); System.out.println(any.get()); System.out.println("##################"); //錯誤 // Optional<Object> any2 = Arrays.asList().stream().findAny(); // System.out.println(any2.get()); // System.out.println("##################"); } //3.1 流的操做 //Intermediate(中間)(並無真正開始流的遍歷):一個流能夠後面跟隨零個或多個 intermediate 操做。 //其目的主要是打開流,作出某種程度的數據映射/過濾,而後返回一個新的流,交給下一個操做使用。 //這類操做都是惰性化的(lazy),就是說,僅僅調用到這類方法,並無真正開始流的遍歷。 //Terminal(終端)(真正開始流的遍歷):一個流只能有一個 terminal 操做,當這個操做執行後,流就被使用「光」了,沒法再被操做。因此這一定是流的最後一個操做。 //Terminal 操做的執行,纔會真正開始流的遍歷,而且會生成一個結果,或者一個 side effect。 //Intermediate:map (mapToInt, flatMap 等)、 filter、 distinct、 sorted、 peek、 limit、 skip、 parallel、 sequential、 unordered //Terminal:forEach、forEachOrdered、toArray、reduce、 collect、 min、 max、 count、 anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 iterator //Short-circuiting:anyMatch、 allMatch、 noneMatch、 findFirst、 findAny、 limit public static void operate() { String[] strings = {"hello", "sihai", "hello", "Java8"}; Stream<String> stream = Arrays.stream(strings);//Stream 只能被使用一次 //filter過濾 對原始 Stream 進行某項測試,經過測試的元素被留下來生成一個新 Stream。 Stream<String> o = stream.filter(x -> x.contains("o")); o.forEach(System.out::println); System.out.println("filter##################"); //map 把 input Stream 的每個元素,映射成 output Stream 的另一個元素。 Arrays.stream(strings) .map(String::toUpperCase) .forEach(System.out::println); Stream.of(1, 2, 3). map(Integer -> Integer * Integer) .forEach(System.out::println); System.out.println("map##################"); //distinct去重 Stream<String> distinct = Arrays.stream(strings).distinct(); distinct.forEach(System.out::println); System.out.println("distinct##################"); //limit 截取 截取前面兩個單位: Arrays.stream(strings).limit(2).forEach(System.out::println); System.out.println("limit##################"); //skip 跳過 跳過前面兩個單位: Arrays.stream(strings).skip(2).forEach(System.out::println); System.out.println("skip##################"); //計數 2種方式 long count = Arrays.stream(strings) .count(); System.out.println(count); //數組轉集合 轉爲流 計數改成集合計數 Long collect = Arrays.asList(strings).stream().collect(Collectors.counting()); System.out.println(collect); System.out.println("count##################"); //求和 int sum = Arrays.stream(strings) .mapToInt(String::length) .sum(); System.out.println(sum); System.out.println("sum##################"); //平均數 OptionalDouble average = Arrays.stream(strings) .mapToInt(String::length) .average(); System.out.println(average); System.out.println("average##################"); //最大值 OptionalInt max = Arrays.stream(strings) .mapToInt(String::length) .max(); System.out.println(max); System.out.println("max##################"); //最小值 OptionalInt min = Arrays.stream(strings) .mapToInt(String::length) .min(); System.out.println(min); System.out.println("min##################"); } //2.4 流的鏈接 concat flatMap public static void testConcatStream() { //兩個流的鏈接 使用 Stream.concat 方法, Stream<String> first = Stream.of("sihai", "sihai2", "sihai3"); Stream<String> second = Stream.of("sihai4", "sihai5", "sihai6"); Stream<String> third = Stream.of("siha7", "sihai8", "sihai9"); Stream<String> concat = Stream.concat(first, second); //多個流的鏈接 使用 Stream.flatMap 方法 Stream<String> stringStream = Stream.of(first, second, third).flatMap(Function.identity()); } //2.3 一個集合的對象的某一個字段取出來,而後再存到另一個集合中 public static void fieldStrean() { //映射出名字 //List<String> strings = list.stream().map(Person::getName).collect(Collectors.toList()); } //2.2字符串和流的裝換 public static void stringStream() { //1.codePoints() String s = "hello world Java8".codePoints()//轉換成流 .collect(StringBuffer::new, StringBuffer::appendCodePoint, StringBuffer::append)//將流轉換爲字符串 .toString(); System.out.println(s); //2.chars() String s1 = "hello world Java8".chars()//轉換成流 .collect(StringBuffer::new, StringBuffer::appendCodePoint, StringBuffer::append)//將流轉換爲字符串 .toString(); } //2.1流轉集合 裝箱流 基本數值型目前有三種對應的包裝類型:IntStream、LongStream、DoubleStream public static void boxStream() { //1.通常格式 將流的數據收集爲基本類型的集合 //Stream.collect(Collectors.toList()) List<Double> collect2 = Stream.of(1.0, 2.0, 3.0).collect(toList()); //2.通用格式 List<Double> list = Stream.of(1.0, 2.0, 3.0) .collect(ArrayList<Double>::new, ArrayList::add, ArrayList::addAll); // 第一個參數:使用一個靜態方法初始化一個 List 容器; // 第二個參數:使用靜態方法 add ,添加元素; // 第三個參數:使用靜態方法 addAll ,用於聯合全部的元素。 System.out.println("############"); //3.boxed Double List<Double> collect = DoubleStream.of(1.0, 2.0, 3.0) .boxed() .collect(toList()); System.out.println("############"); //4.mapToObj Double List<Double> collect1 = DoubleStream.of(1.0, 2.0, 3.0) .mapToObj(Double::valueOf) .collect(toList()); System.out.println("############"); } //1.1流的建立 4種 of,iterate,generate,集合 public static void createStream() { //1.利用Stream.of方法建立流 參數很簡單,就是一系列的泛型參數。 Stream<String> stringStream = Stream.of("中國", "美國", "加拿大"); stringStream.forEach(System.out::println); System.out.println("############"); //2.利用Stream.iterate方法建立流 第一個參數是一個初始值,第二個參數是一個操做。 java.util.stream.Stream.iterate(10, n -> n + 1) .limit(5) .collect(toList()) .forEach(System.out::println); System.out.println("##################"); //3.利用Stream.generate方法建立流 java.util.stream.Stream.generate(Math::random) .limit(5) .forEach(System.out::println); System.out.println("##################"); //4.從現有的集合中建立流 List<String> strings = Arrays.asList("hello", "world", "Java8"); String string = strings.stream().collect(Collectors.joining(",")); System.out.println(string); //5.數組中建立流 String[] stringss = {"hello", "sihai", "hello", "Java8"}; Stream<String> stream = Arrays.stream(stringss); //6.文件中建立流 //Stream<String> file = Files.lines(Paths.get("D:\\zhangkai\\WorkSpace\\Git\\hexo\\_config.yml")); } //1.2歸約操做(流的轉換) 轉換爲集合、數組、字符串等 public void streamToOther() { Stream<String> stream = Stream.of("15", "25", "35"); // 1. Array String[] strArray1 = stream.toArray(String[]::new); // 2. Collection List<String> list1 = stream.collect(toList()); List<String> list2 = stream.collect(Collectors.toCollection(ArrayList::new)); Set set1 = stream.collect(Collectors.toSet()); Stack stack1 = stream.collect(Collectors.toCollection(Stack::new)); // 3. String String str = stream.collect(Collectors.joining()).toString(); } }