วิธีที่ดีที่สุดในการสลับตัวแปรบูลีนใน Java?


211

มีวิธีที่ดีกว่าในการลบบูลีนใน Java มากกว่าวิธีง่าย ๆ ไหม?

if (theBoolean) {
    theBoolean = false;
} else {
    theBoolean = true;
}

โอ้ดีฉันกำลังจะถามคำถามเดียวกันถึงแม้ว่าคำถามของฉันจะเฉพาะเจาะจงกับ javascript / as3 หรือ ECMAScript โดยทั่วไปฉันคิดว่า ... ซึ่งจะครอบคลุมคำถามนี้ได้อย่างง่ายดาย
แมตต์ lohkamp

เกิดอะไรขึ้นถ้าไม่มี! ผู้ประกอบการ ??
onmyway133

คำตอบ:


537
theBoolean = !theBoolean;

16
นั่น ... ชัดเจนจริงๆ - อุ๊ปส์! ไม่รู้ทำไมฉันไม่คิด ขอบคุณ
Kevin Griffin

! บูลีนดูเหมือนจะเป็นทางเลือกที่เป็นธรรมชาติ - อาจเป็นในอนาคต
แมตต์ lohkamp

21
!!bool == !(!(bool)) == bool@ypnos:
Christoffer Hammarström

12
@ ChristofferHammarströmโดยตรรกะนั้นไม่ควร --integer == - (- (จำนวนเต็ม)) == จำนวนเต็ม?
user515655

1
@ user515655 - ภาษาจะกำหนด--โอเปอเรเตอร์ (อันที่จริงแล้วสองรายการพร้อมด้วย++โอเปอเรเตอร์สองรายการ) แต่ไม่ได้กำหนด!!โอเปอเรเตอร์ ถ้าคุณต้องการ-(-(integer))คุณสามารถใช้ช่องว่างระหว่าง-ตัวละครทั้งสอง แต่!!แยกวิเคราะห์เป็น!ตัวดำเนินการสองตัวโดยไม่คำนึงถึงพื้นที่สีขาว
Ted Hopp

164
theBoolean ^= true;

กดแป้นน้อยลงหากตัวแปรของคุณยาวเกินสี่ตัวอักษร

แก้ไข : รหัสมีแนวโน้มที่จะส่งคืนผลลัพธ์ที่เป็นประโยชน์เมื่อใช้เป็นคำค้นหาของ Google รหัสข้างต้นไม่ได้ สำหรับผู้ที่ต้องการมันก็XOR บิตเป็นอธิบายไว้ที่นี่


14
และมันก็เป็นไปตาม DRY :)
Tetha

6
ความกะทัดรัดเป็นจิตวิญญาณแห่งปัญญา
Paul Brinkley

7
ตอนนี้ฉันไปที่ชื่อ - ปล่อย (syntax-drop?) XOR เพื่อดูเท่ห์ต่อหน้าเพื่อนโปรแกรมเมอร์ของฉัน คำตอบของคุณควรจะถูกรวมเข้ากับคำตอบที่เลือกไว้ด้วยกันซึ่งเป็นความสมบูรณ์แบบอย่างแท้จริง
แมตต์ lohkamp

6
@ScottStanchfield คนแบบนี้ควรเรียนรู้ มันไม่ยากเลยไม่มีแฮ็คและไม่รู้ว่ามันมักจะนำไปสู่การเส็งเคร็งรหัสเช่นหนึ่งคำถามนี้ นี่คือการระเบิดที่แท้จริง - ห้าบรรทัดโดยใช้แบบแผนมาตรฐาน!
maaartinus

4
การดำเนินการนี้เร็วกว่ารุ่นอื่น ๆ12%เช่นtheBoolean = !theBoolean;หรือtheBoolean = theBoolean ? false : true;
Blaine Kasten

32

มีหลายแบบด้วยกัน

วิธี "ชัดเจน" (สำหรับคนส่วนใหญ่)

