Membuat operator "logis eksklusif atau" di Jawa

274

Pengamatan:

Java memiliki operator AND yang logis.
Java memiliki operator ATAU logis.
Java memiliki operator NOT logis.

Masalah:

Java tidak memiliki operator XOR yang logis, menurut sun . Saya ingin mendefinisikan satu.

Definisi metode:

Sebagai metode, ia didefinisikan sebagai berikut:

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


Panggilan metode:

Metode ini disebut dengan cara berikut:

boolean myVal = logicalXOR(x, y);


Penggunaan Operator:

Saya lebih suka memiliki operator, digunakan sebagai berikut:

boolean myVal = x ^^ y;


Pertanyaan:

Saya tidak dapat menemukan apa pun tentang cara mendefinisikan operator baru di Jawa. Di mana saya harus mulai?

sebelas81
sumber
1
apa? tautan yang Anda berikan memiliki konten 'bitwise eksklusif OR'
Mathew P. Jones
apakah Anda bertanya-tanya apakah Anda dapat mendefinisikan operator di Jawa seperti yang Anda bisa di C ++?
avgvstvs
1
Tampaknya Anda salah memahami perbedaan antara & dan &&. Keduanya adalah operator logis (pada boolean). Jawaban Starblue mencakupnya lebih luas.
Vlasec
hanya karena tidak ada dalam tutorial , tidak berarti bahwa Java tidak memilikinya - tutorial tidak selalu lengkap. Lihat Spesifikasi Bahasa Jawa 15.22.2
user85421
5
Disebut !=, ada juga XNOR logis yang disebut==
Mark K Cowan

Jawaban:

695

Java memang memiliki operator XOR logis , itu adalah ^ (seperti dalam a ^ b).

Selain itu, Anda tidak dapat menentukan operator baru di Jawa.

Sunting: Ini contohnya:

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);
        }
    }
}

Keluaran:

false ^ false = salah
false ^ true = benar
true ^ false = benar
true ^ true = salah
javashlook
sumber
5
Ini luput dari ingatan saya juga ketika saya menulis posting saya, tapi saya pikir Anda BISA menggunakan ^ sebagai operator logis (dan juga bitwise).
Neil Coffey
144
^ bukan hanya operator bitwise. Ini juga merupakan operator yang logis. Operator ^ kelebihan beban. Ini beroperasi pada tipe integral atau tipe boolean. +1 untuk jawaban javashlook yang bagus. Eddie, itu tidak menjadi lebih eksplisit daripada JLS Bagian 15.22.2, "Boolean Logical Operators &, ^, and |".
erickson
97
Dan tentu saja, jawabannya adalah bahwa && dan || akan melewatkan evaluasi bagian ke-2 dari ekspresi dan & dan | akan selalu mengevaluasi kedua bagian ekspresi (dari baca JLS saya). A ^^ harus selalu mengevaluasi kedua bagian, menurut definisi, jadi berperilaku identik dengan ^. Mungkin mengapa tidak ada ^^
Eddie
81
@ Eddie: Itu dan ^^ terlihat terlalu mirip emoticon.
Michael Myers
5
Mungkin ini masalah semantik, tetapi ketika menyangkut XOR, bitwise dan logis menghasilkan hasil yang sama. Karena itu, tidak perlu untuk operator yang berbeda. Tabel kebenaran yang disederhanakan untuk operator XOR adalah X ^! X = 1. Anda tidak dapat membuat arus pendek input di XOR karena Anda harus menentukan apakah inputnya berbeda. Jauh lebih mudah untuk dipahami jika Anda tahu pembuatan gerbang XOR yang sebenarnya.
hfontanez
305

Bukankah x! = Y?

Maurice Perry
sumber
5
Jika x dan y adalah boolean, maka tabel logika untuk xor dan! = Identik: t, t => f; t, f => t; f, t => t; f, f => f
Greg Case
81
Maurice: Arrgh, kau baru saja menghancurkan pikiranku! Bagaimana saya tidak pernah memperhatikan ini?
8
@ Milhous Maksudmu a != b != ctidak akan berhasil, tetapi a ^ b ^ cakankah? Kalau begitu, Anda salah .
fredoverflow
3
Maurice, sangat brilian! Kebetulan saya kehilangan hal-hal sederhana dari pandangan ketika ada banyak yang harus dilakukan :)
sberezin
6
Approch ini meledak ketika kedua sisi adalah kelas wrapper, new Boolean(true) != new Boolean(true)memberi true.
Vlastimil Ovčáčík
74

