Java流處理--Stream

在Java 8中芒粹,引入了一種新的處理集合數(shù)據(jù)的方式——Stream呛踊。Stream可以讓我們更方便地對集合數(shù)據(jù)進(jìn)行處理,同時也提供了更好的性能和并行處理能力。在工作中卓囚,對集合的處理尤為常見,所以今天來聊一聊Stream

什么是Stream谤专?

Stream是Java 8中引入的一個新的API牺丙,它允許我們以聲明性的方式對集合數(shù)據(jù)進(jìn)行操作。Stream可以處理任何類型的數(shù)據(jù)抒抬,包括基本數(shù)據(jù)類型杨刨、對象和數(shù)組等。它提供了一種簡單而強(qiáng)大的方式來對數(shù)據(jù)進(jìn)行過濾擦剑、轉(zhuǎn)換妖胀、排序和聚合等操作。

如何創(chuàng)建Stream惠勒?

Stream可以從多種數(shù)據(jù)源創(chuàng)建赚抡,包括集合、數(shù)組纠屋、文件涂臣、網(wǎng)絡(luò)等。以下是一些創(chuàng)建Stream的示例:

// 從集合中創(chuàng)建Stream
List<String> list = Arrays.asList("apple", "banana", "orange");
Stream<String> stream = list.stream();

// 從數(shù)組中創(chuàng)建Stream
int[] array = {1, 2, 3, 4, 5};
IntStream intStream = Arrays.stream(array);

// 從文件中創(chuàng)建Stream
Stream<String> lines = Files.lines(Paths.get("filename.txt"));

// 創(chuàng)建無限Stream
Stream<Integer> stream = Stream.iterate(0, n -> n + 2); // 0, 2, 4, 6, ...

如何操作Stream售担?

Stream提供了許多操作赁遗,可以分為中間操作和終端操作兩類。中間操作返回的是一個新的Stream對象族铆,可以進(jìn)行連續(xù)的操作吼和;終端操作會產(chǎn)生一個最終的結(jié)果,結(jié)束整個操作流程骑素。

以下是一些常用的Stream操作:

中間操作

  • filter(Predicate<T> predicate):根據(jù)指定的條件過濾Stream中的元素炫乓;
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> filteredNames = names.stream()
    .filter(name -> name.length() > 4)
    .collect(Collectors.toList());
System.out.println(filteredNames); // Output: [Charlie, David]
  • map(Function<T, R> mapper):將Stream中的元素映射為另一種類型;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> squaredNumbers = numbers.stream()
    .map(n -> n * n)
    .collect(Collectors.toList());
System.out.println(squaredNumbers); // Output: [1, 4, 9, 16, 25]
  • sorted(Comparator<T> comparator):根據(jù)指定的比較器對Stream中的元素進(jìn)行排序献丑;
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
List<String> sortedNames = names.stream()
    .sorted((name1, name2) -> name1.compareTo(name2))
    .collect(Collectors.toList());
System.out.println(sortedNames); // Output: [Alice, Bob, Charlie, David]
  • distinct():去除Stream中重復(fù)的元素末捣;
List<Integer> numbers = Arrays.asList(1, 2, 3, 2, 1, 4, 5, 4, 3);
List<Integer> distinctNumbers = numbers.stream()
    .distinct()
    .collect(Collectors.toList());
System.out.println(distinctNumbers); // Output: [1, 2, 3, 4, 5]
  • limit(long maxSize):返回一個不超過指定大小的Stream;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> limitedNumbers = numbers.stream()
    .limit(3)
    .collect(Collectors.toList());
System.out.println(limitedNumbers); // Output: [1, 2, 3]
  • skip(long n):跳過前n個元素创橄,返回剩余的Stream箩做。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
List<Integer> skippedNumbers = numbers.stream()
    .skip(2)
    .collect(Collectors.toList());
System.out.println(skippedNumbers); // Output: [3, 4, 5]