theBoolean = !theBoolean;

วิธี "สั้นที่สุด" (เกือบตลอดเวลา)

theBoolean ^= true;

วิธีที่ "มองเห็นได้มากที่สุด" (ไม่แน่นอนที่สุด)

theBoolean = theBoolean ? false : true;

พิเศษ: สลับและใช้ในการเรียกเมธอด

theMethod( theBoolean ^= true );

เนื่องจากตัวดำเนินการกำหนดส่งคืนสิ่งที่ได้รับมอบหมายเสมอสิ่งนี้จะสลับค่าผ่านตัวดำเนินการระดับบิตแล้วส่งคืนค่าที่กำหนดใหม่ที่จะใช้ในการเรียกใช้เมธอด


ล้อมรอบการนำไปใช้ในฟังก์ชัน / เมธอดที่เรียกว่า toggle แล้วแทบจะไม่มีทางสับสน
Lambage

@ Reiner: Cแน่นอน แต่ในJavaมันไม่ได้รับอนุญาตให้ผสมบูลีนและจำนวนเต็ม (เช่นสิ่งที่while(1)เป็นไปไม่ได้ใน Java)
Levite

@Lambage: จริง แต่ข้อเสียคุณไม่สามารถสลับบูลีนโดยเพียงแค่ผ่านมันเพราะมันเป็นไปไม่ได้ที่จะผ่านดั้งเดิมโดยอ้างอิงใน Java คุณจะต้องกำหนดผลลัพธ์ของเมธอดให้กับตัวแปรของคุณหรือสร้างคลาส wrapper สำหรับบูลีน
Levite

"วิธีที่ชัดเจน" ด้านบนรับการตั้งค่าสถานะโดย SONAR ด้วย - ควรหลีกเลี่ยงการมอบหมายภายใน
Orby

2

หากคุณใช้ค่าบูลีน NULL และพิจารณาว่าเป็นเท็จลองสิ่งนี้:

static public boolean toggle(Boolean aBoolean) {
    if (aBoolean == null) return true;
    else return !aBoolean;
}

หากคุณไม่ได้ส่งค่า NULL ของบูลีนลองสิ่งนี้:

static public boolean toggle(boolean aBoolean) {
   return !aBoolean;
}

สิ่งเหล่านี้สะอาดที่สุดเพราะพวกเขาแสดงเจตนาในลายเซ็นวิธีการนั้นง่ายต่อการอ่านเปรียบเทียบกับ! ตัวดำเนินการและสามารถดีบั๊กได้ง่าย

การใช้

boolean bTrue = true
boolean bFalse = false
boolean bNull = null

toggle(bTrue) // == false
toggle(bFalse) // == true
toggle(bNull) // == true

แน่นอนถ้าคุณใช้Groovyหรือภาษาที่อนุญาตวิธีการส่วนขยายคุณสามารถลงทะเบียนส่วนขยายและทำง่ายๆ

Boolean b = false
b = b.toggle() // == true

วิธีการที่ดี แต่ไม่โปร่งใสทั้งหมด (imho) สำหรับคนที่ใช้ / อ่านเพียงแค่ "toggle (.. )" อาจคิดว่าการเรียกใช้เมธอด (โดยไม่ต้องกำหนดให้กับตัวแปรอีกครั้ง) อาจสลับตัวแปรพื้นฐานแล้ว เห็นได้ชัดว่าตอนนี้เราเห็นรหัสแล้ว แต่ในชีวิตจริงอาจจะยากที่จะแก้ไขข้อบกพร่อง ชื่อวิธีที่ดีกว่าอาจเป็น "ตรงกันข้าม" หรืออาจเป็น "การปฏิเสธ" เพื่อทำให้สิ่งนี้ชัดเจนยิ่งขึ้น หรือใช้วิธีแรกกับวัตถุBooleanและสลับมันจริงๆภายในวิธีการ (แต่ยังค่อนข้างคลุมเครือ)
Levite

