日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

【java学习笔记】java se8的流库概念以及使用

發(fā)布時(shí)間:2024/9/30 编程问答 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【java学习笔记】java se8的流库概念以及使用 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  • 概念
    • 代碼實(shí)例
    • 流的創(chuàng)建
    • 惰性求值與及早求值


概念

流提供了一種讓我們可以在比集合更高的概念級別上指定計(jì)算的數(shù)據(jù)視圖。通過使用流,我們可以說明想要完成什么任務(wù),而不是說明如何去實(shí)現(xiàn)它。我們將操作的調(diào)度留給具體實(shí)現(xiàn)去解決。例如,假設(shè)我們想要計(jì)算某個(gè)屬性的平均值,那么我們就可以指定數(shù)據(jù)源和該屬性,然后,流庫就可以對計(jì)算進(jìn)行優(yōu)化,例如,使用多線程來計(jì)算總和與個(gè)數(shù),并將結(jié)果合并。它是在Java SE 8中引入的,用來以“做什么而非怎么做”的方式處理集合。

代碼實(shí)例

下面一個(gè)例子:

String contents = new String(Files,readAllBytes(Paths.get("mm.txt"), StandardCharsets.UTF_8));List<String>words = Arrays.asList(contents.split("\\PL+"));//long count = 0;for(String w:words){if(w.length()>12)count++;}//如果使用流,也可以用這樣的寫法long count = words.stream().filter(w->w.length()>12).count(); Stream<T> filter(Predicate<? super T> p) //產(chǎn)生一個(gè)流,其中包含當(dāng)前流中滿足P的所有元素。`

·long count() 產(chǎn)生當(dāng)前流中元素的數(shù)量。這是一個(gè)終止操作。

java.util.Collection<E>1.2

·default Stream<E> stream()
·default Stream<E> parallelStream()
產(chǎn)生當(dāng)前集合中所有元素的順序流或并行流。
流表a面上看起來和集合很類似,都可以讓我們轉(zhuǎn)換和獲取數(shù)據(jù)。但是,它們之間存在著顯著的差異:
1.流并不存儲(chǔ)其元素。這些元素可能存儲(chǔ)在底層的集合中,或者是按需生成的。
2.流的操作不會(huì)修改其數(shù)據(jù)源。例如,filter方法不會(huì)從新的流中移除元素,而是會(huì)生成一個(gè)新的流,其中不包含被過濾掉的元素。
3.流的操作是盡可能惰性執(zhí)行的。這意味著直至需要其結(jié)果時(shí),操作才 會(huì)執(zhí)行。例如,如果我們只想查找前5個(gè)長單詞而不是所有長單詞,那么filter方法就會(huì)在匹配到第5個(gè)單詞后停止過濾。因此,我們甚至可以操作無限流。

操作流時(shí)的典型流程:建立一個(gè)包含三個(gè)階段的操作管道:
1.創(chuàng)建一個(gè)流。 2.指定將初始流轉(zhuǎn)換為其他流的中間操作,可能包含多個(gè)步驟。 3.應(yīng)用終止操作,從而產(chǎn)生結(jié)果。這個(gè)操作會(huì)強(qiáng)制執(zhí)行之前的惰性操作。從此之后,這個(gè)流就再也不能用了。也可以用parallelStream方法創(chuàng)建并行流

流的創(chuàng)建

可以用Collection接口的stream方法將任何集合轉(zhuǎn)換為一個(gè)流。如果你有一個(gè)數(shù)組,那么可以使用靜態(tài)的Stream.of方法。

Stream<String>words = Stream.of(contends.split("\\pl+");//split returns a String[] array

of方法具有可變長參數(shù),因此我們可以構(gòu)建具有任意數(shù)量引元的流:

Stream<String>words = Stream.of("my","you","and");

使用Array.stream(array,from,to)可以從數(shù)組中位于from(包括)和to(不包括)的元素中創(chuàng)建一個(gè)流
為了創(chuàng)建不包含任何元素的流,可以使用靜態(tài)的Stream.empty方法:

Stream<String>silence = Stream.empty();

Stream接口有兩個(gè)用于創(chuàng)建無限流的靜態(tài)方法。generate方法會(huì)接受一個(gè)不包含任何引元的函數(shù)(或者從技術(shù)上講,是一個(gè)Supplier<T>接口的對象)

Stream<String>echos = Stream.generate(()->"Echo");

static <T> Stream<T> generate(Supplier<T> s)

Where, Stream is an interface and T is the type of stream elements. s
is the Supplier of generated elements and the return value is a new
infinite sequential unordered Stream.

我們可以像下面這樣獲得一個(gè)常量值的流: 或者像下面這樣獲取一個(gè)隨機(jī)數(shù)的流:

public static void main(String[] args) {Stream.generate(new Random()::nextInt).limit(5).forEach(System.out::println);}

輸出
-1891038009
-1978949720
107075108
196723573
2041949678

惰性求值與及早求值

惰性求值:只描述Stream,操作的結(jié)果也是Stream,這樣的操作稱為惰性求值。惰性求值可以像建造者模式一樣鏈?zhǔn)绞褂?#xff0c;最后再使用及早求值得到最終結(jié)果。
及早求值:得到最終的結(jié)果而不是Stream,這樣的操作稱為及早求值。

