java8-強大的Stream API
阿新 • • 發佈:2020-12-30
學習使我快樂,我要去上海的位元組跳動,夢想是要有的,萬一一不小心實現了呢!!!
1、瞭解Stream
Java8中有兩個最為重要的改變。第一個是Lambda表示式,另外一個則是Stream API(java.util.stream.*)
Stream是Java8中處理集合的關鍵抽象概念,對集合進行的操作,可以指定非常複雜的
查詢、過濾和對映資料等操作。使用Stream API對集合資料進行操作,就類似於使用SQL執行資料庫查詢。
也可以使用Stream API來並行執行操作。簡而言之,Stream API提供了一種高效且易於使用的處理資料的方式
【注意】產生一個新流,原來的資料來源沒有任何改變
2、流(stream)到底是什麼?
流是資料渠道,用於操作資料來源(集合、陣列等)所生成的元素序列
“集合講的是資料,流講的是計算”
【注意】
①、Stream 自己不會儲存元素
②、Stream不會改變源物件。相反,他們會返回一個持有結果的新Stream
③、Stream操作是延遲執行的。這意味著它們會等到需要結果的時候才執行
3、Stream操作的三個步驟
1)建立Stream
一個數據源(如:集合,陣列),獲取一個流
2)中間操作
一箇中間操作鏈,對資料來源的資料進行處理
3)終止操作
一個終止操作,執行中間操作鏈,併產生結果
4、建立Stream的四種方式
public classTestStream1 { //建立Stream @Test public void test1(){ //1、可以通過Collection系列集合提供的stream()或 parallelStram List<String> list = new ArrayList<>(); Stream<String> stream1 = list.stream(); //2、通過Arrays中的靜態方法stream()來獲取陣列流 Employee[] emps = newEmployee[10]; Stream<Employee> stream2 = Arrays.stream(emps); //3、通過Stream中的靜態方法 of() Stream<String> stream3 = Stream.of("aa","bb","cc"); //4、建立無限流 //迭代 第一個引數:種子 第二個引數:funtion的函式式介面 Stream<Integer> stream4 = Stream.iterate(0, (x) -> x + 2); stream4.limit(10).forEach(System.out::println); System.out.println("---------------------------------"); //生產 Stream<Double> s = Stream.generate(() -> Math.random()); s.limit(10).forEach(System.out::println); } }
5、Stream 篩選和切片
【注意】多箇中間操作可以連線起來形成一個流水線,除非流水線上觸發終止操作,否則中間操作不會執行任何的
處理!,而是在終止操作時一次性處理,稱為“惰性求值”
/** * @author houChen * @date 2020/12/30 20:18 * @Description: * * 流的中間操作 */ public class TestStream2 { List<Employee> employees = Arrays.asList( new Employee("張三",18,3000), new Employee("李四",45,4000), new Employee("王五",37,3000), new Employee("趙六",18,6000), new Employee("田七",40,10000), new Employee("田七",40,10000)); /* 篩選與切片 filter - 接受Lambda,從流中排除某些元素 limit - 截斷流,使其元素不超過給定數量 skip - 跳過元素,返回一個扔掉了前 n 個元素的流。若流中元素不足n,則返回一個空流。 distinct - 篩選,通過流所生成元素的hashCode()和equals()去除重複元素 */ //filter //內部迭代:迭代操作由Stream API完成 @Test public void test1(){ //中間操作不會不會有任何結果 Stream<Employee> sm = employees.stream().filter((e) -> e.getAge() > 25); //終止操作 //sm.forEach((e) -> System.out.println(e)); sm.forEach(System.out::println); } //limit @Test public void test2(){ employees.stream().filter((e) -> e.getAge() > 25) .limit(2).forEach(System.out::println); } //skip @Test public void test3(){ employees.stream().filter((e) -> e.getAge() > 25) .skip(2).forEach(System.out::println); } //distinct() 【注意】比較的元素需要equals()方法 @Test public void test4(){ employees.stream().filter((e) -> e.getAge() > 25) .skip(2).distinct().forEach(System.out::println); } }
6、Stream對映
/* 對映 map - 接受Lambda,將元素轉換成其他形式或提取資訊。接受一個函式作為引數,該函式會被應用到每個元素上,並將其 對映成一個新的元素。 flatMap - 接收一個函式作為引數,將流中的每個值都換成另一個值,然後把所有的流連線成一個流 */ //將元素中的所有元素轉大寫 @Test public void test5(){ List< String> list = Arrays.asList("aaa","bb","ccc"); list.stream().map((str) -> str.toUpperCase()) .forEach(System.out::println); System.out.println("-----------------------------------"); employees.stream().map(Employee::getName) .forEach(System.out::println); System.out.println("------------------------------------"); Stream<Stream<Character>> sm = list.stream().map(TestStream2::filterCharacter); sm.forEach((stm) -> stm.forEach(System.out::println)); System.out.println("------------------------------------"); System.out.println("上述程式碼優化"); list.stream().flatMap(TestStream2::filterCharacter).forEach(System.out::println); } //方法:將字串轉換成一個流 public static Stream<Character> filterCharacter(String str){ List<Character> list = new ArrayList<>(); for(Character c: str.toCharArray()){ list.add(c); } return list.stream(); }
7、Stream 排序
/* 排序: sorted() : 自然排序 sorted(Comparator com) : 定製排序 */ @Test public void test6(){ List<String> list = Arrays.asList("aaa","bb","ccc"); list.stream().sorted() .forEach(System.out::println); System.out.println("------------------------------------"); list.stream().sorted((x,y) -> -x.compareTo(y))