วิธีตรวจสอบว่าองค์ประกอบมีอยู่โดยใช้นิพจน์แลมบ์ดาหรือไม่?


118

โดยเฉพาะฉันมี TabPane และฉันต้องการทราบว่ามีองค์ประกอบที่มี ID เฉพาะอยู่หรือไม่

ดังนั้นฉันต้องการทำสิ่งนี้ด้วยแลมบ์ดานิพจน์ใน Java:

boolean idExists = false;
String idToCheck = "someId";

for (Tab t : tabPane.getTabs()){
    if(t.getId().equals(idToCheck)) {
        idExists = true;
    }
}

คำตอบ:


273

ลองใช้anyMatchLambda Expression เป็นแนวทางที่ดีกว่ามาก

 boolean idExists = tabPane.getTabs().stream()
            .anyMatch(t -> t.getId().equals(idToCheck));

11
ยังมีมูลค่า noting: ถ้าคุณต้องการที่จะลบล้างการใช้เช็คแทนnoneMatch anyMatch
Blacklight

การโทรต้องใช้ API ระดับ 24
FabioLux

50

ในขณะที่คำตอบที่ยอมรับนั้นถูกต้องฉันจะเพิ่มเวอร์ชันที่หรูหรากว่านี้ (ในความคิดของฉัน):

boolean idExists = tabPane.getTabs().stream()
    .map(Tab::getId)
    .anyMatch(idToCheck::equals);

อย่าละเลยการใช้Stream # map ()ซึ่งอนุญาตให้แบนโครงสร้างข้อมูลก่อนที่จะใช้ไฟล์Predicate.


3
ที่นี่มีอะไรดีกว่ากัน? ฉันเห็นการดำเนินการอีกเพียงครั้งเดียว ขอโทษที่ฉันเพิ่งเริ่มใช้ lamba สิ่งนี้
TecHunter

2
@TecHunter มันชัดเจนมากขึ้น สมมติว่าคุณอ่านรหัสนี้เป็นครั้งแรกหรืออีกครั้งหลังจากนั้นสักครู่ มีข้อดีหลายประการประการแรกเราแสดงให้เห็นทันทีว่าเราไม่ได้สนใจแท็บจริง แต่มีการทำแผนที่ ประการที่สองโดยใช้การอ้างอิงวิธีการ (ซึ่งเป็นไปได้เพียงเพราะเราแบ่งแลมบ์ดาเริ่มต้นออกเป็นสองขั้นตอน) เราแสดงให้เห็นว่าไม่มีเรื่องน่าประหลาดใจซ่อนอยู่ในโค้ด ประการที่สามโดยใช้การอ้างอิงวิธีการเราไม่ได้สร้างพรีดิเคตใหม่ แต่ใช้equalsซ้ำจริงๆ แม้ว่าจะได้รับตัวอย่างที่นี่ง่ายมาก แต่ฉันหวังว่าคุณจะเข้าใจในสิ่งที่ฉันหมายถึง
Malte Hartwig

@MalteHartwig ขอบคุณ! ใช่ฉันได้ 3 คะแนนของคุณ แต่ฉันกำลังถามเกี่ยวกับการแบนด้วยmapขั้นตอนการประมวลผลอื่นไม่ใช่หรือ ฉันจะลองเปรียบเทียบ 2 วิธี :)
TecHunter

1
@MalteHartwig ทดสอบใน ArrayList 10kk ด้วยวัตถุง่ายๆที่พยายามค้นหาองค์ประกอบสุดท้าย ให้ความแตกต่าง 2ms 131ms กับ 133ms สำหรับไฟล์. ในรายการอาร์เรย์ 1kk ของคุณหากเร็วขึ้น 2ms (55ms ถึง 53ms) ดังนั้นเราสามารถพูดได้ว่าของคุณดีกว่า :)
TecHunter

2
@TecHunter getters ถูกสุด ๆ มักจะชอบความชัดเจนของโค้ดมากกว่าการประหยัดเวลาเพิ่มอีก 2 มิลลิวินาที (แม้ว่าฉันจะสงสัยว่าผลลัพธ์จะถูกต้อง แต่ก็อาจผันผวนในทุก ๆ ครั้ง) นอกจากนี้จำไว้ว่าการดำเนินงานในระดับกลางลำธาร (เช่นmap) จะขี้เกียจโดยธรรมชาติ นั่นหมายความว่าgetIdวิธีการนั้นจะไม่ถูกนำไปใช้กับแต่ละองค์ประกอบของคอลเล็กชัน มันได้รับการประเมินอย่างเฉื่อยชาจนanyMatchผลตอบแทนที่แท้จริง
jFrenetic

3

คำตอบข้างต้นต้องการให้คุณ malloc วัตถุสตรีมใหม่

public <T>
boolean containsByLambda(Collection<? extends T> c, Predicate<? super T> p) {

    for (final T z : c) {
        if (p.test(z)) {
            return true;
        }
    }
    return false;
}

public boolean containsTabById(TabPane tabPane, String id) {
    return containsByLambda(tabPane.getTabs(), z -> z.getId().equals(id));
}
...
if (containsTabById(tabPane, idToCheck))) {
   ...
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.