Pertanyaan Operator pintas “atau-tugas” (| =) di Jawa


Saya memiliki serangkaian perbandingan yang panjang untuk dilakukan di Jawa, dan saya ingin tahu apakah satu atau lebih dari mereka keluar sebagai benar. String perbandingan panjang dan sulit dibaca, jadi saya merusaknya agar terbaca, dan secara otomatis menggunakan operator pintasan |= daripada negativeValue = negativeValue || boolean.

boolean negativeValue = false;
negativeValue |= (defaultStock < 0);
negativeValue |= (defaultWholesale < 0);
negativeValue |= (defaultRetail < 0);
negativeValue |= (defaultDelivery < 0);

Saya berharap negativeValue menjadi kenyataan jika salah satu nilai default <something> negatif. Apakah ini sah? Apakah akan melakukan apa yang saya harapkan? Saya tidak bisa melihatnya disebutkan di situs Sun atau stackoverflow, tetapi Eclipse tampaknya tidak memiliki masalah dengan itu dan kode kompilasi dan berjalan.


Demikian pula, jika saya ingin melakukan beberapa persimpangan logis, dapatkah saya gunakan &= dari pada &&?


75
2018-03-21 09:06


asal


Jawaban:


Itu |= adalah operator penugasan majemuk (JLS 15.26.2) untuk operator logika boolean | (JLS 15.22.2); tidak menjadi bingung dengan kondisional-atau || (JLS 15.24). Ada juga &= dan ^= sesuai dengan versi penugasan gabungan dari logika boolean & dan ^ masing-masing.

Dengan kata lain, untuk boolean b1, b2, keduanya setara:

 b1 |= b2;
 b1 = b1 | b2;

Perbedaan antara operator logika (& dan |) dibandingkan dengan rekan kondisional mereka (&& dan ||) adalah bahwa yang pertama tidak "shortcircuit"; yang terakhir lakukan. Itu adalah:

  • & dan |  selalu mengevaluasi kedua operan
  • && dan || mengevaluasi operan kanan secara kondisional; operan kanan dievaluasi hanya jika nilainya dapat mempengaruhi hasil operasi biner. Itu berarti operan kanan TIDAK dievaluasi ketika:
    • Operan kiri dari && mengevaluasi ke false
      • (karena tidak peduli apa operan kanan mengevaluasi, seluruh ekspresi adalah false)
    • Operan kiri dari || mengevaluasi ke true
      • (karena tidak peduli apa operan kanan mengevaluasi, seluruh ekspresi adalah true)

Jadi kembali ke pertanyaan awal Anda, ya, konstruk itu valid, dan sementara |= bukan cara pintas yang setara untuk = dan ||, itu menghitung apa yang Anda inginkan. Karena sisi kanan dari |= operator dalam penggunaan Anda adalah operasi perbandingan bilangan bulat sederhana, fakta itu | tidak shortcircuit tidak signifikan.

Ada beberapa kasus, ketika sirkuit pendek diinginkan, atau bahkan diperlukan, tetapi skenario Anda bukan salah satunya.

Sangat disayangkan bahwa tidak seperti beberapa bahasa lain, Java tidak memilikinya &&= dan ||=. Ini dibahas dalam pertanyaan itu Mengapa Java tidak memiliki versi tugas gabungan dari operator kondisional-dan dan kondisional? (&& =, || =).


183
2018-03-21 09:44



Ini bukan "pintas" (atau hubungan arus pendek) operator dengan cara itu || dan && adalah (karena mereka tidak akan mengevaluasi RHS jika mereka sudah tahu hasilnya berdasarkan LHS) tetapi akan melakukan apa yang Anda inginkan dalam hal kerja.

Sebagai contoh perbedaannya, kode ini akan baik-baik saja jika text tidak valid:

boolean nullOrEmpty = text == null || text.equals("")

padahal ini tidak akan:

boolean nullOrEmpty = false;
nullOrEmpty |= text == null;
nullOrEmpty |= text.equals(""); // Throws exception if text is null

