การสร้างโอเปอเรเตอร์“ ตรรกะพิเศษหรือ” ใน Java


274

ข้อสังเกต:

Java มีตัวดำเนินการตรรกะและ AND
Java มีตัวดำเนินการ OR เชิงตรรกะ
Java มีตัวดำเนินการ NOT แบบโลจิคัล

ปัญหา:

Java ยังไม่มีผู้ประกอบการ XOR ตรรกะตามดวงอาทิตย์ ฉันต้องการนิยาม

นิยามวิธีการ:

เป็นวิธีที่มันถูกกำหนดไว้ดังนี้:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}


วิธีการโทร:

วิธีนี้ถูกเรียกด้วยวิธีดังต่อไปนี้:

boolean myVal = logicalXOR(x, y);


การใช้งานผู้ประกอบการ:

ฉันอยากจะมีโอเปอเรเตอร์มากกว่าใช้ดังนี้:

boolean myVal = x ^^ y;


คำถาม:

ฉันหาอะไรไม่ได้เกี่ยวกับการกำหนดโอเปอเรเตอร์ใหม่ใน Java ฉันจะเริ่มได้ที่ไหน


1
อะไร? ลิงค์ที่คุณให้มีเนื้อหา 'bitwise exclusive OR'
Mathew P. Jones

คุณสงสัยไหมว่าถ้าคุณสามารถกำหนดโอเปอเรเตอร์ใน Java อย่างที่คุณสามารถทำได้ใน C ++?
avgvstvs

1
ดูเหมือนว่าคุณเข้าใจผิดความแตกต่างระหว่าง & และ && ทั้งคู่เป็นตัวดำเนินการเชิงตรรกะ (บนบูลีน) คำตอบของ Starblue ครอบคลุมมันอย่างกว้างขวางมากขึ้น
Vlasec

เพียงเพราะมันไม่ได้อยู่ในการกวดวิชาไม่ได้หมายความว่า Java ไม่ได้มี - บทเรียนไม่สมบูรณ์ (เสมอ) ดูข้อกำหนดภาษา Java 15.22.2
85421

5
มันถูกเรียกว่า!=นอกจากนี้ยังมี XNOR แบบลอจิคัลที่เรียกว่า==
Mark K Cowan

คำตอบ:


695

Java มีตัวดำเนินการ XOR แบบลอจิคัลซึ่งเป็น^ (เหมือนในa ^ b )

นอกเหนือจากนั้นคุณไม่สามารถกำหนดโอเปอเรเตอร์ใหม่ใน Java ได้

แก้ไข:นี่คือตัวอย่าง:

public static void main(String[] args) {
    boolean[] all = { false, true };
    for (boolean a : all) {
        for (boolean b: all) {
            boolean c = a ^ b;
            System.out.println(a + " ^ " + b + " = " + c);
        }
    }
}

เอาท์พุท:

false ^ false = false
false ^ true = true
จริง ^ false = จริง
true ^ true = false

5
สิ่งนี้ทำให้ฉันจำหน่วยความจำของฉันได้เช่นกันเมื่อฉันเขียนโพสต์ แต่ฉันคิดว่าคุณสามารถใช้ ^ เป็นตัวดำเนินการเชิงตรรกะ (เช่นเดียวกับบิต)
Neil Coffey

144
^ ไม่เพียงเป็นผู้ประกอบการระดับบิต มันยังเป็นตัวดำเนินการเชิงตรรกะ ตัวดำเนินการ ^ ถูกโหลดมากเกินไป มันทำงานกับประเภทหนึ่งหรือประเภทบูลีน +1 สำหรับคำตอบที่ดี javashlook เอ็ดดี้มันไม่ได้ชัดเจนกว่า JLS มาตรา 15.22.2, "Boolean Logical Operators &, ^ และ |"
erickson

97
และแน่นอนคำตอบคือ && และ || จะข้ามการประเมินส่วนที่ 2 ของนิพจน์และ & และ | จะประเมินทั้งสองส่วนของนิพจน์เสมอ (จากการอ่าน JLS ของฉัน) A ^^ จะต้องประเมินทั้งสองส่วนตามคำนิยามเสมอดังนั้นจึงมีพฤติกรรมเหมือนกันกับ ^ อาจเป็นเหตุผลที่ไม่มี ^^
เอ็ดดี้

81
@Eddie: นั่นและ ^^ ดูเหมือนอิโมติคอนมากเกินไป
Michael Myers