終端操作

  • forEach(Consumer<T> action):對Stream中的每個元素執(zhí)行指定的操作;
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
names.stream()
    .forEach(name -> System.out.println("Hello, " + name + "!"));
// Output: Hello, Alice!
//         Hello, Bob!
//         Hello, Charlie!
//         Hello, David!
  • toArray():將Stream中的元素轉(zhuǎn)換為數(shù)組妥畏;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Integer[] numberArray = numbers.stream()
    .toArray(Integer[]::new);
System.out.println(Arrays.toString(numberArray)); // Output: [1, 2, 3, 4, 5]
  • reduce(T identity, BinaryOperator<T> accumulator):將Stream中的元素依次歸約為一個值邦邦;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
int sum = numbers.stream()
    .reduce(0, (a, b) -> a + b);
System.out.println(sum); // Output: 15
  • collect(Collector<T, A, R> collector):將Stream中的元素轉(zhuǎn)換為另一種形式安吁,例如List、Map等燃辖;
List<String> names = Arrays.asList("Alice", "Bob", "Charlie", "David");
Map<String, Integer> nameLengths = names.stream()
                                        .collect(Collectors.toMap(
                                            name -> name,
                                            name -> name.length()));
System.out.println(nameLengths); // Output: {Alice=5, Bob=3, Charlie=7, David=5}
  • count():返回Stream中的元素個數(shù)鬼店;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
long count = numbers.stream()
                    .count();
System.out.println(count); // Output: 5
  • anyMatch(Predicate<T> predicate):判斷Stream中是否存在滿足指定條件的元素;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean hasEvenNumber = numbers.stream()
                                .anyMatch(n -> n % 2 == 0);
System.out.println(hasEvenNumber); // Output: true
  • allMatch(Predicate<T> predicate):判斷Stream中是否所有元素都滿足指定條件黔龟;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean allNumbersArePositive = numbers.stream()
                                        .allMatch(n -> n > 0);
System.out.println(allNumbersArePositive); // Output: true
  • noneMatch(Predicate<T> predicate):判斷Stream中是否不存在滿足指定條件的元素妇智;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
boolean noNegativeNumbers = numbers.stream()
                                    .noneMatch(n -> n < 0);
System.out.println(noNegativeNumbers); // Output: true
  • findFirst():返回Stream中的第一個元素;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> firstNumber = numbers.stream()
                                    .findFirst();
System.out.println(firstNumber); // Output: Optional[1]
  • findAny():返回Stream中的任意一個元素氏身;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> anyNumber = numbers.stream()
        .filter(n -> n % 2 == 0)
        .findAny();
System.out.println(anyNumber); // Output: Optional[2] (or Optional[4], depending on the stream implementation)
  • max(Comparator<T> comparator):返回Stream中的最大元素巍棱;
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> maxNumber = numbers.stream()
        .max((n1, n2) -> n1.compareTo(n2));
System.out.println(maxNumber); // Output: Optional[5]
  • min(Comparator<T> comparator):返回Stream中的最小元素。
List<Integer> numbers = Arrays.asList(1, 2, 3, 4, 5);
Optional<Integer> minNumber = numbers.stream()
        .min((n1, n2) -> n1.compareTo(n2));
System.out.println(minNumber); // Output: Optional[1]

Stream的并行處理能力

Stream還提供了并行處理能力蛋欣,可以在多個線程上同時處理數(shù)據(jù)航徙,提高處理速度。只需要在創(chuàng)建Stream對象時陷虎,調(diào)用parallel()方法即可啟用并行處理到踏。

List<Integer> list = Arrays.asList(1, 2, 3, 4, 5);
int sum = list.parallelStream().mapToInt(Integer::intValue).sum();

需要注意的是,并不是所有的操作都適合并行處理泻红,例如排序和去重等操作會影響并行處理的效率夭禽。

Stream的優(yōu)點

