中文亚洲精品无码_熟女乱子伦免费_人人超碰人人爱国产_亚洲熟妇女综合网

當前位置: 首頁 > news >正文

四川成都網站優(yōu)化百度快速排名技術培訓教程

四川成都網站優(yōu)化,百度快速排名技術培訓教程,dedecms 做的醫(yī)院網站,網站建設計劃書怎么寫Stream操作流 在Java 8中,得益于Lambda所帶來的函數式編程,引入了一個全新的Stream概念,用于解決已有集合類庫既有的弊端。 1.1 集合的迭代 幾乎所有的集合(如 Collection 接口或 Map 接口等)都支持直接或間接的迭代…

Stream操作流

Java 8中,得益于Lambda所帶來的函數式編程,引入了一個全新的Stream概念,用于解決已有集合類庫既有的弊端。

1.1 集合的迭代

幾乎所有的集合(如 Collection 接口或 Map 接口等)都支持直接或間接的迭代遍歷操作。而當我們需要對集合中的元素進行操作的時候,除了必需的添加、刪除、獲取外,最典型的就是集合遍歷。例如:

public class Demo {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("張無忌");list.add("周芷若");list.add("趙敏");list.add("張三");list.add("張三豐");for (String name : list) {System.out.println(name);}}
}

這是一段非常簡單的集合遍歷操作:對集合中的每一個字符串都進行打印輸出操作。

循環(huán)遍歷的弊端
Java 8Lambda讓我們可以更加專注于做什么(What),而不是怎么做(How),這點此前已經結合內部類進行了對比說明。現在,我們仔細體會一下上例代碼,可以發(fā)現:

  • for循環(huán)的語法就是“怎么做”
  • for循環(huán)的循環(huán)體才是“做什么”

為什么使用循環(huán)?因為要進行遍歷。但循環(huán)是遍歷的唯一方式嗎?遍歷是指每一個元素逐一進行處理,而并不是從第一個到最后一個順次處理的循環(huán)。前者是目的,后者是方式。
試想一下,如果希望對集合中的元素進行篩選過濾:

  1. 將集合A根據條件一過濾為子集B;
  2. 然后再根據條件二過濾為子集C。

那怎么辦?在Java 8之前的做法可能為:

這段代碼中含有三個循環(huán),每一個作用不同:

  1. 首先篩選所有姓張的人;
  2. 然后篩選名字有三個字的人;
  3. 最后進行對結果進行打印輸出。
public class DemoFilter {public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("張無忌");list.add("周芷若");list.add("趙敏");list.add("張三");list.add("張三豐");List<String> zhangList = new ArrayList<>();for (String name : list) {if (name.startsWith("張")) {zhangList.add(name);}}List<String> shortList = new ArrayList<>();for (String name : zhangList) {if (name.length() == 3) {shortList.add(name);}}for (String name : shortList) {System.out.println(name);}}
}

每當我們需要對集合中的元素進行操作的時候,總是需要進行循環(huán)、循環(huán)、再循環(huán)。這是理所當然的么?不是。循環(huán)是做事情的方式,而不是目的。另一方面,使用線性循環(huán)就意味著只能遍歷一次。如果希望再次遍歷,只能再使用另一個循環(huán)從頭開始。
那,Lambda的衍生物Stream能給我們帶來怎樣更加優(yōu)雅的寫法呢?