5
บางทีมันอาจเป็นเรื่องของความหมาย แต่เมื่อพูดถึง XOR ค่าบิตและตรรกะจะให้ผลลัพธ์เหมือนกัน ดังนั้นไม่จำเป็นต้องใช้ตัวดำเนินการที่แตกต่างกัน ตารางความจริงแบบง่ายสำหรับผู้ดำเนินการ XOR คือ X ^! X = 1 คุณไม่สามารถลัดวงจรอินพุตใน XOR เพราะคุณต้องพิจารณาว่าอินพุตนั้นแตกต่างกันหรือไม่ มันง่ายกว่าที่จะเข้าใจถ้าคุณรู้การสร้างประตู XOR จริง
hfontanez

305

มันไม่ใช่ x! = y?


5
ถ้า x และ y เป็นบูลีนตารางตรรกะสำหรับ xor และ! = เหมือนกัน: t, t => f; t, f => t; f, t => t; f, f => f
Greg Case

81
Maurice: จัดการกับคุณแค่ทำให้ใจฉัน! ฉันไม่เคยสังเกตสิ่งนี้ได้อย่างไร

8
@Milhous คุณพูดa != b != cไม่ทำงาน แต่a ^ b ^ cจะ? ในกรณีที่คุณจะผิด
fredoverflow

3
มอริสยอดเยี่ยมมาก! มันเกิดขึ้นกับฉันในการสูญเสียสิ่งต่าง ๆ จากการมองเห็นเมื่อมีสิ่งที่ต้องทำมากมาย :)
sberezin

6
approch นี้ implodes เมื่อทั้งสองฝ่ายมีการเรียนการห่อให้new Boolean(true) != new Boolean(true) true
Vlastimil Ovčáčík

74

Java มีตัวดำเนินการตรรกะและ AND
Java มีตัวดำเนินการ OR เชิงตรรกะ

ไม่ถูกต้อง.

Java ได้

  • ตรรกะและตัวดำเนินการสองตัว: ปกติและคือ & และลัดวงจรและคือ &&, และ
  • ตัวดำเนินการตรรกะสองตัวหรือ OR: ปกติ OR คือ | และลัดวงจรหรือคือ ||

XOR มีเพียงเป็น ^ เท่านั้นเนื่องจากไม่สามารถประเมินการลัดวงจรได้


2
ความคิดเห็นที่น่าสนใจ มีการบันทึกไว้หรือไม่
user666412

1
ฉันคิดว่า & และ | ไม่ใช่การลัดวงจรเนื่องจากเป็นตัวดำเนินการระดับบิต และในความเป็นจริงมันเป็นไปไม่ได้ที่จะลัดวงจรพวกเขา
Krzysztof Jabłoński

3
@Krzysztof Jabłońskiพวกเขาเป็นผู้ประกอบการระดับบิตในตัวเลข แต่ที่นี่เรากำลังพูดถึงการแสดงออกแบบบูล
starblue

3
@ user666412 ใช่ในข้อกำหนดภาษา Java (ที่อื่น?)
starblue

18
หากมีตัวดำเนินการ 2 AND และตัวดำเนินการ 2 OR ข้อความสั่ง 'Java มีตัวดำเนินการ AND และ' และ 'Java มีตัวดำเนินการตรรกะหรือ OR' ไม่ผิด ตามคำนิยามถ้าคุณมี 2 อย่างแล้วคุณก็มี 1 อย่าง
RyanfaeScotland

31

บางทีคุณอาจจะเข้าใจผิดความแตกต่างระหว่าง&และ&&, |และ|| วัตถุประสงค์ของผู้ประกอบการทางลัด&&และ||เป็นว่าค่าของตัวถูกดำเนินการครั้งแรกที่สามารถตรวจสอบผลและเพื่อให้ตัวถูกดำเนินการที่สองไม่ต้องมีการประเมิน

สิ่งนี้มีประโยชน์อย่างยิ่งหากตัวถูกดำเนินการตัวที่สองส่งผลให้เกิดข้อผิดพลาด เช่น

if (set == null || set.isEmpty())
// or
if (list != null && list.size() > 0)

อย่างไรก็ตามกับแฮคเกอร์ที่คุณมักจะมีการประเมินผลการดำเนินที่สองที่จะได้รับผลเพื่อให้การดำเนินการเพียง ^แต่มีความหมายคือ


20

คุณสามารถเขียนได้ (a!=b)

a ^ bนี้จะทำงานเช่นเดียวกับวิธีที่เป็น


9

นั่นเป็นเพราะผู้ปฏิบัติงานเกินกำลังเป็นสิ่งที่พวกเขาออกจากภาษาโดยเฉพาะอย่างจงใจ พวกเขา "โกง" เล็กน้อยด้วยการเรียงสตริง แต่ยิ่งไปกว่านั้นฟังก์ชั่นดังกล่าวไม่มีอยู่จริง

