<ruby id="bdb3f"></ruby>

    <p id="bdb3f"><cite id="bdb3f"></cite></p>

      <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
        <p id="bdb3f"><cite id="bdb3f"></cite></p>

          <pre id="bdb3f"></pre>
          <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

          <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
          <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

          <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                <ruby id="bdb3f"></ruby>

                ??碼云GVP開源項目 12k star Uniapp+ElementUI 功能強大 支持多語言、二開方便! 廣告
                [TOC] # 簡介 在JDK1.8開始發現類集里面提供的接口都出現大量的default或者是static方法 以Collection的父接口Iterable接口里面定義的一個方法來觀察: ~~~ default void forEach(Consumer<? super T> action) ~~~ 例子: 利用forEach來輸出 ~~~ ArrayList<String> all = new ArrayList<>(); boolean b = Collections.addAll(all, "A", "B", "c", "D", "E"); all.forEach(System.out::println); ~~~ 不會采用以上方式完成,因為forEach()只能輸出,但是我們很多時候,在輸出的時候還要對數據進行處理,也就是Iterator輸出是我們主要形式 除了使用Iterator迭代輸出之外,JDK1.8還提供了一個專門可以進行數據處理的類就是stream類 ~~~ java.util.stream ~~~ 這個類的對象可以利用Collection接口提供的方法操作: ~~~ default Stream<E> stream(); ~~~ # 注意 1. Stream 自己不會存儲元素 2. Stream 不會改變源對象。相反,他們會返回一個持有結果的新Stream 3. Stream 操作是延遲執行的。這意味著他們會等到需要結果的時候才執行 Stream的使用流程: * 步驟一:Stream的實例化 * 步驟二:一系列的中間操作 * 步驟三:終止操作 注意: 1. 步驟二中的中間操作可以有多個 2. 如果沒有終止操作,那么一系列的中間操作是不會執行的。只有執行了步驟三的終止操作,步驟二才會執行:惰性求值 3. 終止操作一旦執行,就不可以再執行中間操作或其他的終止操作。 # 實例化 ## 通過集合 ~~~ //返回一個順序流 default stream<E> stream(); //返回一個并行流 default stream<E> parallelStream(); ~~~ **返回一個順序流** ~~~ ArrayList<String> strings = new ArrayList<>(); Collections.addAll(strings, "A", "B", "c", "D", "E"); Stream<String> stream = strings.stream(); ~~~ **返回一個并行流** ~~~ ArrayList<String> strings = new ArrayList<>(); Collections.addAll(strings, "A", "B", "c", "D", "E"); Stream<String> stream = strings.parallelStream(); ~~~ ## 通過數組 java8中Arrays的靜態方法stream()可以獲取數組流 * `static <T> Stream<T> stream(T[] array)` 返回一個流 重載形式,能夠處理對應基本類型的數組 * public static IntStream stream(int[] array) * public static LongStream stream(long[] array) * public static DoubleStream stream(double[] array); ~~~ String[] arr = {"MM", "GG", "JJ", "DD"}; Stream<String> stream = Arrays.stream(arr); ~~~ ## 通過Stream的of() 可以調用Stream類靜態方法of(),通過顯示值創建一個流.它可以接收任意數量的參數 * `public static<T> Stream<T> of(T... values)` 返回一個流 ~~~ Stream<Integer> stream = Stream.of(1, 2, 3, 4, 5); ~~~ ## 創建無限流 可以使用靜態方法Stream.iterate()和Steam.generate()創建無限流 * 迭代 `public static<T> Stream<T> iterate(final T seed, final UnartyOperator<T> f)` * 生成 `public static<T> Stream<T> generate(Supplier<T> s)` 迭代 ~~~ Stream<Integer> stream = Stream.iterate(0, x -> x + 2); stream.forEach(System.out::println); ~~~ 生成 ~~~ Stream<Double> stream = Stream.generate(Math::random); stream.forEach(System.out::println); ~~~ # 中間操作 多個**中間操作**可以連接起來形成一個**流水線**,除非流水線上觸發了終止操作,否則**中間操作不會執行任何的處理.** **而在終止操作時一次性全部處理,稱為"惰性求值"** ## 篩選與切片 | 方法 | 描述 | | --- | --- | | filter(Predicate p) | 接收Lambda,從流中排除某些元素 | | distinct() | 篩選,通過流所生產元素的hashCode()和equals()去重 | | limit(long maxSize) | 截斷流,使其元素不超過給定數量 | | skip(long n) | 跳過元素,返回一個扔掉了前n個元素的流.若流中的元素不足n個,則返回一個空流.與limit(n)互補 | ## 映射 | 方法 | 描述 | | --- | --- | | map(Function f) | 接收一個函數作為參數,該函數會被應用到每個元素上,并將其映射成一個新的元素 | | mapToDouble(ToDoubleFunction f) | 接收一個函數作為參數,該函數會被應用到每個元素上,產生一個新的DoubleStream | | mapToInt(ToIntFunction f) | 接收一個函數作為參數,該函數會被應用到每個元素上,產生一個新的IntStream | | mapToLong(ToLongFunction f) | 接收一個函數作為參數,該函數會被應用到每個元素上,產生一個新的LongStream | | flatMap(Function f) | 接收一個函數作為參數,將流中的每個值都換成另一個流,然后把所有流連接成一個流 | ## 排序 | 方法 | 描述 | | --- | --- | | sorted() | 產生一個新流,其中按自然順序排序 | | sorted(Comparator com) | 產生一個新流,其中按比較器順序排序 | 進行排序:失敗。 原因:沒有實現Comparable接口 ~~~ list1.stream().sorted((e1,e2) -> { if(e1.getAge() != e2.getAge()){ return e1.getAge() - e2.getAge(); }else{ //double比較 return -Double.compare(e1.getSalary(),e2.getSalary()); } }).forEach(System.out::println); ~~~ # 終止操作 終端操作會從流的流水線生成結果. 其結果可以是任何不適流的值,例如:List,Integer,甚至是void. 流進行終止操作后,不能再次使用 ## 匹配查找 | 方法 | 描述 | | --- | --- | | allMatch(Predicate p) | 檢查是否匹配所有元素 | | anyMatch(Predicate p) | 檢查是否至少匹配一個元素 | | noneMatch(Predicate p) | 檢查是否沒有匹配所有元素 | | findFirst() | 返回第一個元素 | | findAny() | 返回當前流中的任意元素 | | count() | 返回流中元素的總個數 | | max(Comparator c) | 返回流中最大值 | | min(Comparator c) | 返回流中最小值 | | forEach(Consumer c) | 內部迭代 | ~~~ List<Employee> list = EmployeeData.getEmployees(); // allMatch(Predicate p)——檢查是否匹配所有元素 //是否所有的員工的年齡都大于18 boolean b = list.stream().allMatch(e -> e.getAge() > 18); System.out.println(b); // anyMatch(Predicate p)——檢查是否至少匹配一個元素 //是否存在員工的工資大于 10000 boolean b1 = list.stream().anyMatch(e -> e.getSalary() > 9900); System.out.println(b1); // noneMatch(Predicate p)——檢查是否沒有匹配的元素 //是否存在員工姓“雷” boolean b2 = list.stream().noneMatch(e -> e.getName().contains("雷")); System.out.println(b2); // count——返回流中元素的總個數 long count = list.stream().filter(e -> e.getSalary() > 5000).count(); System.out.println(count); // 練習:返回最高的工資: Stream<Employee> stream = list.stream(); Stream<Double> stream1 = stream.map(Employee::getSalary); Optional<Double> max = stream1.max(Double::compare); System.out.println(max.get()); // min(Comparator c)——返回流中最小值 // 練習:返回最低工資的員工 Stream<Employee> stream2 = list.stream(); Optional<Employee> min = stream2.min((e1, e2) -> Double.compare(e1.getSalary(), e2.getSalary())); System.out.println(min.get()); ~~~ ## 歸約 | 方法 | 描述 | | --- | --- | | reduce(T iden, BinaryOperator b) | 可以將流中元素反復結合起來,得到一個值,返回T | | reduce(BinaryOperator b) | 可以將流中元素反復結合起來,得到一個值,返回Optional<T> | ~~~ List<Integer> list = Arrays.asList(1,2,3,4,5,6); // Integer sum = list.stream().reduce(0, (x1, x2) -> x1 + x2); //如果是空就會取默認值10 Integer sum = list.stream().reduce(10, Integer::sum); System.out.println(sum); // reduce(BinaryOperator) ——可以將流中元素反復結合起來,得到一個值。返回 Optional<T> // 練習1:計算公司所有員工工資的總和 List<Employee> emps = EmployeeData.getEmployees(); Stream<Double> moneyStream = emps.stream().map(Employee::getSalary); Optional<Double> moneyOptional = moneyStream.reduce(Double::sum); System.out.println(moneyOptional.get()); ~~~ ## 收集 | 方法 | 描述 | | --- | --- | | collect(Collector c) | 將流轉換為其他形式.接收一個Collector接口的實現,用于給stream中元素做匯總的方法 | Collector接口中方法的實現決定了如何對流執行收集的操作(如收集到List,Set,Map) 另外,Collectors使用類提供了很多靜態方法,可以方便地創建常見收集器實例 ![](https://box.kancloud.cn/3241c2b96b8e7203007f0c5d78b31c1b_967x617.png) # 例子 ## 取得Stream對象并統計個數 ~~~ long count(); ~~~ ~~~ ArrayList<String> all = new ArrayList<>(); boolean b = Collections.addAll(all, "A", "B", "c", "D", "E"); Stream<String> stream = all.stream(); //取得個數 System.out.println(stream.count()); ~~~ ## 去掉重復數據 ~~~ Stream<T> distinct(); ~~~ ~~~ ArrayList<String> all = new ArrayList<>(); boolean b = Collections.addAll(all, "A", "B", "E", "A", "a"); Stream<String> stream = all.stream(); //去重后的數據 System.out.println(stream.distinct().count()); ~~~ ## 收集器(最后使用) ~~~ <R, A> R collect(Collector<? super T, A, R> collector); ~~~ 需要Collectors方法 ~~~ public static <T> Collector<T, ?, List<T>> toList() ~~~ ~~~ ArrayList<String> all = new ArrayList<>(); boolean b = Collections.addAll(all, "A", "B", "E", "A", "a"); Stream<String> stream = all.stream(); //去除掉所有的重復數據后形成的新的集合,里面是不包含重復內容的集合 List<String> collect = stream.distinct().collect(Collectors.toList()); System.out.println(collect); ~~~ 既然Stream類是進行數據處理的,那么在數據處理過程中就不可能不進行數據篩選(過濾) ## 數據過濾 ~~~ Stream<T> filter(Predicate<? super T> predicate); ~~~ ~~~ ArrayList<String> all = new ArrayList<>(); boolean b = Collections.addAll(all, "A", "B", "E", "A", "a"); Stream<String> stream = all.stream(); //增加了數據的過濾操作,使用了斷言行的函數接口,使用了string的contains List<String> collect = stream.distinct().filter((x) -> x.contains("a")).collect(Collectors.toList()); System.out.println(collect); ~~~ 數據過濾是區分大小寫的,那么在數據過濾前要對數據進行處理呢? ## map數據處理方法 map是針對數據逐行處理 ~~~ <R> Stream<R> map(Function<? super T, ? extends R> mapper); ~~~ ~~~ ArrayList<String> all = new ArrayList<>(); boolean b = Collections.addAll(all, "Android", "Java", "Ios", "jsp", "ORACLE"); Stream<String> stream = all.stream(); List<String> collect = stream.distinct() .map((x) -> x.toLowerCase()) .filter((x) -> x.contains("a")) .collect(Collectors.toList()); System.out.println(collect); ~~~ ## 集合數據分頁 在Stream接口里面提供有進行集合數據分頁的操作 * 設置跳過的數據行數 ~~~ public Stream<T> skip(long n); ~~~ * 設置取出的數據個數 ~~~ public Stream<T> limit(long maxSize); ~~~ ~~~ ArrayList<String> all = new ArrayList<>(); boolean b = Collections.addAll(all, "Android", "Java", "Ios", "jsp", "ORACLE"); Stream<String> stream = all.stream(); List<String> collect = stream.distinct() .map((x) -> x.toLowerCase()) .skip(2).limit(2) .collect(Collectors.toList()); System.out.println(collect); ~~~ 在stream可以進行數據全匹配和部分比配 ## 數據匹配 * 全匹配 ~~~ public boolean allMatch(Predicate<? super T> predicate); ~~~ * 匹配任意一個 ~~~ public boolean anyMatch(Predicate<? super T> predicate); ~~~ ~~~ ArrayList<String> all = new ArrayList<>(); boolean b = Collections.addAll(all, "Android", "Java", "Ios", "jsp", "ORACLE"); Stream<String> stream = all.stream(); boolean bool = stream.anyMatch((x) -> x.contains("jsp")); System.out.println(bool); ~~~ 在實際之中有可能會出現多個匹配條件,在斷言型接口函數式接口里面提供有如下的方法 * 或操作 ~~~ default Predicate<T> or(Predicate<? super T> other); ~~~ * 與操作 ~~~ default Predicate<T> and(Predicate<? super T> other); ~~~ **設置多個條件** ~~~ ArrayList<String> all = new ArrayList<>(); boolean b = Collections.addAll(all, "Android", "Java", "Ios", "jsp", "ORACLE", "jspIos"); Stream<String> stream = all.stream(); Predicate<String> p1 = (x) -> x.contains("jsp"); Predicate<String> p2 = (x) -> x.contains("Ios"); //同時使用2個條件 if (stream.anyMatch(p1.or(p2))) { System.out.println("數據存在"); } ~~~ 利用這樣的匹配條件,可以針對數據進行方便的查詢操作 如果要想更好的返回stream的操作優勢,必須結合MapReduce ## 數據分析reduce 就是做數據統計使用的 ~~~ public Optional<T> reduce(BinaryOperator<T> accumulator); ~~~ 我們點進去看下 ~~~ public interface BinaryOperator<T> extends BiFunction<T,T,T> public interface BiFunction<T, U, R> | |--- R apply(T t, U u); ~~~ 比如一個購物類 ~~~ class ShopCar { //商品名稱 private String pname; //商品單價 private double price; //購買數量 private int amount; public ShopCar(String pname, double price, int amount) { this.pname = pname; this.price = price; this.amount = amount; } public String getPname() { return pname; } public double getPrice() { return price; } public int getAmount() { return amount; } } ~~~ 設計的時候設計出了商品的單價與數量,這樣如果獲取一個商品花費的錢,就要單價乘以數量 例子:求每個商品花費的數量和金額 ~~~ all.add(new ShopCar("java", 800, 20)); all.add(new ShopCar("php", 100, 10)); all.add(new ShopCar("c++", 200, 15)); all.add(new ShopCar("c", 300, 30)); Stream<ShopCar> stream = all.stream(); all.stream().map((x) -> x.getAmount() * x.getPrice()) .forEach(System.out::println); ~~~ 但是這時候處理沒有總價,于是數據處理的總價就用reduce完成 ~~~ ArrayList<ShopCar> all = new ArrayList<>(); all.add(new ShopCar("java", 800, 20)); all.add(new ShopCar("php", 100, 10)); all.add(new ShopCar("c++", 200, 15)); all.add(new ShopCar("c", 300, 30)); Stream<ShopCar> stream = all.stream(); Double s = all.stream().map((x) -> x.getAmount() * x.getPrice()) .reduce((sum, m) -> sum + m).get(); System.out.println(s); ~~~ 以上只是實現了一個最簡單的MapReuce,但是完成的統計實在有限,如果要更完善統計,需要使用如下方法 ## 統計 ~~~ * 按照Double處理 DoubleStream mapToDouble(ToDoubleFunction<? super T> mapper); * 按照Int處理 IntStream mapToInt(ToIntFunction<? super T> mapper); * 按照Long處理 LongStream mapToLong(ToLongFunction<? super T> mapper); ~~~ ~~~ ArrayList<ShopCar> all = new ArrayList<>(); all.add(new ShopCar("java", 800, 20)); all.add(new ShopCar("php", 100, 10)); all.add(new ShopCar("c++", 200, 15)); all.add(new ShopCar("c", 300, 30)); Stream<ShopCar> stream = all.stream(); DoubleSummaryStatistics dss = all.stream().mapToDouble((x) -> x.getAmount() * x.getPrice()) .summaryStatistics(); System.out.println("商品個數: " + dss.getCount()); System.out.println("商品總花費: " + dss.getSum()); System.out.println("平局花費: " + dss.getAverage()); System.out.println("最高花費: " + dss.getMax()); System.out.println("最低花費: " + dss.getMin()); ~~~
                  <ruby id="bdb3f"></ruby>

                  <p id="bdb3f"><cite id="bdb3f"></cite></p>

                    <p id="bdb3f"><cite id="bdb3f"><th id="bdb3f"></th></cite></p><p id="bdb3f"></p>
                      <p id="bdb3f"><cite id="bdb3f"></cite></p>

                        <pre id="bdb3f"></pre>
                        <pre id="bdb3f"><del id="bdb3f"><thead id="bdb3f"></thead></del></pre>

                        <ruby id="bdb3f"><mark id="bdb3f"></mark></ruby><ruby id="bdb3f"></ruby>
                        <pre id="bdb3f"><pre id="bdb3f"><mark id="bdb3f"></mark></pre></pre><output id="bdb3f"></output><p id="bdb3f"></p><p id="bdb3f"></p>

                        <pre id="bdb3f"><del id="bdb3f"><progress id="bdb3f"></progress></del></pre>

                              <ruby id="bdb3f"></ruby>

                              哎呀哎呀视频在线观看