เมื่อใช้ Java8 สตรีม api ใหม่เพื่อค้นหาองค์ประกอบเฉพาะในคอลเลกชันฉันเขียนโค้ดดังนี้:
String theFirstString = myCollection.stream()
.findFirst()
.get();
ที่นี่ IntelliJ เตือนว่า get () ถูกเรียกโดยไม่ตรวจสอบ isPresent () ก่อน
อย่างไรก็ตามรหัสนี้:
String theFirstString = myCollection.iterator().next();
... ไม่ได้เตือนใด ๆ
มีความแตกต่างอย่างลึกซึ้งระหว่างสองเทคนิคนี้หรือไม่ที่ทำให้การสตรีมเข้าหา "อันตราย" มากกว่านี้ในบางด้านนั่นเป็นสิ่งสำคัญที่จะไม่ต้องโทรหารับ () โดยไม่ต้องเรียก isPresent () ก่อน Googling ไปรอบ ๆ ฉันพบบทความที่พูดถึงว่าโปรแกรมเมอร์ไม่ใส่ใจกับตัวเลือก <> และคิดว่าพวกเขาสามารถโทรหา get () ได้ทุกเมื่อ
สิ่งที่ฉันชอบที่จะได้รับข้อยกเว้นโยนฉันที่ใกล้ที่สุดกับสถานที่ที่รหัสของฉันเป็นรถซึ่งในกรณีนี้จะเป็นที่ที่ฉันโทรหารับ () เมื่อไม่มีองค์ประกอบที่จะพบ ฉันไม่ต้องการที่จะเขียนเรียงความไร้ประโยชน์เช่น:
Optional<String> firstStream = myCollection.stream()
.findFirst();
if (!firstStream.isPresent()) {
throw new IllegalStateException("There is no first string even though I totally expected there to be! <sarcasm>This exception is much more useful than NoSuchElementException</sarcasm>");
}
String theFirstString = firstStream.get();
... เว้นแต่จะมีอันตรายในการยั่วยุข้อยกเว้นจากการได้รับ () ที่ฉันไม่รู้?
หลังจากอ่านคำตอบจาก Karl Bielefeldt และความคิดเห็นจาก Hulk ฉันรู้รหัสข้อยกเว้นของฉันข้างต้นค่อนข้างงุ่มง่ามนี่คือสิ่งที่ดีกว่า:
String errorString = "There is no first string even though I totally expected there to be! <sarcasm>This exception is much more useful than NoSuchElementException</sarcasm>";
String firstString = myCollection.stream()
.findFirst()
.orElseThrow(() -> new IllegalStateException(errorString));
สิ่งนี้ดูมีประโยชน์มากขึ้นและอาจเป็นธรรมชาติในหลาย ๆ ที่ ฉันยังคงรู้สึกว่าฉันจะต้องการเลือกองค์ประกอบหนึ่งรายการจากรายการโดยไม่ต้องจัดการกับสิ่งเหล่านี้ทั้งหมด แต่นั่นอาจเป็นได้ว่าฉันต้องคุ้นเคยกับสิ่งก่อสร้างเหล่านี้