關(guān)于JAVA8的 Stream學(xué)習(xí)
一、Stream的使用
1 創(chuàng)建
- 通過Collection接口的實(shí)現(xiàn)類提供的 stream()方法,或
- 通過Arrays中的靜態(tài)方法 stream()獲取
- 通過Stream類中的靜態(tài)方法 of()
- 無限流(迭代/生成)
/** * @Author: 郜宇博 * @Date: 2021/9/1 23:28 * 流操作 */ public class StreamTests { @Test public void test(){ //1.通過Collection接口的實(shí)現(xiàn)類提供的 stream()方法,或 Collection<String> list = new ArrayList<>(); list.stream(); list.parallelStream(); //2.通過Arrays中的靜態(tài)方法 stream()獲取 Integer[] integers = new Integer[10]; Arrays.stream(integers); //3.通過Stream類中的靜態(tài)方法 of() Stream<String> stream = Stream.of("1","2"); //4.無限流 //迭代 Stream<Integer> iterate = Stream.iterate(0, (x) -> x + 2); //生成 Stream<Double> generate = Stream.generate(() -> Math.random()); } }
1.1.1并行流parallelStream
parallelStream提供了流的并行處理,它是Stream的另一重要特性,其底層使用Fork/Join框架實(shí)現(xiàn)。簡(jiǎn)單理解就是多線程異步任務(wù)的一種實(shí)現(xiàn)。
2 步驟
- 創(chuàng)建Stream;
- 轉(zhuǎn)換Stream,每次轉(zhuǎn)換原有Stream對(duì)象不改變,返回一個(gè)新的Stream對(duì)象(可以有多次轉(zhuǎn)換);
- 對(duì)Stream進(jìn)行聚合(Reduce)操作,獲取想要的結(jié)果;
二、Stream的特性
惰性求值:
多個(gè)中間操作
可以連接起來形成一個(gè)流水線,除非流水線上觸發(fā)終止操作,否則中間操作不會(huì)執(zhí)行任何處理!而是在終止操作時(shí)一次性全部處理,這種情況稱為“惰性求值”。
三、中間操作
篩選與切片】
1 filter()
接受lambda表達(dá)式,從流中排除某些元素
@Test public void test2(){ //獲取一個(gè)數(shù)組 ArrayList<Integer> arrayList = new ArrayList<>(); for (int i = 0; i <10; i++) { arrayList.add(i); } //流操作:獲取大于5的 arrayList.stream().filter((num)->num>5).forEach(System.out::println); } //結(jié)果: 6 7 8 9
2 limit()
截?cái)嗔?,使其元素個(gè)數(shù)不超過一定數(shù)量
滿足limit的數(shù)量后,就短路,不在執(zhí)行后續(xù)操作
@Test public void test2(){ //獲取一個(gè)數(shù)組 ArrayList<Integer> arrayList = new ArrayList<>(); for (int i = 0; i <10; i++) { arrayList.add(i); } //流操作:獲取大于5的 arrayList.stream().filter((num)->num>5) .limit(2) .forEach(System.out::println); } //結(jié)果: 6 7
3 skip()
跳過元素,跳過前n個(gè)元素,執(zhí)行后面的元素,如果不足n個(gè)則返回空流
@Test public void test2(){ //獲取一個(gè)數(shù)組 ArrayList<Integer> arrayList = new ArrayList<>(); for (int i = 0; i <10; i++) { arrayList.add(i); } //流操作:獲取大于5的 arrayList.stream().filter((num)->num>5) .skip(2) .forEach(System.out::println); } //結(jié)果: 8 9 3.3 map() 映射,在方法中使用方法Function< T> 函數(shù)型接口 -----> R apply(T t); @Test public void test4(){ //獲取一個(gè)list List<String> list = Arrays.asList("aaa","bbb","ccc"); //使用流操作 轉(zhuǎn)化大寫 list.stream().map((str)->str.toUpperCase()) .forEach(System.out::println); } /*結(jié)果:AAA BBB CCC*/ @Test public void test3(){ //獲取一個(gè)list List<String> list = Arrays.asList("aaa","bbb","ccc"); //流操作: 將list中的元素取出 //第一步使用map取出流,流里存放的還是流 //因此需要二次foreach Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper); chs.forEach((stream)->{ stream.forEach(System.out::print); }); } //將str返回為流對(duì)象 public static Stream<Character> getUpper(String str){ List<Character> list = new ArrayList<>(); for (Character character: str.toCharArray()){ list.add(character); } return list.stream(); } //結(jié)果:aaabbbccc
4 map()
映射,在方法中使用方法Function< T> 函數(shù)型接口 -----> R apply(T t);
@Test public void test4(){ //獲取一個(gè)list List<String> list = Arrays.asList("aaa","bbb","ccc"); //使用流操作 轉(zhuǎn)化大寫 list.stream().map((str)->str.toUpperCase()) .forEach(System.out::println); } /*結(jié)果:AAA BBB CCC*/
@Test public void test3(){ //獲取一個(gè)list List<String> list = Arrays.asList("aaa","bbb","ccc"); //流操作: 將list中的元素取出 //第一步使用map取出流,流里存放的還是流 //因此需要二次foreach Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper); chs.forEach((stream)->{ stream.forEach(System.out::print); }); } //將str返回為流對(duì)象 public static Stream<Character> getUpper(String str){ List<Character> list = new ArrayList<>(); for (Character character: str.toCharArray()){ list.add(character); } return list.stream(); } //結(jié)果:aaabbbccc
3.1 flatMap
相當(dāng)于集合方法的 addAll
即:將流中的流內(nèi)元素取出,放入一個(gè)流中,而不是流內(nèi)套流
@Test public void test3(){ //獲取一個(gè)list List<String> list = Arrays.asList("aaa","bbb","ccc"); //流操作: 將list中的元素取出 //第一步使用map取出流,流里存放的還是流 //因此需要二次foreach Stream<Stream<Character>> chs = list.stream().map(StreamTests::getUpper); chs.forEach((stream)-> stream.forEach(System.out::print)); System.out.println("\n====="); //方法二: //使用flatMap list.stream().flatMap(StreamTests::getUpper).forEach(System.out::print); }
5 sorted
@Test public void test5(){ List<String> list = Arrays.asList("aaa", "ccc", "bbbb", "eeeee"); //自然排序 list.stream() .sorted() .forEach(System.out::println); System.out.println("============="); //定制排序 list.stream() .sorted((x,y)->{ //如果長(zhǎng)度一樣,則按照字典排序 if (x.length() == y.length()){ return x.compareTo(y); } //如果長(zhǎng)度不一樣則按照長(zhǎng)度的降序排序 else { return y.length() - x.length(); } }) .forEach(System.out::println); } /*結(jié)果: aaa bbbb ccc eeeee ============= eeeee bbbb aaa ccc */
四、終止操作
查找與匹配
1 allMatch
Predicate<? super T> predicate /** * @Author: 郜宇博 * @Date: 2021/9/3 14:00 * 終止操作 */ public class FinalOperation { static ArrayList<Student> list; /** * allMath 檢查是否全部元素符合 */ @BeforeEach public void before(){ //準(zhǔn)備集合 Student student1 = new Student(10,"張三", Student.Status.Sad); Student student2 = new Student(20,"李四", Student.Status.Happy); Student student3 = new Student(30,"王五", Student.Status.Free); Student student4 = new Student(18,"田七", Student.Status.Free); Student student5 = new Student(140,"趙六", Student.Status.Tired); list = new ArrayList<>(); list.add(student1); list.add(student2); list.add(student3); list.add(student4); list.add(student5); } } class Student{ private int age; private String name; private Status status; public int getAge() { return age; } public String getName() { return name; } public Status getStatus() { return status; } /** * 枚舉狀態(tài) */ public enum Status{ Free,Tired,Happy,Sad; } public Student(int age, String name, Status status) { this.age = age; this.name = name; this.status = status; } } /** * 是否全部年齡都大于20 */ @Test public void test1(){ boolean b = list.stream().allMatch((s) -> s.getAge() > 20); System.out.println(b); } //結(jié)果: false
2 anyMatch
Predicate<? super T> predicate /** * 是否存在年齡大于20的 */ @Test public void test2(){ boolean b = list.stream().anyMatch((s) -> s.getAge() > 20); System.out.println(b); } //結(jié)果:true
3 noneMatch
Predicate<? super T> predicate /** * 是否沒有滿足年齡大于20的 * */ @Test public void test3(){ boolean b = list.stream().noneMatch((s) -> s.getAge() > 20); System.out.println(b); } //結(jié)果:false
4 findFirst()
返回第一元素,但結(jié)果可能為null, 因此使用Optional<T> 來接收,如果為null則可以替換。
/** * 返回第一元素 */ @Test public void test4(){ Optional<Student> first = list.stream() .filter((e) -> e.getStatus().equals(Student.Status.Free)) .findFirst(); System.out.println(first); } //結(jié)果:Optional[Student{age=30, name='王五', status=Free}]
5 findAny()
返回任意一個(gè)
/** * 返回任意一個(gè) * */ @Test public void test5(){ Optional<Student> b = list.parallelStream() .filter((student -> student.getAge()<30)) .findAny(); System.out.println(b.get()); } //結(jié)果: 任意一個(gè)年齡小于30的學(xué)生
6 count
/** * 獲取數(shù)量count */ @Test public void test6(){ long count = list.stream().count(); System.out.println(count); } //結(jié)果 : 5
7 max
/** * 獲得最大值 */ @Test public void test7(){ Optional<Integer> max = list.stream() .map(x->x.getAge()) .max(Integer::compare); System.out.println(max.get()); } //結(jié)果: 140
8 min
/** * 獲得最小值 */ @Test public void test7(){ Optional<Integer> max = list.stream() .map(x->x.getAge()) .min(Integer::compare); System.out.println(max.get()); }
9 forEach
@Test public void test2(){ //獲取一個(gè)數(shù)組 ArrayList<Integer> arrayList = new ArrayList<>(); for (int i = 0; i <10; i++) { arrayList.add(i); } //流操作:獲取大于5的 arrayList.stream().filter((num)->num>5) .limit(2) .forEach(System.out::println); } //結(jié)果: 6 7
10 reduce
/** * 歸納 */ @Test public void test8(){ Integer reduce = list.stream() .map(Student::getAge) .reduce(0, (x, y) -> x + y); System.out.println(reduce); //方法二: //此方法有可能為null,因此封裝為Optional對(duì)象 Optional<Integer> reduce1 = list.stream() .map(Student::getAge) .reduce(Integer::sum); System.out.println(reduce1.get()); }
11 collect
可以收集為集合類,
可以在收集后進(jìn)行分組、多級(jí)分組、分片
/** * 收集 */ @Test public void test9(){ List<Student> collect = list.stream().collect(Collectors.toList()); collect.forEach(System.out::println); //方式二: HashSet<Student> collect1 = list.stream().collect(Collectors.toCollection(HashSet::new)); collect.forEach(System.out::println); } /* 結(jié)果:Student{age=10, name='張三', status=Sad} Student{age=20, name='李四', status=Happy} Student{age=30, name='王五', status=Free} Student{age=18, name='田七', status=Free} Student{age=140, name='趙六', status=Tired} */ /** * 使用收集可以計(jì)算最大值、最小值、平均值、等 * 也可以進(jìn)行分組 */ @Test public void test10(){ Map<Student.Status, List<Student>> collect = list.stream().collect(Collectors.groupingBy((x) -> x.getStatus())); System.out.println(collect.size()); System.out.println(collect); }
到此這篇關(guān)于JAVA8 Stream學(xué)習(xí)的文章就介紹到這了,更多相關(guān)JAVA8 Stream內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Java和Rust實(shí)現(xiàn)JSON序列化互轉(zhuǎn)的解決方案詳解
這篇文章主要為大家詳細(xì)介紹了Java和Rust實(shí)現(xiàn)JSON序列化互轉(zhuǎn)的解決方案,文中的示例代碼講解詳細(xì),感興趣的小伙伴可以跟隨小編一起學(xué)習(xí)一下2024-03-03Caused?by:?java.lang.NumberFormatException:?For?input?s
這篇文章主要介紹了Caused?by:?java.lang.NumberFormatException:?For?input?string:?“port“,本文給大家分享完美解決方法,需要的朋友可以參考下2023-01-01Java實(shí)現(xiàn)微信支付的項(xiàng)目實(shí)踐
最近的一個(gè)項(xiàng)目中涉及到了支付業(yè)務(wù),其中用到了微信支付和支付寶支付,本文就來介紹一下Java實(shí)現(xiàn)微信支付的項(xiàng)目實(shí)踐,具有一定的參考價(jià)值,感興趣的可以了解一下2023-10-10SpringCloud手寫Ribbon實(shí)現(xiàn)負(fù)載均衡
這篇文章主要介紹了SpringCloud手寫Ribbon實(shí)現(xiàn)負(fù)載均衡的示例代碼,文中通過示例代碼介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2021-01-01安卓系統(tǒng)中實(shí)現(xiàn)搖一搖畫面振動(dòng)效果的方法
這篇文章主要介紹了安卓系統(tǒng)中實(shí)現(xiàn)搖一搖畫面振動(dòng)效果的方法,調(diào)用Android SDK中的SensorEventListener接口,需要的朋友可以參考下2015-07-07SpringBoot啟動(dòng)并初始化執(zhí)行sql腳本問題
這篇文章主要介紹了SpringBoot啟動(dòng)并初始化執(zhí)行sql腳本問題,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2023-01-01java實(shí)現(xiàn)多人多牌數(shù)比較游戲
這篇文章主要為大家詳細(xì)介紹了java實(shí)現(xiàn)多人多牌數(shù)比較游戲,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01