<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      java-Stream的總結(jié)

      JAVA中的Stream

      01.什么是Stream

      Stream是JDK8中引入,Stream是一個(gè)來自數(shù)據(jù)源的元素序列并支持聚合操作。可以讓你以一種聲明的方式處理數(shù)據(jù),Stream 使用一種類似用 SQL 語句從數(shù)據(jù)庫查詢數(shù)據(jù)的直觀方式來提供一種對(duì) Java 集合運(yùn)算和表達(dá)的高階抽象。Stream API可以極大提高Java程序員的生產(chǎn)力,讓程序員寫出高效率、干凈、簡(jiǎn)潔的代碼。

      02.Stream特點(diǎn)

      • 元素:是特定類型的對(duì)象,形成一個(gè)序列。 Java中的Stream并不會(huì)存儲(chǔ)元素,而是按需計(jì)算。
      • 數(shù)據(jù)源:流的來源可以是集合,數(shù)組,I/O channel等。
      • 過濾、聚合、排序等操作:類似SQL語句一樣的操作, 比如filter, map, reduce, find, match, sorted等
      • Pipelining(流水線/管道): 中間操作都會(huì)返回流對(duì)象本身。 這樣多個(gè)操作可以串聯(lián)成一個(gè)管道, 如同流式風(fēng)格(fluent style)。 這樣做可以對(duì)操作進(jìn)行優(yōu)化, 比如延遲執(zhí)行(laziness)和短路( short-circuiting)。
      • 內(nèi)部迭代: 以前對(duì)集合遍歷都是通過Iterator或者For-Each的方式, 顯式的在集合外部進(jìn)行迭代, 這叫做外部迭代。 Stream提供了內(nèi)部迭代的方式。
      • 只能遍歷一次:數(shù)據(jù)流的從一頭獲取數(shù)據(jù)源,在流水線上依次對(duì)元素進(jìn)行操作,當(dāng)元素通過流水線,便無法再對(duì)其進(jìn)行操作

      image-20220617093802599

      一個(gè)stream是由三部分組成的。數(shù)據(jù)源,零個(gè)或一個(gè)或多個(gè)中間操作,一個(gè)或零個(gè)終止操作。
      中間操作是對(duì)數(shù)據(jù)的加工,注意:中間操作是lazy操作,并不會(huì)立馬啟動(dòng),需要等待終止操作才會(huì)執(zhí)行。
      終止操作是stream的啟動(dòng)操作,只有加上終止操作,stream才會(huì)真正的開始執(zhí)行。

      03.Stream入門案例

      //要求把list1中的空字符串過濾掉,并把結(jié)果保存在列表中
      public class Test {
          public static void main(String[] args) {
              List<String> list1 = Arrays.asList("ab", "", "cd", "ef", "mm","", "hh");
              System.out.println(list1);//[ab, , cd, ef, mm, , hh]
              List<String> result = list1.stream().filter(s -> !s.isEmpty()).collect(Collectors.toList());
              System.out.println(result);//[ab, cd, ef, mm, hh]
          }
      }
      

      上面這個(gè)例子可以看出list1是一個(gè)字符串的列表,其中有兩個(gè)空字符串,在stream的操作過程中,我們使用了stream()、filter()、collect()等方法,在filter()過程中,我們引入了Lambda表達(dá)式s->!s.isEmpty(),結(jié)果是把兩個(gè)空字符串過濾掉后,形成了一個(gè)新的列表result。
      上面這個(gè)需求如果我們使用傳統(tǒng)的代碼完成如下:

      public class Test {
          public static void main(String[] args) {
              List<String> list1 = Arrays.asList("ab", "", "cd", "ef", "mm","", "hh");
              List<String> result = new ArrayList<>();
              for (String str : list1) {
                  if(str.isEmpty()){
                      continue;
                  }
                  result.add(str);
              }
              System.out.println(result);
          }
      }
      

      比較兩段代碼,我們可以發(fā)現(xiàn)在第二段代碼中我們自己創(chuàng)建了一個(gè)字符串對(duì)象列表,開啟一個(gè)for循環(huán)遍歷字符串對(duì)象列表,在for循環(huán)中判斷是否當(dāng)前的字符串是空串,如果不是,加到結(jié)果列表中。而在第一段程序中,我們并不需要自己開啟for循環(huán)遍歷,stream會(huì)在內(nèi)部做迭代,我們只需要傳入我們的過濾條件就可以了,最后這個(gè)字符串列表也是代碼自動(dòng)創(chuàng)建出來的,并且把結(jié)果放入了列表中,可以看出,第一段代碼簡(jiǎn)潔優(yōu)雅。

      04.Stream操作分類

      image-20220617233709237

      • 無狀態(tài):指元素的處理不受之前元素的影響;
      • 有狀態(tài):指該操作只有拿到所有元素之后才能繼續(xù)下去。
      • 非短路操作:指必須處理所有元素才能得到最終結(jié)果;
      • 短路操作:指遇到某些符合條件的元素就可以得到最終結(jié)果,如 A || B,只要A為true,則無需判斷B的結(jié)果。

      05.Stream使用案例

      5.1.創(chuàng)建流

      5.1.1.使用Collection下的 stream() 和 parallelStream() 方法

      public class Test {
          public static void main(String[] args) {
              List<String> list = new ArrayList<>();
              Stream<String> stream = list.stream(); //獲取一個(gè)串行流
              Stream<String> parallelStream = list.parallelStream(); //獲取一個(gè)并行流
          }
      }
      

      5.1.2.使用Arrays 中的 stream() 方法,將數(shù)組轉(zhuǎn)成流

      public class Test {
          public static void main(String[] args) {
              Integer[] nums = new Integer[10];
              Stream<Integer> stream = Arrays.stream(nums);
          }
      }
      

      5.1.3.使用Stream中的靜態(tài)方法:of()、iterate()、generate()

      public class Test {
          public static void main(String[] args) {
              Stream<Integer> stream = Stream.of(1,2,3,4,5,6);
              stream.forEach(System.out::print);//1 2 3 4 5 6
              System.out.println("==========");
              Stream<Integer> stream2 = Stream.iterate(0, (x) -> x + 2).limit(6);
              stream2.forEach(System.out::print); // 0 2 4 6 8 10
              System.out.println("==========");
              Stream<Double> stream3 = Stream.generate(Math::random).limit(2);
              stream3.forEach(System.out::print);//隨機(jī)產(chǎn)生兩個(gè)小數(shù)
          }
      }
      
      

      5.1.4.使用 BufferedReader.lines() 方法,將每行內(nèi)容轉(zhuǎn)成流

      public class Test {
          public static void main(String[] args) throws FileNotFoundException {
              BufferedReader reader = new BufferedReader(new FileReader("d:\\study\\demo\\test_stream.txt"));
              Stream<String> lineStream = reader.lines();
              lineStream.forEach(System.out::println);
          }
      }
      

      5.1.5.使用 Pattern.splitAsStream() 方法,將字符串分隔成流

      public class Test {
          public static void main(String[] args) {
              Pattern pattern = Pattern.compile(",");
              Stream<String> stringStream = pattern.splitAsStream("tom,jack,jerry,john");
              stringStream.forEach(System.out::println);
          }
      }
      
      

      5.2.中間操作

      5.2.1.篩選與切片

      • filter:過濾流中的某些元素
      • limit(n):獲取n個(gè)元素
      • skip(n):跳過n元素,配合limit(n)可實(shí)現(xiàn)分頁
      • distinct:通過流中元素的 hashCode() 和 equals() 去除重復(fù)元素
      //filter 測(cè)試
      public class Test {
          public static void main(String[] args) {
              List<String> list = Arrays.asList("aaa", "ff", "dddd","eeeee","hhhhhhh");
      
              //把字符串長(zhǎng)度大于3的過濾掉
              Stream<String> stringStream = list.stream().filter(s -> s.length() <= 3);
      
              stringStream.forEach(System.out::println);
      
              System.out.println("===================");
      
      
              //驗(yàn)證整個(gè)流只遍歷一次
              //stream只有遇到終止操作才會(huì)觸發(fā)流啟動(dòng),中間操作都是lazy
              Stream.of(1, 2, 3, 4, 5)
              .filter(i -> {
                  System.out.println("filter1的元素:" + i);
                  return i > 0;
              }).filter(i -> {
                  System.out.println("filter2的元素:" + i);
                  return i == 5;
              }).forEach(i-> System.out.println("最后結(jié)果:"+i));
      
      
          }
      }
      
      //limit 測(cè)試
      public class Test {
          public static void main(String[] args) {
              List<String> list = Arrays.asList("aaa", "ff", "dddd","eeeee","hhhhhhh");
      
              //取三個(gè)元素
              List<String> result = list.stream().limit(3).collect(Collectors.toList());
      
              System.out.println(result);
      
          }
      }
      
      //limit 和 skip 測(cè)試
      public class Test {
          public static void main(String[] args) {
              List<String> list = Arrays.asList("11", "22", "33","44","55","66","77","88","99");
      
              //演示skip:跳過前三條記錄
              list.stream().skip(3).forEach(System.out::println);
              
              //模擬翻頁,每頁3條記錄
              //第一頁
              List<String> page1= list.stream().skip(0).limit(3).collect(Collectors.toList());
              System.out.println(page1);
              //第二頁
              List<String> page2= list.stream().skip(3).limit(3).collect(Collectors.toList());
              System.out.println(page2);
              //第三頁
              List<String> page3= list.stream().skip(6).limit(3).collect(Collectors.toList());
              System.out.println(page3);
      
              //limit和skip順序換一下
              //可以看出,最終的結(jié)果會(huì)收到執(zhí)行順序的影響
              List<String> page4= list.stream().limit(3).skip(1).collect(Collectors.toList());
              System.out.println(page4);
          }
      }
      
      
      //distinct去重測(cè)試
      //注意:當(dāng)我們自己重寫hashcode和equals的方法的時(shí)候,要遵循一個(gè)原則:
      //如果兩個(gè)對(duì)象的hashcode相等,那么用equals比較不一定相等;反之,如果兩個(gè)對(duì)象用equals比較相等,那么他們的hashcode也一定相等
      public class Student {
          private Integer id;
          private String name;
      
          public Student(Integer id, String name) {
              this.id = id;
              this.name = name;
          }
      
          public Integer getId() {
              return id;
          }
      
          public void setId(Integer id) {
              this.id = id;
          }
      
          public String getName() {
              return name;
          }
      
          public void setName(String name) {
              this.name = name;
          }
      
          @Override
          public boolean equals(Object o) {
              if (this == o) return true;
              if (o == null || getClass() != o.getClass()) return false;
              Student student = (Student) o;
              return getId().equals(student.getId()) &&
                      getName().equals(student.getName());
          }
      
          @Override
          public int hashCode() {
              return Objects.hash(getId(), getName());
          }
      
          @Override
          public String toString() {
              return "Student{" +
                      "id=" + id +
                      ", name='" + name + '\'' +
                      '}';
          }
      }
      
      //去掉重復(fù)的student
      //1.Student類的hashcode和equals包含了id和name
      //2.Student類的hashcode和equals中只包含name
      public class Test {
          public static void main(String[] args) {
              List<Student> studentList = Arrays.asList(
                     new Student(1, "zhangsan"),
                      new Student(6, "zhangsan"),
                      new Student(2, "lisi"),
                      new Student(5, "lisi"),
                      new Student(3, "wangwu"));
              //1.學(xué)生對(duì)象去重
              List<Student> result = studentList.stream().distinct().collect(Collectors.toList());
              System.out.println(result);
      
      
              //2.普通字符串去重
              Stream<String> stringStream = Stream.of("a", "a", "b", "c", "d");
              List<String> stringList = stringStream.distinct().collect(Collectors.toList());
              System.out.println(stringList);
              
          }
      }
      
      

      5.2.2.映射(map和flatMap)

      public class Test {
          public static void main(String[] args) {
      
                  //第一個(gè)例子對(duì)比
                  List<String> list = Arrays.asList("a,b,c", "1,2,3");
      
                  //將每個(gè)元素轉(zhuǎn)成一個(gè)新的且不帶逗號(hào)的元素
                  //注意:這里元素是值在list中的元素,一共有兩個(gè),分別是"a,b,c" 和"1,2,3"
                  //map函數(shù)傳入的lambda表達(dá)式就是我們的轉(zhuǎn)換邏輯,需要返回一個(gè)轉(zhuǎn)換之后的元素
                  Stream<String> s1 = list.stream().map(s -> s.replaceAll(",", ""));
                  s1.forEach(System.out::println); // abc  123
      
                  System.out.println("===============");
              
                  List<Integer> integerList = Arrays.asList(1, 2, 3);
                  integerList.stream().map(i->i*2).forEach(System.out::println);
      
                  System.out.println("===============");
              
                  //將每個(gè)元素轉(zhuǎn)換成一個(gè)stream
                  //注意:flatMap跟上面的map函數(shù)對(duì)比
                  //兩者傳入的lambda都是轉(zhuǎn)換邏輯,但是map中的lambda返回的是一個(gè)轉(zhuǎn)換后的新元素,
                  //flatMap可以把每一個(gè)元素進(jìn)一步處理:例如"a,b,c"進(jìn)一步分隔成a b c三個(gè)元素
                  //返回的是這三個(gè)元素形成的三個(gè)stream,最終把這些單獨(dú)的stream合并成一個(gè)stream返回
                  //總結(jié):可以看出,flatMap相比于map,它可以把每一個(gè)元素再進(jìn)一步拆分成更多的元素,
                  // 最后,拆分出來的元素個(gè)數(shù)會(huì)多于最初輸入的列表中的元素個(gè)數(shù)
                  //就這個(gè)例子而言,最初輸入兩個(gè)元素"a,b,c" 和"1,2,3",結(jié)果是6個(gè)元素  a b c 1 2 3
                  Stream<String> s3 = list.stream().flatMap(s -> {
      
                      String[] split = s.split(",");
                      Stream<String> s2 = Arrays.stream(split);
                      return s2;
                  });
                  s3.forEach(System.out::println); // a b c 1 2 3
      
                  System.out.println("===============");
      
                  //第二個(gè)例子(嵌套的list)[["a","b","c"],["d","e","f"],["h","k"]]
                  //輸出結(jié)果要求是:["A","B","C","D","E","F","G","H"]
                  List<List<String>> nestedList = Arrays.asList(
                                                      Arrays.asList("a","b","c"),
                                                      Arrays.asList("d","e","f"),
                                                      Arrays.asList("h","k")
                                                  );
      
                  Stream<String> s4 = nestedList.stream()
                      .flatMap(Collection::stream)
                      .map(s -> s.toUpperCase());
      
      
                  s4.forEach(System.out::print);
          }
      }
      

      5.2.3.排序

      • sorted():自然排序,流中元素需實(shí)現(xiàn)Comparable接口
      • sorted(Comparator com):定制排序,自定義Comparator排序器
      //字符串排序
      public class Test {
          public static void main(String[] args) {
              List<String> list = Arrays.asList("aaa", "ff", "dddd");
      
              //String 類自身已實(shí)現(xiàn)Compareable接口,可以按照字符的自然順序【升序】排序
              list.stream().sorted().forEach(System.out::println);// aaa dddd ff
       		System.out.println("=====");
              //給sorted函數(shù)傳入一個(gè)lambda表達(dá)式
              //1.自定義排序規(guī)則,按照字符串的長(zhǎng)度【升序】排序,也就是字符串長(zhǎng)度最短的排在最前面
              list.stream().sorted((s1,s2)->s1.length()-s2.length()).forEach(System.out::println);//ff aaa dddd
       		System.out.println("=====");
              //2.自定義排序規(guī)則,按照字符串的長(zhǎng)度【降序】排序,也就是字符串長(zhǎng)度最長(zhǎng)的排在最前面
              list.stream().sorted((s1,s2)->s2.length()-s1.length()).forEach(System.out::println);//dddd aaa ff
          }
      }
      
      
      //對(duì)象排序
      public class Employee {
          private String name;
          private Integer salary;
          public Employee(String name,Integer salary) {
              this.name = name;
              this.salary = salary;
          }
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public Integer getSalary() {
              return salary;
          }
          public void setSalary(Integer salary) {
              this.salary = salary;
          }
      
          @Override
          public String toString() {
              return "Employee{" +
                      "name='" + name + '\'' +
                      ", salary=" + salary +
                      '}';
          }
      }
      
      //測(cè)試類
      public class Test {
          public static void main(String[] args) {
                  List<Employee> list = Arrays.asList(
                          new Employee("Tom",1000),
                          new Employee("Jack",900),
                          new Employee("John",1300),
                          new Employee("Jack",2000)
                  );
                  //自定義排序規(guī)則,先按照名稱【升序】,如果名稱相同,再按照工資【降序】
                  list.stream().sorted((e1,e2)->{
                      if(e1.getName().equals(e2.getName())){
                          return e2.getSalary()-e1.getSalary();
                      }else{
                          return e1.getName().compareTo(e2.getName());
                      }
                  }).forEach(System.out::println);
      
                  //輸出結(jié)果:
                  //        Employee{name='Jack', salary=2000}
                  //        Employee{name='Jack', salary=900}
                  //        Employee{name='John', salary=1300}
                  //        Employee{name='Tom', salary=1000}
      
                  //打印原始列表,看看是否被改變,注意我們通過stream進(jìn)行排序操作,原始的列表元素順序沒有變化,也就是說我們沒有修改原始的list
                  System.out.println(list);
      
                  //Stream排序和集合本身的排序方法對(duì)比
      
                  //我們使用List接口本身的sort方法再來排序一下看看
                  list.sort((e1,e2)->{
                      if(e1.getName().equals(e2.getName())){
                          return e2.getSalary()-e1.getSalary();
                      }else{
                          return e1.getName().compareTo(e2.getName());
                      }
                  });
                  //排序后再次打印一下list本身,可以發(fā)現(xiàn),list本身元素的順序被修改過了
                  System.out.println(list);
              }
      }
      
      

      5.2.4.消費(fèi)
      peek:如同于map,能得到流中的每一個(gè)元素。但map接收的是一個(gè)Function表達(dá)式,有返回值;而peek接收的是Consumer表達(dá)式,沒有返回值。

      //為Tom增加500工資
      public class Test {
          public static void main(String[] args) {
              List<Employee> list = Arrays.asList(
                      new Employee("Tom",1000),
                      new Employee("John",1300),
                      new Employee("Jack",2000)
              );
              //如果是Tom,工資增加500
              list.stream().peek(e->{
                  if("Tom".equals(e.getName())){
                      e.setSalary(500+e.getSalary());
                  }
              }).forEach(System.out::println);
              //輸出結(jié)果
      //        Employee{name='Tom', salary=1500}
      //        Employee{name='John', salary=1300}
      //        Employee{name='Jack', salary=2000}
          }
      }
      

      5.3.終止操作

      5.3.1.匹配

      public class Test {
          public static void main(String[] args) {
              List<Integer> list = Arrays.asList(2, 1, 3, 4, 5);
      
              //流中所有的元素都匹配,返回true,否則返回false
              boolean allMatch = list.stream().allMatch(e -> {
                  System.out.println(e);
                  return e > 10;
              }); //false
              System.out.println("allMatch:"+allMatch);
              //流中沒有任何的元素匹配,返回true,否則返回false
              boolean noneMatch = list.stream().noneMatch(e -> {
                  System.out.println(e);
                  return e > 10;
              }); //true
              System.out.println("noneMatch:"+noneMatch);
              //流中只要有任何一個(gè)元素匹配,返回true,否則返回false
              boolean anyMatch = list.stream().anyMatch(e -> {
                  System.out.println(e);
                  return e > 1;
              });  //true
              System.out.println("anyMatch:"+anyMatch);
              //返回流的第一個(gè)元素
              Integer findFirst = list.stream().findFirst().get(); //2
              System.out.println("findFirst"+findFirst);
              //返回流中的任意元素
              Integer findAny = list.stream().findAny().get(); //2
              System.out.println("findAny:"+findAny);
          }
      }
      
      

      5.3.2.聚合

      public class Test {
          public static void main(String[] args) {
              List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
      
              //計(jì)算元素總的數(shù)量
              long count = list.stream().count(); //5
              System.out.println(count);
              //找出最大的元素(需要傳入Lambda比較器)
              Integer max = list.stream().max(Integer::compareTo).get(); //5
              System.out.println(max);
              //找出最小元素(需要傳入Lambda比較器)
              Integer min = list.stream().min(Integer::compareTo).get(); //1
              System.out.println(min);
          }
      }
      

      5.3.3.歸約
      在java.util.stream.Stream接口中,reduce有下面三個(gè)重載的方法

      /**
      第一次執(zhí)行時(shí),accumulator函數(shù)的第一個(gè)參數(shù)為流中的第一個(gè)元素,第二個(gè)參數(shù)為流中元素的第二個(gè)元素;第二次執(zhí)行時(shí),第一個(gè)參數(shù)為第一次函數(shù)執(zhí)行的結(jié)果,第二個(gè)參數(shù)為流中的第三個(gè)元素;依次類推。
      */
      Optional<T> reduce(BinaryOperator<T> accumulator);
      
      /**
      流程跟上面一樣,只是第一次執(zhí)行時(shí),accumulator函數(shù)的第一個(gè)參數(shù)為identity,而第二個(gè)參數(shù)為流中的第一個(gè)元素。
      */
      T reduce(T identity, BinaryOperator<T> accumulator);
      
      /**
      在串行流(stream)中,該方法跟第二個(gè)方法一樣,即第三個(gè)參數(shù)combiner不會(huì)起作用。
      在并行流(parallelStream)中,我們知道流被fork join創(chuàng)建出多個(gè)線程進(jìn)行執(zhí)行,此時(shí)每個(gè)線程的執(zhí)行流程就跟第二個(gè)方法reduce(identity,accumulator)一樣,而第三個(gè)參數(shù)combiner函數(shù),則是將每個(gè)線程的執(zhí)行結(jié)果當(dāng)成一個(gè)新的流,然后使用第一個(gè)方法reduce(accumulator)流程進(jìn)行歸約。
      */
      <U> U reduce(U identity,
                   BiFunction<U, ? super T, U> accumulator,
                   BinaryOperator<U> combiner);
      

      歸約應(yīng)用舉例

      
      public class Test {
          public static void main(String[] args) {
      
              List<Integer> list = Arrays.asList(1, 2, 3, 4, 5, 6, 7, 8, 9, 10);
      
              Integer v = list.stream().reduce((a1, a2) -> a1 + a2).get();
              System.out.println("reduce計(jì)算v="+v);   // 55
      
      
      
              Integer v1 = list.stream().reduce(10, (a1, a2) -> a1 + a2);
              System.out.println("reduce計(jì)算v1="+v1);  //65
      
      
              Integer v2 = list.stream().reduce(0,
                      (a1, a2) -> {
                          return a1 + a2;
                      },
                      (a1, a2) -> {
                          return 1000; //第二個(gè)表達(dá)式在串行流中無效,這里返回1000測(cè)試
                      });
              System.out.println("reduce計(jì)算v2="+v2); 
      
      
              //并行流reduce傳三個(gè)參數(shù)
              Integer v3 = list.parallelStream().reduce(0,
                      (a1, a2) -> {
                          System.out.println(Thread.currentThread().getName()+":parallelStream accumulator: a1:" + a1 + "  a2:" + a2);
                          return a1 + a2;
                      },
                      (a1, a2) -> {
                          System.out.println(Thread.currentThread().getName()+":parallelStream combiner: a1:" + a1 + "  a2:" + a2);
                          return a1 + a2;
                      });
      
              System.out.println("并行流reduce計(jì)算v3=:"+v3);
          }
      }
      

      5.3.4.收集
      collect:接收一個(gè)Collector實(shí)例,將流中元素收集成另外一個(gè)數(shù)據(jù)結(jié)構(gòu)

      <R, A> R collect(Collector<? super T, A, R> collector);
      

      應(yīng)用舉例:

      //創(chuàng)建一個(gè)Person類
      public class Person {
          private String name;
          private String sex;
          private Integer age;
          public Person(String name, String sex, Integer age) {
              this.name = name;
              this.sex = sex;
              this.age = age;
          }
      
          @Override
          public String toString() {
              return "Person{" +
                      "name='" + name + '\'' +
                      ", sex='" + sex + '\'' +
                      ", age=" + age +
                      '}';
          }
      
          public String getName() {
              return name;
          }
          public void setName(String name) {
              this.name = name;
          }
          public String getSex() {
              return sex;
          }
          public void setSex(String sex) {
              this.sex = sex;
          }
          public Integer getAge() {
              return age;
          }
          public void setAge(Integer age) {
              this.age = age;
          }
      }
      
      public class Test {
      
      
          public static void main(String[] args) {
              //1.collect(Collectors.toList()) 把流轉(zhuǎn)換成一個(gè)列表(允許重復(fù)值)
              Stream<String> stringStream = Stream.of("aa","bb","dd","ee","bb");
              List<String> listResult = stringStream.collect(Collectors.toList());
              System.out.println(listResult);//[aa, bb, dd, ee, bb]
      
              //2.collect(Collectors.toSet()) 把流轉(zhuǎn)換成一個(gè)集合(去重)
              Stream<String> stringStream1 = Stream.of("aa","bb","dd","ee","bb");
              Set<String> setResult = stringStream1.collect(Collectors.toSet());
              System.out.println(setResult);//[aa, bb, dd, ee]
      
              //3.collect(Collectors.toCollection(LinkedList::new)) 把流轉(zhuǎn)換成一個(gè)指定的集合類型(LinkedList)
              Stream<String> stringStream2 = Stream.of("aa","bb","dd","ee","bb");
              LinkedList<String> linkedListResult = stringStream2.collect(Collectors.toCollection(LinkedList::new));
              System.out.println(linkedListResult);//[aa, bb, dd, ee, bb]
      
              //4.collect(Collectors.toCollection(ArrayList::new)) 把流轉(zhuǎn)換成一個(gè)指定的集合類型(ArrayList)
              Stream<String> stringStream3 = Stream.of("aa","bb","dd","ee","bb");
              ArrayList<String> arrayListResult = stringStream3.collect(Collectors.toCollection(ArrayList::new));
              System.out.println(arrayListResult);//[aa, bb, dd, ee, bb]
      
              //5.collect(Collectors.toCollection(TreeSet::new)) 把流轉(zhuǎn)換成一個(gè)指定的集合類型(TreeSet)
              Stream<String> stringStream4 = Stream.of("aa","bb","dd","ee","bb");
              TreeSet<String> treeSetResult = stringStream4.collect(Collectors.toCollection(TreeSet::new));
              System.out.println(treeSetResult);//[aa, bb, dd, ee]
      
              //6.collect(Collectors.joining()) 使用joining拼接流中的元素
              Stream<String> stringStream5 = Stream.of("A","B","C","D","E");
              String result5 = stringStream5.collect(Collectors.joining());
              System.out.println(result5);//ABCDE
      
              //7.collect(Collectors.joining("-")) 使用joining拼接流中的元素并指定分隔符
              Stream<String> stringStream6 = Stream.of("A","B","C","D","E");
              String result6 = stringStream6.collect(Collectors.joining("-"));
              System.out.println(result6);//A-B-C-D-E
      
              //7.collect(Collectors.joining("-","<",">")) 使用joining拼接流中的元素并指定分隔符
              Stream<String> stringStream7 = Stream.of("A","B","C","D","E");
              String result7 = stringStream7.collect(Collectors.joining("-","<",">"));
              System.out.println(result7);//<A-B-C-D-E>
      
      
      
              //8.collect(Collectors.groupingBy(Person::getSex) 對(duì)person流按照性別進(jìn)行分組
              Stream<Person> stringStream8 = Stream.of(
                      new Person("zhangsan", "男", 10),
                      new Person("lisi", "女", 11),
                      new Person("wangwu", "男", 15),
                      new Person("zhaoliu", "男", 12),
                      new Person("xiaoming", "女", 13)
              );
      
              Map<String, List<Person>> resultMap1 = stringStream8.collect(Collectors.groupingBy(Person::getSex));
              System.out.println(resultMap1.toString());//{女=[Person{name='lisi', sex='女', age=11}, Person{name='xiaoming', sex='女', age=13}], 男=[Person{name='zhangsan', sex='男', age=10}, Person{name='wangwu', sex='男', age=15}, Person{name='zhaoliu', sex='男', age=12}]}
      
              //9.collect(Collectors.groupingBy(Person::getSex, Collectors.mapping(Person::getName, Collectors.toList())))
              // 對(duì)person流按照性別進(jìn)行分組,并且把每一組對(duì)象流中人員的姓名轉(zhuǎn)成列表
              Stream<Person> stringStream9 = Stream.of(
                      new Person("zhangsan", "男", 10),
                      new Person("lisi", "女", 11),
                      new Person("wangwu", "男", 15),
                      new Person("zhaoliu", "男", 12),
                      new Person("xiaoming", "女", 13)
              );
              Map<String, List<String>> listMap = stringStream9.collect(
                      Collectors.groupingBy(Person::getSex, Collectors.mapping(Person::getName, Collectors.toList()))
              );
              System.out.println(listMap.toString());//{女=[lisi, xiaoming], 男=[zhangsan, wangwu, zhaoliu]}
      
              //10.collect(Collectors.groupingBy(Person::getSex, Collectors.mapping(Person::getAge, Collectors.maxBy(Integer::compareTo))))
              // 對(duì)person流按照性別進(jìn)行分組,并統(tǒng)計(jì)每一組中年齡最大的人的年齡
              Stream<Person> stringStream10 = Stream.of(
                      new Person("zhangsan", "男", 10),
                      new Person("lisi", "女", 11),
                      new Person("wangwu", "男", 15),
                      new Person("zhaoliu", "男", 12),
                      new Person("xiaoming", "女", 13)
              );
              Map<String, Optional<Integer>> listMap1 = stringStream10.collect(
                      Collectors.groupingBy(Person::getSex, Collectors.mapping(Person::getAge, Collectors.maxBy(Integer::compareTo)))
              );
              System.out.println(listMap1.toString());//{女=Optional[13], 男=Optional[15]}
      
      
              //11.collect(
              //           Collectors.groupingBy(Person::getName,
              //                                 Collectors.reducing(BinaryOperator.maxBy(Comparator.comparingInt(Person::getAge)))
              //   )
              //對(duì)person流按照性別進(jìn)行分組,并統(tǒng)計(jì)每一組中年齡最大的人
              //這個(gè)案例使用了groupingBy和reducing組合
              Stream<Person> stringStream111 = Stream.of(
                      new Person("zhangsan", "男", 10),
                      new Person("lisi", "女", 11),
                      new Person("zhangsan", "男", 15),
                      new Person("zhaoliu", "男", 12),
                      new Person("lisi", "女", 13)
              );
              Map<String, Optional<Person>> resultMap111 = stringStream111.collect(
                      Collectors.groupingBy(Person::getSex,
                              Collectors.reducing(BinaryOperator.maxBy(Comparator.comparingInt(Person::getAge)))
                      )
              );
              System.out.println(resultMap111.toString());//{女=Optional[Person{name='lisi', sex='女', age=13}], 男=Optional[Person{name='zhangsan', sex='男', age=15}]}
      
      
              //12.collect(Collectors.groupingBy(Person::getSex,
              //                 Collectors.reducing(0,Person::getAge,(x,y)->x+y)
              //          )
              //        )
              //對(duì)person流按照性別進(jìn)行分組,并統(tǒng)計(jì)每一組人員年齡和
              Stream<Person> stringStream121 = Stream.of(
                      new Person("zhangsan", "男", 10),
                      new Person("lisi", "女", 11),
                      new Person("zhangsan", "男", 15),
                      new Person("zhaoliu", "男", 12),
                      new Person("lisi", "女", 13)
              );
              Map<String, Integer> resultMap121 = stringStream121.collect(
                      Collectors.groupingBy(Person::getSex,
                              Collectors.reducing(0,Person::getAge,(x,y)->x+y)
                      )
              );
              /*上面這段如果不使用reducing,還可以用下面這中方式完成
              Map<String, Integer> resultMap121 = stringStream121.collect(
                                   Collectors.groupingBy(Person::getSex, Collectors.summingInt(Person::getAge))
              );*/
              System.out.println(resultMap121.toString());//{女=24, 男=37}
      
      
      
              //12.collect(Collectors.groupingBy(Person::getName,  TreeMap::new, Collectors.toList()))
              // 對(duì)person流按照name進(jìn)行分組,結(jié)果轉(zhuǎn)成TreeMap,key是name,value是這個(gè)組的對(duì)象列表
              //groupingBy的第一個(gè)參數(shù)就是獲取分組的屬性,第二個(gè)參數(shù)指定返回類型,第三個(gè)是把每個(gè)分組里面的對(duì)象元素轉(zhuǎn)成一個(gè)列表
              Stream<Person> stringStream11 = Stream.of(
                      new Person("zhangsan", "男", 10),
                      new Person("lisi", "女", 11),
                      new Person("zhangsan", "男", 15),
                      new Person("lisi", "男", 12),
                      new Person("xiaoming", "女", 13)
              );
              TreeMap<String, List<Person>> listMap2 = stringStream11.collect(
                      Collectors.groupingBy(Person::getName,  TreeMap::new, Collectors.toList())
              );
              System.out.println(listMap2.toString());//{lisi=[Person{name='lisi', sex='女', age=11}, Person{name='lisi', sex='男', age=12}], xiaoming=[Person{name='xiaoming', sex='女', age=13}], zhangsan=[Person{name='zhangsan', sex='男', age=10}, Person{name='zhangsan', sex='男', age=15}]}
      
      
              //13.collect(Collectors.collectingAndThen(
              //                Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))),
              //                ArrayList::new))
              //對(duì)Person流先通過TreeSet去重,去重的比較屬性是name,然后在把這個(gè)TreeSet中的元素轉(zhuǎn)換成ArrayList
              Stream<Person> stringStream12 = Stream.of(
                      new Person("lisi", "女", 11),
                      new Person("lisi", "女", 11),
                      new Person("zhangsan", "男", 15),
                      new Person("zhangsan", "男", 15),
                      new Person("xiaoming", "女", 13)
              );
      
              List<Person> list = stringStream12.collect(Collectors.collectingAndThen(
                      Collectors.toCollection(() -> new TreeSet<>(Comparator.comparing(Person::getName))),
                      ArrayList::new));//這里的ArrayList::new等同于pset->new ArrayList(pset),是把前面生成的TreeSet賦值給ArrayList構(gòu)造函數(shù)
              System.out.println(list);//[Person{name='lisi', sex='女', age=11}, Person{name='xiaoming', sex='女', age=13}, Person{name='zhangsan', sex='男', age=15}]
      
      
              //14.collect(Collectors.groupingBy(Person::getName, Collectors.summingInt(Person::getAge)))
              // 對(duì)person流按照姓名進(jìn)行分組,并對(duì)每一個(gè)組內(nèi)的人員的年齡求和
              Stream<Person> stringStream13 = Stream.of(
                      new Person("zhangsan", "男", 10),
                      new Person("zhangsan", "女", 11),
                      new Person("lisi", "男", 15),
                      new Person("zhaoliu", "男", 12),
                      new Person("lisi", "女", 13)
              );
      
              Map<String, Integer> resultMap2 = stringStream13.collect(Collectors.groupingBy(Person::getName, Collectors.summingInt(Person::getAge)));
              System.out.println(resultMap2.toString());//{lisi=28, zhaoliu=12, zhangsan=21}
      
              //15.collect(Collectors.groupingBy(Person::getName, Collectors.averagingInt(Person::getAge)))
              // 對(duì)person流按照姓名進(jìn)行分組,并對(duì)每一個(gè)組內(nèi)的人員的年齡求平均值
              Stream<Person> stringStream14 = Stream.of(
                      new Person("zhangsan", "男", 10),
                      new Person("zhangsan", "女", 11),
                      new Person("lisi", "男", 15),
                      new Person("zhaoliu", "男", 12),
                      new Person("lisi", "女", 13)
              );
      
              Map<String, Double> resultMap3 = stringStream14.collect(Collectors.groupingBy(Person::getName, Collectors.averagingInt(Person::getAge)));
              System.out.println(resultMap3.toString());//{lisi=14.0, zhaoliu=12.0, zhangsan=10.5}
      
              //16.parallel().collect(
              //                Collectors.groupingByConcurrent(Person::getSex, Collectors.summingInt(Person::getAge))
              //        )
              //使用并行流,把人員按照性別分組,計(jì)算每一組中的年齡和,返回的類型是ConcurrentMap,保證線程安全
              Stream<Person> stringStream16 =  Stream.of(
                      new Person("zhangsan", "男", 10),
                      new Person("zhangsan", "女", 11),
                      new Person("lisi", "男", 15),
                      new Person("zhaoliu", "男", 12),
                      new Person("zhaoliu", "男", 16),
                      new Person("zhaoliu", "男", 17),
                      new Person("lisi", "女", 13));
              ConcurrentMap<String, Integer> resultMap4 = stringStream16.parallel().collect(
                      Collectors.groupingByConcurrent(Person::getSex, Collectors.summingInt(Person::getAge))
              );
              System.out.println(resultMap4.toString());//{女=24, 男=70}
      
              //17.collect(Collectors.partitioningBy(p -> p.getAge() > 12))
              //把流中元素根據(jù)年齡是否大于12分成兩組,保存在Map中,key是true或者false,value是對(duì)象列表
              Stream<Person> stringStream17 =  Stream.of(
                      new Person("zhangsan", "女", 11),
                      new Person("wangwu", "男", 10),
                      new Person("lisi", "男", 15),
                      new Person("zhaoliu", "女", 13));
              Map<Boolean, List<Person>> resultMap5 = stringStream17.collect(Collectors.partitioningBy(p -> p.getAge() > 12));
              System.out.println(resultMap5.toString());//{false=[Person{name='zhangsan', sex='女', age=11}], true=[Person{name='lisi', sex='男', age=15}, Person{name='lisi', sex='女', age=13}]}
      
              //18.collect(Collectors.partitioningBy(p -> p.getAge() > 12,Collectors.summingInt(Person::getAge)))
              //把流中元素根據(jù)年齡是否大于12分成兩組,保存在Map中,key是true或者false,每一組的年齡的和
              Stream<Person> stringStream18 =  Stream.of(
                      new Person("zhangsan", "女", 11),
                      new Person("wangwu", "男", 10),
                      new Person("lisi", "男", 15),
                      new Person("zhaoliu", "女", 13));
              Map<Boolean, Integer> resultMap6 = stringStream18.collect(Collectors.partitioningBy(p -> p.getAge() > 12,Collectors.summingInt(Person::getAge)));
              System.out.println(resultMap6.toString());//{false=21, true=28}
      
              //19.Collectors.toMap:有兩個(gè)參數(shù)的toMap方法,流中對(duì)象的key是不允許存在相同的,否則報(bào)錯(cuò)
              //toMap的第二個(gè)參數(shù)需要?jiǎng)?chuàng)建一個(gè)列表,并且key對(duì)應(yīng)的元素對(duì)象放入列表
              Stream<Person> stringStream19 =  Stream.of(
                      new Person("zhangsan", "女", 11),
                      new Person("zhaoliu", "女", 13));
              Map<String, List<Person>> resultMap7 = stringStream19.collect(Collectors.toMap(Person::getName, p -> {
                  List<Person> personList = new ArrayList<>();
                  personList.add(p);
                  return personList;
              }));
              System.out.println(resultMap7.toString());//{zhaoliu=[Person{name='zhaoliu', sex='女', age=13}], zhangsan=[Person{name='zhangsan', sex='女', age=11}]}
      
              //20.Collectors.toMap:有兩個(gè)參數(shù)的toMap方法,流中對(duì)象的key是不允許存在相同的,否則報(bào)錯(cuò)
              //toMap的第二個(gè)參數(shù)直接使用流中的對(duì)象作為key所對(duì)應(yīng)的value
              Stream<Person> stringStream20 = Stream.of(
                      new Person("zhangsan", "女", 11),
                      new Person("zhaoliu", "女", 13));
              Map<String, Person> resultMap8 = stringStream20.collect(Collectors.toMap(Person::getName, p -> p));
              System.out.println(resultMap8.toString());//{zhaoliu=Person{name='zhaoliu', sex='女', age=13}, zhangsan=Person{name='zhangsan', sex='女', age=11}}
      
      
              //21.Collectors.toMap:有三個(gè)參數(shù)的toMap方法,流中對(duì)象的key是允許存在相同的,
              // 第三個(gè)參數(shù)表示key重復(fù)的處理方式(這里是把重復(fù)的key對(duì)應(yīng)的value用新的替換老的)
              //toMap的第二個(gè)參數(shù)直接使用流中的對(duì)象作為key所對(duì)應(yīng)的value
              Stream<Person> stringStream21 = Stream.of(
                      new Person("zhangsan", "女", 11),
                      new Person("zhangsan", "男", 12),
                      new Person("zhaoliu", "男", 13)
              );
      
              Map<String, Person> resultMap9 = stringStream21.collect(
                      Collectors.toMap(Person::getName,
                              p -> p,
                              (oldPerson,newPerson)->newPerson
                      )
              );
              System.out.println(resultMap9.toString());//{zhaoliu=[Person{name='zhaoliu', sex='男', age=13}], zhangsan=[Person{name='zhangsan', sex='女', age=11}, Person{name='zhangsan', sex='女', age=11}]}
      
      
              //22.Collectors.toMap:有三個(gè)參數(shù)的toMap方法,流中對(duì)象的key是允許存在相同的,第三個(gè)參數(shù)表示key重復(fù)的處理方式(這里是把重復(fù)的key對(duì)應(yīng)的value放入列表)
              //toMap的第二個(gè)參數(shù)直接使用流中的對(duì)象作為key所對(duì)應(yīng)的value
              Stream<Person> stringStream22 = Stream.of(
                      new Person("zhangsan", "女", 11),
                      new Person("zhangsan", "女", 11),
                      new Person("zhaoliu", "男", 13)
              );
      
              Map<String, List<Person>> resultMap10 = stringStream22.collect(
                      Collectors.toMap(Person::getName,
                              p -> {
                                  List<Person> personList = new ArrayList<>();
                                  personList.add(p);
                                  return personList;
                              },
                              (oldList,newList)->{
                                  oldList.addAll(newList);
                                  return oldList;
                              })
              );
              System.out.println(resultMap10.toString());//{zhaoliu=[Person{name='zhaoliu', sex='男', age=13}], zhangsan=[Person{name='zhangsan', sex='女', age=11}, Person{name='zhangsan', sex='女', age=11}]}
      
      
              //23.Collectors.toMap:有四個(gè)參數(shù)的toMap方法,流中對(duì)象的key是允許存在相同的,
              //toMap的第二個(gè)參數(shù)直接使用流中的對(duì)象作為key所對(duì)應(yīng)的value
              //第三個(gè)參數(shù)表示key重復(fù)的處理方式(這里是把重復(fù)的key對(duì)應(yīng)的value放入列表)
              //第四個(gè)參數(shù)可以指定一個(gè)返回的Map具體類型
              Stream<Person> stringStream23 = Stream.of(
                      new Person("zhangsan", "女", 11),
                      new Person("zhangsan", "女", 11),
                      new Person("zhaoliu", "男", 13)
              );
      
              Map<String, List<Person>> resultMap11 = stringStream23.collect(
                      Collectors.toMap(Person::getName,
                              p -> {
                                  List<Person> personList = new ArrayList<>();
                                  personList.add(p);
                                  return personList;
                              },
                              (oldList,newList)->{
                                  oldList.addAll(newList);
                                  return oldList;
                              },
                              LinkedHashMap::new
                      )
      
              );
              System.out.println(resultMap11.toString());//{zhangsan=[Person{name='zhangsan', sex='女', age=11}, Person{name='zhangsan', sex='女', age=11}], zhaoliu=[Person{name='zhaoliu', sex='男', age=13}]}
      
      
              //24.Collectors.summarizingInt((a -> a.getAge()))
              //針對(duì)Integer類型的元素進(jìn)行匯總計(jì)算
              //得到1、元素?cái)?shù)量 2、元素的和 3、元素的最大值 4、元素的最小值 5、平均值
              Stream<Person> personStream24=Stream.of(
                              new Person("zhangsan", "女", 11),
                              new Person("zhangsan", "女", 25),
                              new Person("zhaoliu", "男", 13)
              );
              IntSummaryStatistics intSummaryStatistics = personStream24.collect(Collectors.summarizingInt((a -> a.getAge())));
              System.out.println(intSummaryStatistics);//IntSummaryStatistics{count=3, sum=49, min=11, average=16.333333, max=25}
          }
      }
      
      

      image-20220617094840170

      posted @ 2022-07-08 15:41  [奮斗]  閱讀(406)  評(píng)論(0)    收藏  舉報(bào)
      主站蜘蛛池模板: 国产亚洲av嫩草久久| 欧美日韩亚洲国产| 无码人妻丝袜在线视频红杏| 亚洲日韩性欧美中文字幕| 久久这里只精品热免费99| 狠狠躁夜夜人人爽天96| 日本一道一区二区视频| 亚洲一区成人av在线| 在线免费播放亚洲自拍网| 伊人成人在线视频免费| 欧美成人aaa片一区国产精品| 国产精品中文字幕久久| 国产成人精品日本亚洲网站 | 亚洲一区二区精品动漫| 亚洲综合91社区精品福利| 亚洲av永久无码精品秋霞电影影院| 亚洲欧洲一区二区免费| 成人乱码一区二区三区四区| 黄网站色视频免费观看| 国产婷婷综合在线视频中文| 女人下边被添全过视频的网址| 91亚洲一线产区二线产区| 一区二区三区AV波多野结衣| 国产av无码专区亚洲草草| 四虎精品视频永久免费| 白丝乳交内射一二三区| 久久精品国产99久久6| 亚洲国产欧美在线人成AAAA| 日本高清成本人视频一区| 日韩中文免费一区二区| 亚洲中文字幕在线观看| 精品人妻av区乱码| 一区二区三区精品视频免费播放| 日本久久一区二区免高清| 性色在线视频精品| 中文字幕精品亚洲字幕成| 最新国产AV最新国产在钱| 中文字幕在线精品国产| 国产成人亚洲一区二区三区 | 亚洲V天堂V手机在线| 亚洲最大日韩精品一区|