collect(Collectors.toList()) //將流轉(zhuǎn)換為list。還有toSet(),toMap()等。及早求值。 public class TestCase {public static void main(String[] args) {List<Student> studentList = Stream.of(new Student("路飛", 22, 175),new Student("紅發(fā)", 40, 180),new Student("白胡子", 50, 185)).collect(Collectors.toList());System.out.println(studentList);} }

filter的引元是Predicate/,即從T到boolean的函數(shù)。 通常,我們想要按照某種方式來轉(zhuǎn)換流中的值,此時(shí),可以使用map方法并傳遞執(zhí)行該轉(zhuǎn)換的函數(shù)
map
轉(zhuǎn)換功能,內(nèi)部就是Function接口。惰性求值。例如,

//惰性求值 public class TestCase {public static void main(String[] args) {List<Student> students = new ArrayList<>(3);students.add(new Student("路飛", 22, 175));students.add(new Student("紅發(fā)", 40, 180));students.add(new Student("白胡子", 50, 185));List<String> names = students.stream().map(student -> student.getName()).collect(Collectors.toList());System.out.println(names);} } //輸出結(jié)果 //[路飛, 紅發(fā), 白胡子]

流的轉(zhuǎn)換會(huì)產(chǎn)生一個(gè)新的流,它的元素派生自另一個(gè)流中的元素。我們已經(jīng)看到了filter轉(zhuǎn)換會(huì)產(chǎn)生一個(gè)流,它的元素與某種條件相匹配。如上面的一個(gè)代碼,我們將一個(gè)字符串流轉(zhuǎn)換為了只包含長單詞的另一個(gè)流
我們可以像下面這樣將所有單詞都轉(zhuǎn)換為小寫:

Stream<String>lowercaseWords = words.stream().map(String::toLowerCase);

這里,我們使用的是帶有方法引用的map,但是,通常我們可以使用lambda表達(dá)式來代替:

Stream<String>firstLetters = words.stream().map(s->s.substring(0,1) //產(chǎn)生的流中包含了所有單詞的首字母

·Stream<T>filter(Predicate<?super T>predicate)
產(chǎn)生一個(gè)流,它包含當(dāng)前流中所有滿足斷言條件的元素。 ·<R>Stream<R>map(Function<?super
T,?extends R>mapper) 產(chǎn)生一個(gè)流,它包含將mapper應(yīng)用于當(dāng)前流中所有元素所產(chǎn)生的結(jié)果。
·<R>Stream<R>flatMap(Function<?super T,?extends Stream<?extends
R>>mapper)
產(chǎn)生一個(gè)流,它是通過將mapper應(yīng)用于當(dāng)前流中所有元素所產(chǎn)生的結(jié)果連接到一起而獲得的。(注意,這里的每個(gè)結(jié)果都是一個(gè)流。)

flatmap
多個(gè)stream合并為一個(gè)stream

public class TestCase {public static void main(String[] args) {List<Student> students = new ArrayList<>(3);students.add(new Student("路飛", 22, 175));students.add(new Student("紅發(fā)", 40, 180));students.add(new Student("白胡子", 50, 185));List<Student> studentList = Stream.of(students,asList(new Student("艾斯", 25, 183),new Student("雷利", 48, 176))).flatMap(students1 -> students1.stream()).collect(Collectors.toList());System.out.println(studentList);} //結(jié)果將五個(gè)人都輸出

調(diào)用Stream.of的靜態(tài)方法將兩個(gè)list轉(zhuǎn)換為Stream,再通過flatMap將兩個(gè)流合并為一個(gè)。
max和min
我們經(jīng)常會(huì)在集合中求最大或最小值,使用流就很方便。及早求值。

public class TestCase {public static void main(String[] args) {List<Student> students = new ArrayList<>(3);students.add(new Student("路飛", 22, 175));students.add(new Student("紅發(fā)", 40, 180));students.add(new Student("白胡子", 50, 185));Optional<Student> max = students.stream().max(Comparator.comparing(stu -> stu.getAge()));Optional<Student> min = students.stream().min(Comparator.comparing(stu -> stu.getAge()));//判斷是否有值if (max.isPresent()) {System.out.println(max.get());}if (min.isPresent()) {System.out.println(min.get());}} } //輸出結(jié)果 //Student{name='白胡子', age=50, stature=185, specialities=null} //Student{name='路飛', age=22, stature=175, specialities=null}

max、min接收一個(gè)Comparator(例子中使用java8自帶的靜態(tài)函數(shù),只需要傳進(jìn)需要比較值即可。)并且返回一個(gè)Optional對象,該對象是java8新增的類,專門為了防止null引發(fā)的空指針異常。

reduce
reduce 操作可以實(shí)現(xiàn)從一組值中生成一個(gè)值。在上述例子中用到的 count 、 min 和 max 方法,因?yàn)槌S枚患{入標(biāo)準(zhǔn)庫中。事實(shí)上,這些方法都是 reduce 操作。及早求值。

public static void main(String[] args) {Integer integer = Stream.of(1,2,3,4,5).reduce(0,(acc,x)->acc+x);System.out.println(integer);}

輸出15

總結(jié)

以上是生活随笔為你收集整理的【java学习笔记】java se8的流库概念以及使用的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。