一、stream()簡介
Java8引入了Stream API用於處理集合數據,它是集合框架的新成員,允許以一種比傳統for/while循環更加聲明式和函數化的方式處理數據。它可以對集合數據進行過濾、映射、分組、排序等操作,讓開發人員更關注於處理數據本身而不是如何實現操作。
二、stream().findany()與findfirst()
1、基本介紹
在Stream中,findany()和findfirst()都是Terminal Operations,表示Terminal Operation可以結束Stream的操作流程,即終止Stream的生成。
Optional findAny();
Optional findFirst();
findAny() 和 findFirst() 方法都會返回一個 Optional 元素,它代表了這個 Stream 的任意一個元素或第一個元素,並且返回值包含元素可能為 null 的情況。它們的區別在於,前者是並行查找,而後者則不是。
2、性能比較
由於findAny是在並行情況下的任意匹配,的確可以提供更高的並行性,因為在採用該方法時,我們不關心返回的元素是哪一個。只要它符合條件就可以了。
然而,正由於它是任意的,可能會導致生成不同的結果,尤其是在並行處理中,因為在並行處理中,對於一個元素集合,每個線程分配到的元素集合不同,所以結果不一定是固定不變的,但這個影響通常是可接受的。
相比之下,findFirst返回Stream中的第一個元素的確切匹配,正如其名稱所示,findFirst()獲取流中的第一個元素。在並行流中findFirst在某些情況下會表現出更好的性能,這是因為它不會使用比較大的流進行掃描,只需搜索第一個匹配項即可,而任意匹配只需要比較開頭部分的流的部分元素。
總之,如果您不關心返回哪個元素,使用findAny是一個比較好的選擇。如果你想要有一種固定的返回值,使用findFirst。
3、代碼示例
下面的代碼是一個簡單的集合的演示,其中我們通過流易語法使用filter()和collect()方法來過濾具有指定物品名稱或品牌名稱的所有物品對象。接下來,我們使用findFirst()方法獲取第一個匹配的元素,然後使用findAny()方法獲取任意一個匹配的元素。
public class StreamExample {
public static void main(String[] args) {
//Create a list of items
List<Item> items = new ArrayList<Item>();
items.add(new Item("name1", "brand1"));
items.add(new Item("name2", "brand2"));
items.add(new Item("name3", "brand3"));
items.add(new Item("name4", "brand4"));
items.add(new Item("name5", "brand5"));
items.add(new Item("name6", "brand6"));
//Filter items with given criteria
Item filteredItem = items.stream()
.filter(item -> item.getName().equals("name1"))
.findFirst().orElse(null);
System.out.println("First matching name item : " + filteredItem);
filteredItem = items.stream()
.filter(item -> item.getBrand().equals("brand2"))
.findAny().orElse(null);
System.out.println("Just filtering with brand : " + filteredItem);
}
}
class Item{
private String name;
private String brand;
public Item(String name, String brand) {
this.name = name;
this.brand = brand;
}
public String getName() {
return name;
}
public String getBrand() {
return brand;
}
public String toString() {
return "Name : " + this.name + ", Brand : " + this.brand;
}
}
三、stream().findany()使用場景
1、Stream中anyMatch()
當使用 Stream.anyMatch() 遍歷 Stream 時,很可能會使用 findAny() 來判斷是否是 true,這種情況下使用 findAny() 可以充分發揮 Stream 的並行優勢。當然,這一局限性並不是影響 Stream 效率的唯一因素,我們需要綜合考慮每一種操作,並選擇最佳方案。
2、Stream中filter()
在 Stream 中使用 filter() + findAny() 可以代替 Stream 中的 findFirst() 方法。它們的結果是相同的,後者的開銷較小,前者可能並行處理。
3、Stream中map()
當我們對 Stream 進行處理時,如果使用了 map() 方法,並且不關心返回哪一個元素,那麼就可以使用 findAny() 方法來獲得任意一個匹配的元素。當然, map() 的返回元素為 int、double 或者 long 基本數據類型時,名為 mapToInt()、mapToDouble() 或 mapToLong() 的方法也可以使用。
4、代碼示例
下面的代碼演示了我們如何使用findAny()方法在String[]數組中查找任何帶有給定名字的人。
import java.util.Optional;
import java.util.stream.Stream;
public class StreamExample {
public static void main(String[] args) {
String[] people = { "Bob", "Alice", "John", "Sarah" };
Optional<String> person = Stream.of(people).filter("John"::equals).findAny();
System.out.println(person.orElse("Not Found"));
}
}
四、stream().findany()總結
stream().findany() 可以用於尋找任意匹配的元素,這個方法可能在並行操作中對性能有所提升。但是這個方法可能對不同的元素集合產生不同的結果。當要求精確的匹配時,可以使用 findFirst() 方法。此外,findAny() 方法還可以用於Stream中anyMatch()、filter()和map()等操作。
參考資料
3. FindAny() vs. FindFirst() in Java Streams
原創文章,作者:小藍,如若轉載,請註明出處:https://www.506064.com/zh-tw/n/295954.html