Java memiliki operator AND yang logis.
Java memiliki operator ATAU logis.

Salah.

Jawa memiliki

  • dua operator AND logis: AND normal adalah & dan hubung singkat AND adalah&&, dan
  • dua operator OR logis: OR normal adalah | dan hubungan arus pendek OR adalah ||.

XOR hanya ada sebagai ^, karena evaluasi hubungan pendek tidak dimungkinkan.

starblue
sumber
2
Komentar yang menarik Apakah itu didokumentasikan?
user666412
1
Saya pikir & dan | bukan hubungan arus pendek karena mereka adalah operator bitwise. Dan nyatanya tidak memungkinkan untuk melakukan hubungan pendek dengan mereka.
Krzysztof Jabłoński
3
@ Krzysztof Jabłoński Mereka adalah operator bitwise pada angka, tetapi di sini kita berbicara tentang ekspresi boolean.
starblue
3
@ user666412 Ya, dalam Spesifikasi Bahasa Jawa (di mana lagi?).
starblue
18
Jika memiliki 2 operator AND dan 2 OR operator maka pernyataan 'Java memiliki logika AND operator' dan 'Java memiliki operator OR logis' tidak salah. Menurut definisi jika Anda memiliki 2 sesuatu maka Anda juga memiliki 1 darinya.
RyanfaeScotland
31

Mungkin Anda salah memahami perbedaan antara &dan &&, |dan || Tujuan dari operator pintas &&dan|| adalah bahwa nilai operan pertama dapat menentukan hasil dan sehingga operan kedua tidak perlu dievaluasi.

Ini sangat berguna jika operan kedua akan menghasilkan kesalahan. misalnya

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

Namun dengan XOR , Anda selalu harus mengevaluasi operan kedua untuk mendapatkan hasil sehingga satu-satunya operasi yang berarti adalah ^.

Peter Lawrey
sumber
20

Anda bisa menulis (a!=b)

Ini akan bekerja sama seperti cara a ^ b.

Shuliyey
sumber
9

Itu karena operator kelebihan beban adalah sesuatu yang secara khusus mereka tinggalkan dari bahasa. Mereka "menipu" sedikit dengan penggabungan string, tetapi lebih dari itu, fungsi seperti itu tidak ada.

(Penafian: Saya belum bekerja dengan 2 rilis utama terakhir java, jadi jika sekarang, saya akan sangat terkejut)

Kevin Anderson
sumber
5
Ingatlah bahwa Anda tidak dapat mendefinisikan operator baru dalam C ++ juga. Yang bisa Anda lakukan adalah memberi makna baru kepada yang lama.
David Thornley
7

Satu-satunya operator kelebihan beban di Jawa adalah + on Strings ( JLS 15.18.1 String Concatenation Operator + ).

Komunitas telah dibagi menjadi 3 selama bertahun-tahun, 1/3 tidak menginginkannya, 1/3 menginginkannya, dan 1/3 tidak peduli.

Anda dapat menggunakan unicode untuk membuat nama metode yang merupakan simbol ... jadi jika Anda memiliki simbol yang ingin Anda gunakan, Anda dapat melakukan myVal = x. $ (Y); di mana $ adalah simbol dan x bukan primitif ... tapi itu akan menjadi cerdik di beberapa editor dan membatasi karena Anda tidak dapat melakukannya pada primitif.

TofuBeer
sumber
7

Berikut kode Anda:

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

berlebihan.

Mengapa tidak menulis:

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

?

Juga, seperti kata javashlook , sudah ada^ operator.

!=dan ^bekerja secara identik * untuk operan boolean (kasing Anda), tetapi berbeda untuk operan bilangan bulat.

* Catatan:
1. Mereka bekerja secara identik untuk boolean(tipe primitif), tetapi tidak untuk Boolean(tipe objek) operan. Sebagai Boolean(tipe objek) nilai dapat memiliki nilai null. Dan !=akan kembali falseatau trueketika salah satu atau kedua operannya null, sementara ^akan melempar NullPointerExceptiondalam kasus ini.
2. Meskipun mereka bekerja secara identik, mereka memiliki prioritas yang berbeda, misalnya ketika digunakan dengan &: a & b != c & dakan diperlakukan sebagai a & (b != c) & d, sementara a & b ^ c & dakan diperlakukan sebagai (a & b) ^ (c & d)(offtopic: aduh, tabel presedensi gaya-C menyebalkan).