2

คำตอบนี้เกิดขึ้นเมื่อค้นหา "ฟังก์ชั่น java invert boolean" ตัวอย่างด้านล่างจะป้องกันเครื่องมือการวิเคราะห์แบบสแตติกบางอย่างจากความล้มเหลวในการสร้างเนื่องจากตรรกะการแตกแขนง สิ่งนี้มีประโยชน์หากคุณต้องการสลับบูลีนและยังไม่ได้สร้างการทดสอบหน่วยที่ครอบคลุม;)

Boolean.valueOf(aBool).equals(false)

หรืออีกทางหนึ่ง:

Boolean.FALSE.equals(aBool)

หรือ

Boolean.FALSE::equals

1
ฉันชอบความจริงที่ว่าคุณสามารถส่งผ่านBoolean.FALSE::equalsไปยังฟังก์ชั่นการทำแผนที่แทนการเขียนแลมบ์ดาเล็กน้อย
Patrick Parker

0

หากคุณไม่ได้ทำสิ่งใดโดยเฉพาะมืออาชีพคุณสามารถใช้คลาส Util ได้ตลอดเวลา ตัวอย่างคลาส util จากโครงงานสำหรับคลาส

public class Util {


public Util() {}
public boolean flip(boolean bool) { return !bool; }
public void sop(String str) { System.out.println(str); }

}

จากนั้นเพียงแค่สร้างวัตถุ Util Util u = new Util(); และมีบางสิ่งบางอย่างสำหรับการส่งคืนSystem.out.println( u.flip(bool) );

หากคุณกำลังจะจบลงด้วยการใช้สิ่งเดียวกันซ้ำไปซ้ำมาใช้วิธีการและโดยเฉพาะอย่างยิ่งถ้ามันข้ามโครงการทำคลาส Util Dunno มาตรฐานอุตสาหกรรมเป็นอย่างไร (โปรแกรมเมอร์ที่มีประสบการณ์รู้สึกฟรีเพื่อแก้ไขฉัน)



-4

ก่อน:

boolean result = isresult();
if (result) {
    result = false;
} else {
    result = true;
}

หลังจาก:

boolean result = isresult();
result ^= true;

ใครลงคะแนนบ้าง คุณช่วยอธิบายเหตุผลด้วยได้มั้ย
Nikhil Kumar

11
สองเหตุผลหลักที่ฉันคิดได้ว่าทำไมใครบางคนถึงอาจทำให้คุณผิดหวัง: 1) การเย้ยหยัน ( มา! คำถามที่ถามมา 7 (!) ปีที่แล้ว! ) และคำตอบของคุณไม่ได้นำสิ่งใหม่มาสู่ตาราง 2) ผู้มีสิทธิเลือกตั้งคาดหวังสิ่งที่ "สะอาด" ( อ่าน: สั้นกว่า ) - คำตอบของ AaronMaenpaa เป็นตัวอย่างที่ดีของเรื่องนี้
Priidu Neemre

5
@Elltz: ในทางตรงกันข้าม - ฉันได้ upvoting เขาจริง ๆ เนื่องจากการตอบถูกต้องในทางเทคนิค อย่างไรก็ตามฉันต้องบอกว่าฉันไม่ชอบแนวโน้มของการลักลอบส่งข้อความตอบกลับของผู้ใช้ก่อนหน้านี้สำหรับกรรมถูก (ดูคำตอบของ nlaq)
Priidu Neemre

@PriiduNeemre คำถามที่ถามและคำตอบที่ยอมรับก่อน 7 ปีขึ้นไป & คุณคิดว่ายกเว้นใครในรายการของคุณใครจะยอมแพ้? นอกเหนือจากนี้คำตอบของคุณยังไม่เกินเครื่องหมาย .. :(
user1140237

2
หลังจาก: บูลีนผล =! isresult ();
Petter Friberg
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.