(Tentunya Anda bisa melakukannya "".equals(text) untuk kasus tertentu - saya hanya mencoba mendemonstrasikan prinsipnya.)


16
2018-03-21 09:12



Anda hanya bisa memiliki satu pernyataan. Disajikan melalui beberapa baris yang terbaca hampir persis seperti kode contoh Anda, hanya kurang penting:

boolean negativeValue
    = defaultStock < 0 
    | defaultWholesale < 0
    | defaultRetail < 0
    | defaultDelivery < 0;

Untuk ekspresi yang paling sederhana, gunakan | bisa lebih cepat daripada || karena meskipun menghindari melakukan perbandingan, itu berarti menggunakan cabang secara implisit dan itu bisa berkali-kali lebih mahal.


3
2018-03-21 10:14



Meskipun mungkin berlebihan untuk masalah Anda, Jambu biji perpustakaan memiliki beberapa sintaks yang bagus dengan Predicates dan apakah evaluasi arus pendek dari atau / dan Predicates.

Pada dasarnya, perbandingan diubah menjadi objek, dikemas menjadi koleksi, dan kemudian diulang. Untuk atau predikat, klik pertama yang benar kembali dari iterasi, dan sebaliknya untuk dan.


1
2018-03-22 14:28



Jika itu tentang keterbacaan saya punya konsep pemisahan data yang diuji dari logika pengujian. Contoh kode:

// declare data
DataType [] dataToTest = new DataType[] {
    defaultStock,
    defaultWholesale,
    defaultRetail,
    defaultDelivery
}

// define logic
boolean checkIfAnyNegative(DataType [] data) {
    boolean negativeValue = false;
    int i = 0;
    while (!negativeValue && i < data.length) {
        negativeValue = data[i++] < 0;
    }
    return negativeValue;
}

Kode terlihat lebih verbose dan cukup jelas. Anda bahkan dapat membuat array dalam pemanggilan metode, seperti ini:

checkIfAnyNegative(new DataType[] {
    defaultStock,
    defaultWholesale,
    defaultRetail,
    defaultDelivery
});

Ini lebih mudah dibaca daripada 'perbandingan string', dan juga memiliki keunggulan kinerja dari hubungan arus pendek (dengan biaya alokasi array dan pemanggilan metode).

Edit: Bahkan keterbacaan lebih mudah dapat dicapai dengan menggunakan parameter varargs:

Tanda tangan metode adalah:

boolean checkIfAnyNegative(DataType ... data)

Dan panggilan itu bisa terlihat seperti ini:

checkIfAnyNegative( defaultStock, defaultWholesale, defaultRetail, defaultDelivery );

1
2018-04-25 09:38



List<Integer> params = Arrays.asList (defaultStock, defaultWholesale, 
                                       defaultRetail, defaultDelivery);
int minParam = Collections.min (params);
negativeValue = minParam < 0;

0
2018-03-21 09:15



|| logika boolean OR
| bitwise OR

| = bitwise, termasuk OR dan operator penugasan

Alasan mengapa | = tidak shortcircit adalah karena melakukan bitwise ATAU bukan OR yang logis. Artinya:


C | = 2 sama dengan C = C | 2

Tutorial untuk operator java


0
2018-01-11 19:15



Ini adalah posting lama tetapi untuk memberikan perspektif yang berbeda untuk pemula, saya ingin memberikan contoh.

Saya pikir kasus penggunaan yang paling umum untuk operator senyawa serupa akan +=. Saya yakin kita semua menulis sesuatu seperti ini:

int a = 10;   // a = 10
a += 5;   // a = 15

Apa maksudnya ini? Itu untuk menghindari penulisan variabel a dua kali di baris yang sama. (Apakah saya kehilangan sesuatu yang superior di sini?)

Jadi, baris berikutnya melakukan hal yang sama, menghindari untuk mengetikkan variabel b1 dua kali di baris yang sama.

b1 |= b2;

0
2018-04-16 14:13