(ข้อจำกัดความรับผิดชอบ: ฉันไม่ได้ทำงานร่วมกับจาวารุ่นใหญ่ 2 ตัวล่าสุดดังนั้นหากในตอนนี้ฉันจะแปลกใจมาก)


5
โปรดจำไว้ว่าคุณไม่สามารถกำหนดตัวดำเนินการใหม่ใน C ++ ได้เช่นกัน สิ่งที่คุณทำได้คือให้ความหมายใหม่กับสิ่งเก่า ๆ
David Thornley

7

โอเปอเรเตอร์ที่โอเวอร์โหลดใน Java เท่านั้นคือ + on Strings ( JLS 15.18.1 String Concatenation Operator + )

ชุมชนถูกแบ่งเป็น 3 ปีเป็น 1/3 ไม่ต้องการ 1/3 ต้องการและ 1/3 ไม่สนใจ

คุณสามารถใช้ Unicode เพื่อสร้างชื่อเมธอดที่เป็นสัญลักษณ์ ... ดังนั้นหากคุณมีสัญลักษณ์ที่คุณต้องการใช้คุณสามารถทำได้ myVal = x. $ (y); โดยที่ $ คือสัญลักษณ์และ x ไม่ใช่ดึกดำบรรพ์ ... แต่นั่นจะเป็นสิ่งที่หลีกเลี่ยงในบรรณาธิการบางคนและมีข้อ จำกัด เนื่องจากคุณไม่สามารถทำได้บนดั่งเดิม


7

รหัสของคุณดังต่อไปนี้:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}

ฟุ่มเฟือย

ทำไมไม่เขียน:

public static boolean logicalXOR(boolean x, boolean y) {
    return x != y;
}

?

ตามที่ javashlook กล่าวว่ามี^ผู้ให้บริการอยู่แล้ว

!=และ^ทำงานเหมือนกัน * สำหรับตัวถูกดำเนินการบูลีน (กรณีของคุณ) แต่แตกต่างกันสำหรับตัวถูกดำเนินการจำนวนเต็ม

* หมายเหตุ:
1. มันทำงานเหมือนกันสำหรับตัวดำเนินการboolean(ดึกดำบรรพ์) แต่ไม่ใช่Boolean(ตัวประมวลผลชนิดวัตถุ) ค่าBoolean(ประเภทวัตถุ) สามารถมีค่าnullได้ และ!=จะส่งคืนfalseหรือtrueเมื่อหนึ่งหรือทั้งสองตัวถูกดำเนินการnullในขณะที่^จะโยนNullPointerExceptionในกรณีนี้
2. แม้ว่ามันจะทำงานเหมือนกัน แต่ก็มีความสำคัญต่างกันเช่นเมื่อใช้กับ&: a & b != c & dจะถือว่าเป็นa & (b != c) & dในขณะที่a & b ^ c & dจะถือว่าเป็น(a & b) ^ (c & d)(offtopic: ouch, ตารางลำดับความสำคัญแบบ C)


1
สำหรับค่าบูลีนที่ฉันชอบ!=
GKalnytskyi

1
@GKalnytskyi สำหรับBooleanค่า!=ทำงานไม่ถูกต้อง สำหรับbooleanค่ามันก็โอเค
vadipp

2
! = และ ^ ไม่ทำงานเหมือนกันสำหรับตัวถูกดำเนินการบูลีน คุณจะได้รับผลลัพธ์ที่แตกต่างกันสำหรับ "false & false! = true" กับ "false & false ^ true" เนื่องจากลำดับความสำคัญ
Albert Hendriks

1
@ AlbertHendriks ฉันควรจะบอกว่าพวกเขาทำงานเหมือนกัน แต่มีความสำคัญที่แตกต่างกัน(แม้ว่ามันจะเป็นเพียงเรื่องของคำศัพท์)
Sasha

6

นี่คือวิธี var arg XOR สำหรับ java ...

public static boolean XOR(boolean... args) {
  boolean r = false;
  for (boolean b : args) {
    r = r ^ b;
  }
  return r;
}

สนุก


นี่รู้สึกเหมือนว่ามันจะมีพฤติกรรมแปลก ๆ เช่นผลตอบแทนจริงซึ่งดูเหมือนจะไม่ชอบสิ่งที่คุณคาดหวังจากวิธีการที่เรียกว่าXOR(true,true,true) XORพฤติกรรมที่คาดหวังของฉันคือจะให้ผลตอบแทนที่ผิดเสมอ (ซึ่งแน่นอนว่าไม่มีประโยชน์)
Richard Tingle

4

!=แต่เพียงผู้เดียวหรือตรรกะในชวาเรียกว่า คุณสามารถใช้^หากคุณต้องการทำให้เพื่อนสับสน