使用Stream處理數(shù)據(jù)有以下幾個優(yōu)點:

  • 聲明性的代碼:可以更清晰地表達(dá)數(shù)據(jù)的處理流程霞掺,減少冗余代碼谊路;
  • 更好的性能:Stream可以充分利用多核處理器的性能,提高數(shù)據(jù)處理效率菩彬;
  • 與Lambda表達(dá)式結(jié)合使用:可以更方便地處理數(shù)據(jù)缠劝,減少代碼的復(fù)雜度和冗余度。

結(jié)論

Stream是Java 8中一個強(qiáng)大的API骗灶,可以幫助我們更方便地處理集合數(shù)據(jù)惨恭,同時提供了更好的性能和并行處理能力。掌握Stream的相關(guān)技術(shù)耙旦,可以讓我們的代碼更加簡潔脱羡、高效、易于維護(hù)免都。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末锉罐,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子绕娘,更是在濱河造成了極大的恐慌脓规,老刑警劉巖,帶你破解...
    沈念sama閱讀 217,826評論 6 506
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件险领,死亡現(xiàn)場離奇詭異侨舆,居然都是意外死亡秒紧,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,968評論 3 395
  • 文/潘曉璐 我一進(jìn)店門挨下,熙熙樓的掌柜王于貴愁眉苦臉地迎上來熔恢,“玉大人,你說我怎么就攤上這事复颈〖ㄆ福” “怎么了?”我有些...
    開封第一講書人閱讀 164,234評論 0 354
  • 文/不壞的土叔 我叫張陵耗啦,是天一觀的道長凿菩。 經(jīng)常有香客問我,道長帜讲,這世上最難降的妖魔是什么衅谷? 我笑而不...
    開封第一講書人閱讀 58,562評論 1 293
  • 正文 為了忘掉前任,我火速辦了婚禮似将,結(jié)果婚禮上获黔,老公的妹妹穿的比我還像新娘。我一直安慰自己在验,他們只是感情好玷氏,可當(dāng)我...
    茶點故事閱讀 67,611評論 6 392
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著腋舌,像睡著了一般盏触。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上块饺,一...
    開封第一講書人閱讀 51,482評論 1 302
  • 那天赞辩,我揣著相機(jī)與錄音,去河邊找鬼授艰。 笑死辨嗽,一個胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的淮腾。 我是一名探鬼主播糟需,決...
    沈念sama閱讀 40,271評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼谷朝!你這毒婦竟也來了洲押?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,166評論 0 276
  • 序言:老撾萬榮一對情侶失蹤徘禁,失蹤者是張志新(化名)和其女友劉穎诅诱,沒想到半個月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體送朱,經(jīng)...
    沈念sama閱讀 45,608評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡娘荡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 37,814評論 3 336
  • 正文 我和宋清朗相戀三年干旁,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片炮沐。...
    茶點故事閱讀 39,926評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡争群,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出大年,到底是詐尸還是另有隱情换薄,我是刑警寧澤,帶...
    沈念sama閱讀 35,644評論 5 346
  • 正文 年R本政府宣布翔试,位于F島的核電站轻要,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏垦缅。R本人自食惡果不足惜冲泥,卻給世界環(huán)境...
    茶點故事閱讀 41,249評論 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望壁涎。 院中可真熱鬧凡恍,春花似錦、人聲如沸怔球。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,866評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽竟坛。三九已至闽巩,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間流码,已是汗流浹背又官。 一陣腳步聲響...
    開封第一講書人閱讀 32,991評論 1 269
  • 我被黑心中介騙來泰國打工延刘, 沒想到剛下飛機(jī)就差點兒被人妖公主榨干…… 1. 我叫王不留漫试,地道東北人。 一個月前我還...
    沈念sama閱讀 48,063評論 3 370
  • 正文 我出身青樓碘赖,卻偏偏與公主長得像驾荣,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子普泡,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 44,871評論 2 354

推薦閱讀更多精彩內(nèi)容