Sasha
sumber
1
Untuk nilai Boolean yang saya suka!=
GKalnytskyi
1
@GKalnytskyi untuk Booleannilai !=berfungsi dengan tidak benar. Untuk booleannilai tidak masalah.
vadipp
2
! = dan ^ tidak bekerja secara identik untuk operan boolean. Anda akan mendapatkan hasil yang berbeda untuk "false & false! = True" versus "false & false ^ true" karena diutamakan.
Albert Hendriks
1
@AlbertHendriks, saya lebih baik mengatakan bahwa mereka bekerja secara identik, tetapi memiliki prioritas yang berbeda (meskipun itu hanya masalah terminologi).
Sasha
6

Berikut adalah metode vor arg XOR untuk java ...

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

Nikmati

Timothy Jacobsen
sumber
Ini terasa seperti akan memiliki perilaku yang sangat aneh. Misalkan XOR(true,true,true)mengembalikan true, yang sepertinya tidak seperti apa yang Anda harapkan dari metode yang disebut XOR. Tingkah laku saya yang diharapkan adalah bahwa itu selalu mengembalikan false (yang tentu saja tidak membantu)
Richard Tingle
5

Logikanya eksklusif-atau di Jawa disebut !=. Anda juga dapat menggunakan ^jika Anda ingin membingungkan teman-teman Anda.

Doradus
sumber
2

Anda dapat menggunakan Xtend (Operator Infix dan Operator Overloading) untuk membebani operator dan 'tetap' di Jawa

iga
sumber
Perhatikan bahwa Xtend tidak memungkinkan Anda untuk menimpa tanda sisipan ^; kamu harus menggunakan bool_1.xor(bool_2). Anehnya, pengurai bahkan tidak memungkinkan Anda untuk menggunakan tanda sisipan; Anda harus menggunakan xoruntuk boolean dan bitwiseXoruntuk bilangan bulat. Anda bisa, tentu saja, membebani operator lain, tetapi itu akan sangat membingungkan.
Kelvin
2

Apa yang Anda minta tidak masuk akal. Kecuali jika saya salah Anda menyarankan Anda ingin menggunakan XOR untuk melakukan operasi logis dengan cara DAN dan ATAU yang sama. Kode yang Anda berikan sebenarnya menunjukkan apa yang saya rujuk ke:

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

Fungsi Anda memiliki input boolean, dan ketika bitwise XOR digunakan pada boolean hasilnya sama dengan kode yang Anda berikan. Dengan kata lain, bitor XOR sudah efisien ketika membandingkan bit individu (boolean) atau membandingkan bit individu dalam nilai yang lebih besar. Untuk memasukkan ini ke dalam konteks, dalam hal nilai-nilai biner nilai non-nol adalah BENAR dan hanya NOL yang salah.

Jadi agar XOR diterapkan dengan cara yang sama dengan logika AND diterapkan, Anda bisa menggunakan nilai biner hanya dengan satu bit (memberikan hasil dan efisiensi yang sama) atau nilai biner harus dievaluasi secara keseluruhan, bukan per bit. Dengan kata lain ungkapan (010 ^^ 110) = FALSE bukan (010 ^^ 110) = 100. Ini akan menghapus sebagian besar makna semantik dari operasi, dan merupakan tes logis yang seharusnya tidak Anda gunakan.

pengguna2904660
sumber
1

A dan B harus menjadi nilai boolean untuk membuat! = Sama dengan xor sehingga tabel kebenaran akan terlihat sama. Anda juga bisa menggunakan! (A == B) lol.

John Theibert
sumber
1

Saya menggunakan kelas yang sangat populer "org.apache.commons.lang.BooleanUtils"

Metode ini diuji oleh banyak pengguna dan aman. Selamat bersenang-senang. Pemakaian:

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

Karena tipe data boolean disimpan seperti integer, operator bit ^ berfungsi seperti operasi XOR jika digunakan dengan nilai boolean.

//©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
            */
        }
    }
Memimpin
sumber
0

Ini sebuah contoh:

Diberi 2 nilai int, kembalikan benar jika satu negatif dan satu positif. Kecuali jika parameter "negatif" benar, maka kembalikan hanya benar jika keduanya negatif.

    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);
    }
Shadman Sudipto
sumber
0

Anda harus beralih ke Scala untuk mengimplementasikan operator Anda sendiri

contoh pipa

mut1na
sumber