您好,登錄后才能下訂單哦!
本篇內容介紹了“JAVA8中Stream的特性和使用”的有關知識,在實際案例的操作過程中,不少人都會遇到這樣的困境,接下來就讓小編帶領大家學習一下如何處理這些情況吧!希望大家仔細閱讀,能夠學有所成!
一、Stream的使用
1.1 創建
1.2 步驟
二、Stream的特性
三、中間操作
3.1 filter()
3.2 limit()
3.3 skip()
3.4 map()
3.5 sorted
四、終止操作
4.1 allMatch
4.2anyMatch
4.3noneMatch
4.4 findFirst()
4.5 findAny()
4.6 count
4.7 max
4.8 min
4.9 forEach
4.10 reduce
4.11 collect
通過Collection接口的實現類提供的 stream()方法,或
通過Arrays中的靜態方法 stream()獲取
通過Stream類中的靜態方法 of()
無限流(迭代/生成)
/** * @Author: 郜宇博 * @Date: 2021/9/1 23:28 * 流操作 */ public class StreamTests { @Test public void test(){ //1.通過Collection接口的實現類提供的 stream()方法,或 Collection<String> list = new ArrayList<>(); list.stream(); list.parallelStream(); //2.通過Arrays中的靜態方法 stream()獲取 Integer[] integers = new Integer[10]; Arrays.stream(integers); //3.通過Stream類中的靜態方法 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()); } }
parallelStream提供了流的并行處理,它是Stream的另一重要特性,其底層使用Fork/Join框架實現。簡單理解就是多線程異步任務的一種實現。
創建Stream;
轉換Stream,每次轉換原有Stream對象不改變,返回一個新的Stream對象(可以有多次轉換);
對Stream進行聚合(Reduce)操作,獲取想要的結果;
惰性求值:
多個中間操作
可以連接起來形成一個流水線,除非流水線上觸發終止操作,否則中間操作不會執行任何處理!而是在終止操作時一次性全部處理,這種情況稱為“惰性求值”。
篩選與切片
接受lambda表達式,從流中排除某些元素
@Test public void test2(){ //獲取一個數組 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); } //結果: 6 7 8 9
截斷流,使其元素個數不超過一定數量
滿足limit的數量后,就短路,不在執行后續操作
@Test public void test2(){ //獲取一個數組 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); } //結果: 6 7
跳過元素,跳過前n個元素,執行后面的元素,如果不足n個則返回空流
@Test public void test2(){ //獲取一個數組 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); } //結果: 8 9 3.3 map() 映射,在方法中使用方法Function< T> 函數型接口 -----> R apply(T t); @Test public void test4(){ //獲取一個list List<String> list = Arrays.asList("aaa","bbb","ccc"); //使用流操作 轉化大寫 list.stream().map((str)->str.toUpperCase()) .forEach(System.out::println); } /*結果:AAA BBB CCC*/ @Test public void test3(){ //獲取一個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返回為流對象 public static Stream<Character> getUpper(String str){ List<Character> list = new ArrayList<>(); for (Character character: str.toCharArray()){ list.add(character); } return list.stream(); } //結果:aaabbbccc
映射,在方法中使用方法Function< T> 函數型接口 -----> R apply(T t);
@Test public void test4(){ //獲取一個list List<String> list = Arrays.asList("aaa","bbb","ccc"); //使用流操作 轉化大寫 list.stream().map((str)->str.toUpperCase()) .forEach(System.out::println); } /*結果:AAA BBB CCC*/
@Test public void test3(){ //獲取一個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返回為流對象 public static Stream<Character> getUpper(String str){ List<Character> list = new ArrayList<>(); for (Character character: str.toCharArray()){ list.add(character); } return list.stream(); } //結果:aaabbbccc
相當于集合方法的 addAll
即:將流中的流內元素取出,放入一個流中,而不是流內套流
@Test public void test3(){ //獲取一個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); }
@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)->{ //如果長度一樣,則按照字典排序 if (x.length() == y.length()){ return x.compareTo(y); } //如果長度不一樣則按照長度的降序排序 else { return y.length() - x.length(); } }) .forEach(System.out::println); } /*結果: aaa bbbb ccc eeeee ============= eeeee bbbb aaa ccc */
查找與匹配
Predicate<? super T> predicate /** * @Author: 郜宇博 * @Date: 2021/9/3 14:00 * 終止操作 */ public class FinalOperation { static ArrayList<Student> list; /** * allMath 檢查是否全部元素符合 */ @BeforeEach public void before(){ //準備集合 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; } /** * 枚舉狀態 */ 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); } //結果: false
Predicate<? super T> predicate /** * 是否存在年齡大于20的 */ @Test public void test2(){ boolean b = list.stream().anyMatch((s) -> s.getAge() > 20); System.out.println(b); } //結果:true
Predicate<? super T> predicate /** * 是否沒有滿足年齡大于20的 * */ @Test public void test3(){ boolean b = list.stream().noneMatch((s) -> s.getAge() > 20); System.out.println(b); } //結果:false
返回第一元素,但結果可能為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); } //結果:Optional[Student{age=30, name='王五', status=Free}]
返回任意一個
/** * 返回任意一個 * */ @Test public void test5(){ Optional<Student> b = list.parallelStream() .filter((student -> student.getAge()<30)) .findAny(); System.out.println(b.get()); } //結果: 任意一個年齡小于30的學生
/** * 獲取數量count */ @Test public void test6(){ long count = list.stream().count(); System.out.println(count); } //結果 : 5
/** * 獲得最大值 */ @Test public void test7(){ Optional<Integer> max = list.stream() .map(x->x.getAge()) .max(Integer::compare); System.out.println(max.get()); } //結果: 140
/** * 獲得最小值 */ @Test public void test7(){ Optional<Integer> max = list.stream() .map(x->x.getAge()) .min(Integer::compare); System.out.println(max.get()); }
@Test public void test2(){ //獲取一個數組 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); } //結果: 6 7
/** * 歸納 */ @Test public void test8(){ Integer reduce = list.stream() .map(Student::getAge) .reduce(0, (x, y) -> x + y); System.out.println(reduce); //方法二: //此方法有可能為null,因此封裝為Optional對象 Optional<Integer> reduce1 = list.stream() .map(Student::getAge) .reduce(Integer::sum); System.out.println(reduce1.get()); }
可以收集為集合類,
可以在收集后進行分組、多級分組、分片
/** * 收集 */ @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); } /* 結果: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} */ /** * 使用收集可以計算最大值、最小值、平均值、等 * 也可以進行分組 */ @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); }
“JAVA8中Stream的特性和使用”的內容就介紹到這里了,感謝大家的閱讀。如果想了解更多行業相關的知識可以關注億速云網站,小編將為大家輸出更多高質量的實用文章!
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。