public static void main(String[] args) {List<String> list = new ArrayList<>();list.add("張無忌");list.add("周芷若");list.add("趙敏");list.add("陽頂天");list.add("小昭");list.add("楊逍");list.add("楊過");list.add("韋一笑");list.add("謝遜");list.add("滅絕師太");list.add("靜虛師太");//獲取list的stream流Stream<String> listStream = list.stream();//stream.filter(boolean)  當boolean = true 是保留,false移除//過濾流中的非姓張的人名 //boolean test(T t)Stream<String> zhangStream = listStream.filter(t -> t.startsWith("張"));//姓張 且名字長度是3個字的Stream<String> shortStream = zhangStream.filter(t -> t.length() == 3);//迭代輸出  //void accept(T t)shortStream.forEach(t -> System.out.println(t));//等同于list.stream().filter(s -> s.startsWith("張")).filter(s -> s.length() == 3).forEach(s -> System.out.println(s));}

直接閱讀代碼的字面意思即可完美展示無關邏輯方式的語義:獲取流、過濾姓張、過濾長度為3、逐一打印。代碼中并沒有體現使用線性循環(huán)或是其他任何算法進行遍歷,我們真正要做的事情內容被更好地體現在代碼中。流式版本比之前的寫法要更易于閱讀,因為流遵循了"做什么而非怎么做"的原則。

流表面上看起來和集合很類似,都可以讓我們轉換和獲取數據。但是,它們之間存在著顯著的差異:

  1. 流并不存儲其元素。這些元素可能存儲在底層的集合中,或者是按需生成的。

  2. 流的操作不會修改其數據源。例如,filter方法不會從新的流中移除元素,而是會生成一個新的流,其中不包含被過濾掉的元素。

  3. 流的操作是盡可能惰性執(zhí)行的。這意味著直至需要其結果時,操作才會執(zhí)行。

例如:
如果我們只想査找前5個長單詞而不是所有的長單詞,那么filter方法就會在匹配到第 5 個單詞后就停止過濾。

1.2 流式思想

注意:請暫時忘記對傳統(tǒng)IO流的固有印象!

整體來看,流式思想類似于工廠車間的“生產流水線”

當需要對多個元素進行操作(特別是多步操作)的時候,考慮到性能及便利性,我們應該首先拼好一個“模型”步驟方案,然后再按照方案去執(zhí)行它。

這張圖中展示了過濾、映射、跳過、計數等多步操作,這是一種集合元素的處理方案,而方案就是一種“函數模型”。圖中的每一個方框都是一個“流”,調用指定的方法,可以從一個流模型轉換為另一個流模型。而最右側的數字3是最終結果。
這里的 filter 、 map 、 skip 都是在對函數模型進行操作,集合元素并沒有真正被處理。只有當終結方法 count 執(zhí)行的時候,整個模型才會按照指定策略執(zhí)行操作。而這得益于Lambda的延遲執(zhí)行特性。

備注:“Stream流”其實是一個集合元素的函數模型,它并不是集合,也不是數據結構,其本身并不存儲任何元素(或其地址值)。

1.3 獲取流方式

生成Stream流的方式

  • Collection體系集合

    使用默認方法stream()生成流, default Stream stream()

  • Map體系集合

    把Map轉成Set集合,間接的生成流

  • 數組

    通過Arrays中的靜態(tài)方法stream生成流

  • 同種數據類型的多個數據

    通過Stream接口的靜態(tài)方法of(T… values)生成流

java.util.stream.StreamJava 8新加入的最常用的流接口。(這并不是一個函數式接口。)

public interface Stream<T> extends BaseStream<T, Stream<T>>

獲取一個流非常簡單,有以下幾種常用的方式:

  • 所有的 Collection 集合都可以通過 stream 默認方法獲取流;
  • Stream 接口的靜態(tài)方法 of 可以獲取數組對應的流。

**根據Collection獲取流 **

首先, java.util.Collection 接口中加入了default方法 stream 用來獲取流,所以其所有實現類均可獲取流。

public class DemoGetStream {public static void main(String[] args) {/*獲取Stream流的方式1.Collection中 方法    Stream stream()2.Stream接口 中靜態(tài)方法  of(T...t) 向Stream中添加多個數據*/List<String> list = new ArrayList<>();Stream<String> stream1 = list.stream();Set<String> set = new HashSet<>();Stream<String> stream2 = set.stream();}
}

根據數組獲取流

如果使用的不是集合或映射而是數組,由于數組對象不可能添加默認方法,所以 Stream 接口中提供了靜態(tài)方法of ,使用很簡單:

public static void main(String[] args) {String[] array = { "張無忌", "張翠山", "張三豐", "張翠山" };Stream<String> stream = Stream.of(array);Stream<String> stream3 = Stream.of("張小山");Stream<String> stream4 = Stream.of("張無忌", "張翠山", "張三豐", "張一元");
}

of 方法的參數其實是一個可變參數,所以支持數組。

1.4 常用方法

流模型的操作很豐富,這里介紹一些常用的API。這些方法可以被分成兩種:

  • 終結方法:返回值類型不再是 Stream 接口自身類型的方法,因此不再支持類似 StringBuilder 那樣的鏈式調用。終結方法包括 countforEach等 方法。

  • 非終結方法(中間方法):返回值類型仍然是 Stream 接口自身類型的方法,因此支持鏈式調用。(除了終結方法外,其余方法均為非終結方法。)

    備注:除了以下要介紹的方法外還有更多方法,請自行參考API文檔。

方法名說明
Stream filter(Predicate predicate)用于對流中的數據進行過濾
Stream limit(long maxSize)返回此流中的元素組成的流,截取前指定參數個數的數據
Stream skip(long n)跳過指定參數個數的數據,返回由該流的剩余元素組成的流
static Stream concat(Stream a, Stream b)合并a和b兩個流為一個流
Stream distinct()返回由該流的不同元素(根據Object.equals(Object) )組成的流

filter:過濾

可以通過 filter 方法將一個流轉換成另一個子集流。方法聲明:

Stream<T> filter(Predicate<? super T> predicate);

該接口接收一個 Predicate 函數式接口參數(可以是一個Lambda)作為篩選條件。

public static void main(String[] args) {Stream<String> original = Stream.of("張無忌", "張三豐", "周芷若");Stream<String> result = original.filter((String s) -> s.startsWith("張"));}

limit:取用前幾個

limit 方法可以對流進行截取,只取用前n個。方法:

Stream<T> limit(long maxSize)

參數是一個long型,如果集合當前長度大于參數則進行截取;否則不進行操作?;臼褂?#xff1a;

public static void main(String[] args) {Stream<String> original = Stream.of("張無忌", "張三豐", "周芷若");Stream<String> result = original.limit(2);System.out.println(result.count()); // 2
}

skip:跳過前幾個

如果希望跳過前幾個元素,可以使用 skip 方法獲取一個截取之后的新流:

Stream<T> skip(long n)

如果流的當前長度大于n,則跳過前n個;否則將會得到一個長度為0的空流?;臼褂?#xff1a;

public static void main(String[] args) {Stream<String> original = Stream.of("張無忌", "張三豐", "周芷若");Stream<String> result = original.skip(2);System.out.println(result.count()); // 1
}

concat:組合

如果有兩個流,希望合并成為一個流,那么可以使用 Stream 接口的靜態(tài)方法concat

static <T> Stream<T> concat(Stream<? extends T> a, Stream<? extends T> b)

這是一個靜態(tài)方法,與 java.lang.String 當中的 concat 方法是不同的。

public static void main(String[] args) {Stream<String> streamA = Stream.of("張無忌");Stream<String> streamB = Stream.of("張翠山");Stream<String> result = Stream.concat(streamA, streamB);
}

distinct: 去重

 public static void main(String[] args) {//創(chuàng)建一個集合,存儲多個字符串元素ArrayList<String> list = new ArrayList<String>();list.add("林青霞");list.add("張曼玉");list.add("王祖賢");list.add("柳巖");list.add("張敏");list.add("張無忌");// 取前4個數據組成一個流Stream<String> s1 = list.stream().limit(4);// 跳過2個數據組成一個流Stream<String> s2 = list.stream().skip(2);Stream.concat(s1,s2).distinct().forEach(s-> System.out.println(s));}

終結方法:

forEach : 逐一處理

雖然方法名字叫 forEach ,但是與for循環(huán)中的for-each不同,該方法并不保證元素的逐一消費動作在流中是被有序執(zhí)行的。

void forEach(Consumer<? super T> action);

該方法接收一個 Consumer 接口函數,會將每一個流元素交給該函數進行處理。例如:

public class DemoForEach {public static void main(String[] args) {Stream<String> stream = Stream.of("張無忌", "張三豐", "周芷若");stream.forEach((String str)->{System.out.println(str);});}
}

在這里,lambda表達式 (String str)->{System.out.println(str);} 就是一個Consumer函數式接口的示例。

count:統(tǒng)計個數

正如舊集合 Collection 當中的 size 方法一樣,流提供 count 方法來數一數其中的元素個數:

long count();

此處方法返回值是long而不是int

public static void main(String[] args) {Stream<String> original = Stream.of("張無忌", "張三豐", "周芷若");Stream<String> result = original.filter((String s) -> s.startsWith("張"));System.out.println(result.count()); // 2
}

在上述介紹的各種方法中,凡是返回值仍然為 Stream 接口的為函數拼接方法,它們支持鏈式調用;而返回值不再為Stream 接口的為終結方法,不再支持鏈式調用。

Files.lines : 方法

Files.lines 是 Java 8 中的一個方法,用于讀取文件中的所有行并返回為一個流(Stream)對象。

使用 Files.lines 方法可以方便地逐行讀取文本文件。下面是一個示例代碼:

import java.io.IOException;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.stream.Stream;public class FileLinesExample {public static void main(String[] args) {String filename = "path/to/file.txt";try (Stream<String> lines = Files.lines(Paths.get(filename))) {lines.forEach(System.out::println);} catch (IOException e) {e.printStackTrace();}}
}

在這個示例中,我們使用 Paths.get 方法來獲取文件路徑,并將其傳遞給 Files.lines 方法。然后使用 try-with-resources 語句來確保在讀取完成后關閉流。在 lines.forEach(System.out::println) 中,我們遍歷每一行并打印到控制臺上。

請注意,你需要替換 filename 變量的值為實際的文件路徑。此外,使用 Files.lines 時要注意處理可能拋出的 IOException 異常。

常見末端方法:

返回類型方法名方法簽名描述
voidforEachvoid forEach(Consumer<? super T> action)對流中的每個元素執(zhí)行給定的操作
voidforEachOrderedvoid forEachOrdered(Consumer<? super T> action)保證按照流中元素的遍歷順序執(zhí)行給定的操作
longcountlong count()返回流中的元素數
Optional<T>findFirstOptional findFirst()返回流中的第一個元素
Optional<T>findAnyOptional findAny()返回流中的任意一個元素
booleanallMatchboolean allMatch(Predicate<? super T> predicate)檢查流中的所有元素是否都滿足給定的謂詞
booleananyMatchboolean anyMatch(Predicate<? super T> predicate)檢查流中是否有任意一個元素滿足給定的謂詞
booleannoneMatchboolean noneMatch(Predicate<? super T> predicate)檢查流中的所有元素是否都不滿足給定的謂詞
Optional<T>maxOptional max(Comparator<? super T> comparator)返回流中根據給定比較器最大的元素
Optional<T>minOptional min(Comparator<? super T> comparator)返回流中根據給定比較器最小的元素
TreduceT reduce(T identity, BinaryOperator accumulator)根據給定的起始值和累加函數將流中的所有元素聚合成一個結果
Optional<T>reduceOptional reduce(BinaryOperator accumulator)根據給定的累加函數將流中的所有元素聚合成一個結果
Rcollect R collect(Collector<? super T, A, R> collector)將流中的所有元素收集到一個容器中
IntStreammapToIntIntStream mapToInt(ToIntFunction<? super T> mapper)將流中的元素映射為 int 值,返回一個 IntStream
LongStreammapToLongLongStream mapToLong(ToLongFunction<? super T> mapper)將流中的元素映射為 long 值,返回一個 LongStream
DoubleStreammapToDoubleDoubleStream mapToDouble(ToDoubleFunction<? super T> mapper)將流中的元素映射為 double 值,返回一個 DoubleStream
Stream<T>distinctStream distinct()返回一個去除重復元素之后的新流
Stream<T>sortedStream sorted()返回一個根據自然順序升序排序后的新流
Stream<T>sortedStream sorted(Comparator<? super T> comparator)返回一個根據給定比較器排序后的新流
Stream<T>skipStream skip(long n)返回一個丟棄前 n 個元素后的新流
Stream<T>limitStream limit(long maxSize)截取前 maxSize 個元素返回一個新流

Stream流的收集操作【應用】

  • 概念

    對數據使用Stream流的方式操作完畢后,可以把流中的數據收集到集合中

  • 常用方法

    方法名說明
    R collect(Collector collector)把結果收集到集合中
  • 工具類Collectors提供了具體的收集方式

    方法名說明
    public static Collector toList()把元素收集到List集合中
    public static Collector toSet()把元素收集到Set集合中
    public static Collector toMap(Function keyMapper,Function valueMapper)把元素收集到Map集合中
  • 代碼演示

// toList和toSet方法演示 
public class MyStream7 {public static void main(String[] args) {ArrayList<Integer> list1 = new ArrayList<>();for (int i = 1; i <= 10; i++) {list1.add(i);}list1.add(10);list1.add(10);list1.add(10);list1.add(10);list1.add(10);//filter負責過濾數據的.//collect負責收集數據.//獲取流中剩余的數據,但是他不負責創(chuàng)建容器,也不負責把數據添加到容器中.//Collectors.toList() : 在底層會創(chuàng)建一個List集合.并把所有的數據添加到List集合中.List<Integer> list = list1.stream().filter(number -> number % 2 == 0).collect(Collectors.toList());System.out.println(list);Set<Integer> set = list1.stream().filter(number -> number % 2 == 0).collect(Collectors.toSet());System.out.println(set);
}
}
/**
Stream流的收集方法 toMap方法演示
創(chuàng)建一個ArrayList集合,并添加以下字符串。字符串中前面是姓名,后面是年齡
"zhangsan,23"
"lisi,24"
"wangwu,25"
保留年齡大于等于24歲的人,并將結果收集到Map集合中,姓名為鍵,年齡為值
*/
public class MyStream8 {public static void main(String[] args) {ArrayList<String> list = new ArrayList<>();list.add("zhangsan,23");list.add("lisi,24");list.add("wangwu,25");Map<String, Integer> map = list.stream().filter(s -> {String[] split = s.split(",");int age = Integer.parseInt(split[1]);return age >= 24;}//   collect方法只能獲取到流中剩余的每一個數據.//在底層不能創(chuàng)建容器,也不能把數據添加到容器當中//Collectors.toMap 創(chuàng)建一個map集合并將數據添加到集合當中// s 依次表示流中的每一個數據//第一個lambda表達式就是如何獲取到Map中的鍵//第二個lambda表達式就是如何獲取Map中的值).collect(Collectors.toMap(s -> s.split(",")[0],s -> Integer.parseInt(s.split(",")[1]) ));System.out.println(map);}
}

Stream流綜合練習

案例需求

  • 現在有兩個ArrayList集合,分別存儲6名男演員名稱和6名女演員名稱,要求完成如下的操作

    • 男演員只要名字為3個字的前三人
    • 女演員只要姓林的,并且不要第一個
    • 把過濾后的男演員姓名和女演員姓名合并到一起
    • 把上一步操作后的元素作為構造方法的參數創(chuàng)建演員對象,遍歷數據

    演員類Actor已經提供,里面有一個成員變量,一個帶參構造方法,以及成員變量對應的get/set方法

  • 代碼實現

    演員類

    public class Actor {private String name;public Actor(String name) {this.name = name;}public String getName() {return name;}public void setName(String name) {this.name = name;}
    }
    

    測試類

public class StreamTest {public static void main(String[] args) {//創(chuàng)建集合ArrayList<String> manList = new ArrayList<String>();manList.add("周潤發(fā)");manList.add("成龍");manList.add("劉德華");manList.add("吳京");manList.add("周星馳");manList.add("李連杰");ArrayList<String> womanList = new ArrayList<String>();womanList.add("林心如");womanList.add("張曼玉");womanList.add("林青霞");womanList.add("柳巖");womanList.add("林志玲");womanList.add("王祖賢");//男演員只要名字為3個字的前三人Stream<String> manStream = manList.stream().filter(s -> s.length() == 3).limit(3);//女演員只要姓林的,并且不要第一個Stream<String> womanStream = womanList.stream().filter(s -> s.startsWith("林")).skip(1);//把過濾后的男演員姓名和女演員姓名合并到一起Stream<String> stream = Stream.concat(manStream, womanStream);// 將流中的數據封裝成Actor對象之后打印stream.forEach(name -> {Actor actor = new Actor(name);System.out.println(actor);}); }
}

forEachOrdered 和 forEach 區(qū)別
forEachOrderedforEach 都是 Java 8 中 Stream API 提供的方法,用于對流中的元素進行迭代操作。它們之間的區(qū)別在于元素的處理順序。

  1. forEach 方法:它在并行流上不保證元素的處理順序。在并行流中,元素會按照多個線程處理,可能會導致輸出的順序與源數據的順序不一致。

  2. forEachOrdered 方法:它在并行流上保證元素的處理順序與源數據的順序一致。無論是串行流還是并行流,forEachOrdered 方法都會按照源數據的順序依次處理元素。

下面是一個示例來演示兩者之間的區(qū)別:

import java.util.Arrays;
import java.util.concurrent.TimeUnit;public class ForEachExample {public static void main(String[] args) {String[] words = {"apple", "banana", "cherry", "date"};// forEachSystem.out.println("forEach:");Arrays.stream(words).parallel().forEach(System.out::println);// forEachOrderedSystem.out.println("forEachOrdered:");Arrays.stream(words).parallel().forEachOrdered(System.out::println);}
}

在這個示例中,我們創(chuàng)建了一個包含幾個單詞的字符串數組。然后使用并行流對這些單詞進行處理。通過 forEach 方法打印輸出時,由于并行流的處理順序不確定,每次運行結果可能會有所不同。而通過 forEachOrdered 方法打印輸出時,無論是串行流還是并行流,都會按照源數據的順序依次輸出單詞。

總結來說,forEach 方法適用于不關心元素處理順序的場景,而 forEachOrdered 方法適用于需要保證元素處理順序和源數據順序一致的場景。需要根據具體需求選擇使用哪個方法。

http://www.risenshineclean.com/news/59984.html

相關文章:

  • 關于做網站常見的問題西安seo優(yōu)化公司
  • 濟寧網站建設神華關鍵詞優(yōu)化包含
  • 有哪些網站有收錄做紅酒的商行杭州網絡整合營銷公司
  • 永久免費網站搭建山東網絡推廣網站
  • 做網站時用插件需要注明嗎百度seo關鍵詞優(yōu)化排行
  • 做網站要有哪些知識app推廣代理平臺
  • 東莞樟木頭做網站哪家好百度小說app下載
  • .net做的學校網站百度下載安裝免費
  • 網易做相冊旅游網站海外網絡推廣方案
  • 建站公司專業(yè)地址經典軟文案例100例簡短
  • 高端制作網站公司在線收錄
  • 翻譯網站怎么做網站策劃報告
  • seo網站收錄工具中國工商業(yè)聯合會
  • 北京網站建設公最近軍事新聞熱點大事件
  • 網站只做靜態(tài)頁面安全受到影響蘭州seo整站優(yōu)化服務商
  • 青島網站設計客服人民日報官網
  • 網站用戶投稿怎么做有哪些實用的網絡推廣方法
  • 中國供應商網做網站qq代刷網站推廣免費
  • 佛山響應式網站開發(fā)深圳seo優(yōu)化公司
  • 自己做網站如何盈利世界杯球隊最新排名
  • 購物網站 系統(tǒng)設計seo整站優(yōu)化什么價格
  • wordpress配置教程網站優(yōu)化快速排名軟件
  • 好的網站設計模板廣州seo網站開發(fā)
  • 中電建鐵路建設公司網站查網址
  • 宜昌 醫(yī)院 網站建設seo排名優(yōu)化推廣教程
  • 網站建設單位不給數據庫google推廣教程
  • 防城港北京網站建設廣州權威發(fā)布
  • 安陽做網站公司廣州今天剛剛發(fā)生的重大新聞
  • 網站背景視頻是怎么做的新聞聯播今日新聞
  • 網站建設叫什么軟件seo優(yōu)化費用