2

คุณสามารถใช้Xtend (Infix Operators และ Operator Overloading)เพื่อทำ overload operator และ 'stay' บน Java


โปรดทราบว่า Xtend ไม่อนุญาตให้คุณแทนที่เครื่องหมายรูปหมวก^; bool_1.xor(bool_2)คุณต้องใช้ ตัวแยกวิเคราะห์ไม่ได้อนุญาตให้คุณใช้เครื่องหมายรูปหมวกด้วยซ้ำ คุณต้องใช้xorสำหรับบูลีนและbitwiseXorสำหรับจำนวนเต็ม แน่นอนคุณสามารถโอเวอร์โหลดโอเปอเรเตอร์อื่นได้ แต่นั่นอาจทำให้สับสนมาก
เคลวิน

2

สิ่งที่คุณถามจะไม่สมเหตุสมผล นอกจากว่าฉันผิดคุณแนะนำให้คุณใช้ XOR เพื่อดำเนินการทางตรรกะเช่นเดียวกับ AND และ OR รหัสที่คุณให้มาแสดงสิ่งที่ฉันขอให้:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}

ฟังก์ชั่นของคุณมีอินพุตบูลีนและเมื่อใช้ค่าบิต XOR บนบูลีนผลลัพธ์จะเหมือนกับรหัสที่คุณให้ กล่าวอีกนัยหนึ่ง Bitwise XOR นั้นมีประสิทธิภาพอยู่แล้วเมื่อทำการเปรียบเทียบแต่ละบิต (booleans) หรือเปรียบเทียบแต่ละบิตในค่าที่มากขึ้น เมื่อต้องการใส่สิ่งนี้ลงในบริบทในแง่ของค่าไบนารีค่าที่ไม่เป็นศูนย์ใด ๆ คือ TRUE และ ZERO เท่านั้นที่เป็นเท็จ

ดังนั้นสำหรับ XOR ที่จะใช้วิธีเดียวกับ Logical AND คุณจะใช้เฉพาะค่าไบนารีที่มีเพียงหนึ่งบิต (ให้ผลและประสิทธิภาพเดียวกัน) หรือค่าไบนารีจะต้องถูกประเมินโดยรวมแทนที่จะเป็นบิต กล่าวอีกนัยหนึ่งนิพจน์ (010 ^^ 110) = FALSE แทน (010 ^^ 110) = 100 สิ่งนี้จะลบความหมายเชิงความหมายส่วนใหญ่ออกจากการดำเนินการและแสดงถึงการทดสอบเชิงตรรกะที่คุณไม่ควรใช้


1

A และ B จะต้องเป็นค่าบูลีนที่จะทำให้! = เหมือนกับ xor เพื่อให้ตารางความจริงดูเหมือนกัน คุณสามารถใช้! (A == B) lol


1

ฉันใช้คลาส "org.apache.commons.lang.BooleanUtils" ที่เป็นที่นิยมมาก

วิธีนี้ได้รับการทดสอบโดยผู้ใช้จำนวนมากและปลอดภัย มีความสุข. การใช้งาน:

boolean result =BooleanUtils.xor(new boolean[]{true,false});

0

เนื่องจากประเภทข้อมูลบูลีนถูกเก็บไว้เช่นจำนวนเต็มฟังก์ชันบิตตัวดำเนินการ ^ เช่นการดำเนินการ XOR หากใช้กับค่าบูลีน

//©Mfpl - XOR_Test.java

    public class XOR_Test {
        public static void main (String args[]) {
            boolean a,b;

            a=false; b=false;
            System.out.println("a=false; b=false;  ->  " + (a^b));

            a=false; b=true;
            System.out.println("a=false; b=true;  ->  " + (a^b));

            a=true;  b=false;
            System.out.println("a=true;  b=false;  ->  " + (a^b));

            a=true; b=true;
            System.out.println("a=true; b=true;  ->  " + (a^b));

            /*  output of this program:
                    a=false; b=false;  ->  false
                    a=false; b=true;  ->  true
                    a=true;  b=false;  ->  true
                    a=true; b=true;  ->  false
            */
        }
    }

0

นี่คือตัวอย่าง:

รับค่า int 2 ค่าส่งคืนจริงถ้ามีค่าเป็นลบและอีกค่าหนึ่งเป็นค่าบวก ยกเว้นถ้าพารามิเตอร์ "ลบ" เป็นจริงจากนั้นส่งคืนจริงเฉพาะในกรณีที่ทั้งสองเป็นลบ

    public boolean posNeg(int a, int b, boolean negative) {
      if(!negative){
        return (a>0 && b<0)^(b>0 && a<0);
      }
      else return (a<0 && b<0);
    }

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