ฉันสับสนเล็กน้อยระหว่างStream#findAny()
และStream#findFirst()
ของ Stream
API ใน Java 8
สิ่งที่ฉันเข้าใจคือทั้งสองจะส่งคืนองค์ประกอบแรกที่ตรงกันจากสตรีมเช่นเมื่อใช้ร่วมกับตัวกรอง?
เหตุใดจึงมีสองวิธีสำหรับงานเดียวกัน? ฉันพลาดอะไรไปรึเปล่า?
ฉันสับสนเล็กน้อยระหว่างStream#findAny()
และStream#findFirst()
ของ Stream
API ใน Java 8
สิ่งที่ฉันเข้าใจคือทั้งสองจะส่งคืนองค์ประกอบแรกที่ตรงกันจากสตรีมเช่นเมื่อใช้ร่วมกับตัวกรอง?
เหตุใดจึงมีสองวิธีสำหรับงานเดียวกัน? ฉันพลาดอะไรไปรึเปล่า?
คำตอบ:
สิ่งที่ฉันเข้าใจคือทั้งสองจะส่งคืนองค์ประกอบแรกที่ตรงกันจากสตรีมเช่นเมื่อใช้ร่วมกับตัวกรอง?
ที่ไม่เป็นความจริง. อ้างอิงจาก javadoc Stream#findAny()
:
ส่งกลับคำ
Optional<T>
อธิบายองค์ประกอบบางส่วนของสตรีมหรือค่าว่างOptional<T>
หากสตรีมว่างเปล่า พฤติกรรมของการดำเนินการนี้ไม่แน่นอนอย่างชัดเจน สามารถเลือกองค์ประกอบใด ๆ ในสตรีมได้ฟรี เพื่อให้ได้ประสิทธิภาพสูงสุดในการทำงานแบบขนาน
ในขณะที่Stream.findFirst()
จะส่งกลับคำOptional<T>
อธิบายอย่างเคร่งครัดองค์ประกอบแรกของสตรีม Stream
ชั้นไม่ได้มีวิธีการดังนั้นฉันคิดว่าคุณหมายถึง.findOne()
.findFirst()
findAny
สามารถส่งคืนองค์ประกอบใด ๆ จากสิ่งนั้นใน (เรียงลำดับ) แบบสุ่มโดยเฉพาะอย่างยิ่งในการดำเนินการสตรีมคู่ขนาน
ไม่ทั้งสองจะไม่ส่งคืนองค์ประกอบแรกของสตรีม
จากStream.findAny()
(เน้นของฉัน):
ส่งกลับคำ
Optional
อธิบายองค์ประกอบบางส่วนของสตรีมหรือค่าว่างOptional
หากสตรีมว่างเปล่านี่คือการทำงานของเทอร์มินัลที่ลัดวงจร
พฤติกรรมของการดำเนินการนี้ไม่แน่นอนอย่างชัดเจน สามารถเลือกองค์ประกอบใด ๆ ในสตรีมได้ฟรี เพื่อให้ได้ประสิทธิภาพสูงสุดในการทำงานแบบขนาน ค่าใช้จ่ายคือการเรียกใช้หลายครั้งในแหล่งเดียวกันอาจไม่ส่งคืนผลลัพธ์เดียวกัน (หากต้องการผลลัพธ์ที่มั่นคงให้ใช้findFirst()
แทน)
ดังนั้นเพื่อให้ง่ายขึ้นอาจเลือกองค์ประกอบแรกของสตรีมหรือไม่ก็ได้
ด้วยการใช้งานเฉพาะของ Oracle ในปัจจุบันฉันเชื่อว่าจะส่งคืนองค์ประกอบแรกในไปป์ไลน์ที่ไม่ขนานกัน อย่างไรก็ตามในท่อคู่ขนานจะไม่ดำเนินการเสมอไปเช่น
System.out.println(IntStream.range(0, 100).parallel().findAny());
มันกลับมาOptionalInt[50]
เมื่อฉันวิ่ง อย่างไรก็ตามคุณต้องไม่พึ่งพาสิ่งนั้น
findFirst ส่งคืนองค์ประกอบแรกของสตรีม แต่ findAny มีอิสระที่จะเลือกองค์ประกอบใด ๆ ในสตรีม
List<String> lst1 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
List<String> lst2 = Arrays.asList("Jhonny", "David", "Jack", "Duke", "Jill","Dany","Julia","Jenish","Divya");
Optional<String> findFirst = lst1.parallelStream().filter(s -> s.startsWith("D")).findFirst();
Optional<String> fidnAny = lst2.parallelStream().filter(s -> s.startsWith("J")).findAny();
System.out.println(findFirst.get()); //Always print David
System.out.println(fidnAny.get()); //Print Jack/Jill/Julia :behavior of this operation is explicitly nondeterministic
ในโหมดคู่ขนานfindAny
ไม่รับประกันคำสั่ง แต่findFirst
ไม่
ฉันเขียนข้อมูลโค้ดเพื่อแสดงความแตกต่างไปที่มัน
ในสตรีม findFirst และ findAny ส่งคืนองค์ประกอบแรกและไม่ดำเนินการส่วนที่เหลือ แต่ในแบบขนานสตรีมจะไม่สามารถพูดได้ว่าคำสั่งและ parallelStream ดำเนินการส่วนที่เหลือของคอลเล็กชัน
เวลา 01:25:00 น
ฉันจะบอกว่าระวังfindFirst()
และfindAny()
ในขณะที่ใช้
จาก Javadoc ของพวกเขา ( ที่นี่และที่นี่ ) ทั้งสองวิธีจะส่งคืนองค์ประกอบที่กำหนดเองจากสตรีม - เว้นแต่สตรีมจะมีลำดับการเผชิญหน้าซึ่งในกรณีนี้findFirst()
จะส่งคืนองค์ประกอบแรกในขณะที่findAny()
จะส่งคืนองค์ประกอบใด ๆ
สมมติว่าเรามีlist
ISBN และชื่อหนังสือที่กำหนดเอง สำหรับสถานการณ์ดูตัวอย่างนี้:
public class Solution {
private Integer ISBN;
private String BookName;
public Solution(int i, String string) {
ISBN =i;
BookName = string;
}
//getters and setters
}
public static void main(String[] args) {
List<Solution> Library = Arrays.asList(new Solution(12,"Java in Action"),new Solution(13,"Java 8"),new Solution(15,"Java 8 Features"),new Solution(16,"Java in Action"));
System.out.println(Library.stream()
.map(p->p.getBookName())
.sorted(Comparator.reverseOrder())
.findFirst());
}
เอาท์พุต :Optional[Java in Action]
อาจมีสถานการณ์สมมติเมื่อชื่อหนังสือเหมือนกัน แต่หมายเลข ISBN แตกต่างกันในกรณีนั้นการเรียงลำดับและการค้นหาหนังสืออาจคล้ายกันมากfindAny()
และจะให้ผลลัพธ์ที่ไม่ถูกต้อง คิดว่าสถานการณ์ที่ 5 เล่มที่มีชื่อ "Java อ้างอิง" แต่มีหมายเลข ISBN แตกต่างกันและหนังสือโดยชื่อจะส่งผลเช่นเดียวกับfindFirst()
findAny()
ลองนึกถึงสถานการณ์ที่:
ISBN Name Of book
+-----+------------------+
| 100 | Java-8 in Action |
+-----+------------------+
| 101 | Java-8 in Action |
+-----+------------------+
| 102 | Java-8 in Action |
+-----+------------------+
| 103 | Java-8 in Action |
+-----+------------------+
| 104 | Java-8 in Action |
+-----+------------------+
ที่นี่ findFirst () และ findAny () จะให้ผลลัพธ์เหมือนกันแม้ว่าจะเรียงลำดับบนBookByName ก็ตาม
Stream
ไม่เรียงลำดับเมื่อไหร่findFirst()
และfindAny()
เหมือนกัน แต่เมื่อStream
ได้รับคำสั่งfindAny()
จะดีกว่า.
Stream
"ถูกสั่ง" หมายความว่าอย่างไร จะเรียงลำดับเสมอ (การดำเนินการจะดำเนินการตามที่กำหนดStream
ในลำดับเดียวกันทุกครั้งเมื่อไม่ได้ขนานกัน) แต่อาจไม่ได้จัดเรียงโดยผู้ใช้
filter
จะใช้a ไปแล้วก็ตามfindAny
สามารถส่งคืนองค์ประกอบใด ๆ รวมทั้งที่ไม่ตรงกับตัวกรองที่ใช้?