Saya memiliki serangkaian perbandingan panjang yang harus dilakukan di Java, dan saya ingin tahu apakah satu atau lebih dari mereka terbukti benar. String perbandingannya panjang dan sulit dibaca, jadi saya memutuskannya agar mudah dibaca, 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 true jika salah satu nilai default <something> adalah negatif. Apakah ini sah? Akankah itu melakukan apa yang saya harapkan? Saya tidak dapat melihatnya disebutkan di situs Sun atau stackoverflow, tetapi Eclipse tampaknya tidak memiliki masalah dengannya dan kode tersebut terkompilasi dan berjalan.
Demikian pula, jika saya ingin melakukan beberapa persimpangan logis, dapatkah saya menggunakan &=
sebagai gantinya &&
?
sumber
||=
operator yang tidak ada , tetapi|=
merupakan bentuk kombinasi dari bitwise atau operator.|=
hubungan arus pendek tidak akan konsisten dengan operator penugasan gabungan lainnya, karenaa |= b;
tidak akan sama dengana = a | b;
, dengan peringatan biasa tentang mengevaluasia
dua kali (jika itu penting). Bagi saya sepertinya keputusan perilaku bahasa besar tidak terjadi||=
, jadi saya kehilangan maksud Anda.Jawaban:
Ini
|=
adalah operator penugasan gabungan ( JLS 15.26.2 ) untuk operator logika boolean|
( JLS 15.22.2 ); jangan disamakan dengan kondisional-atau||
( JLS 15.24 ). Ada juga&=
dan^=
sesuai dengan versi penugasan gabungan dari logika boolean&
dan^
masing - masing.Dengan kata lain, karena
boolean b1, b2
, keduanya setara:Perbedaan antara operator logika (
&
dan|
) dibandingkan dengan operator bersyaratnya (&&
dan||
) adalah bahwa operator logika sebelumnya tidak melakukan "shortcircuit"; yang terakhir lakukan. Itu adalah:&
dan|
selalu evaluasi kedua operan&&
dan||
mengevaluasi operan kanan secara kondisional ; operan kanan dievaluasi hanya jika nilainya dapat mempengaruhi hasil operasi biner. Itu berarti operan yang tepat TIDAK dievaluasi ketika:&&
mengevaluasi kefalse
false
)||
mengevaluasi ketrue
true
)Jadi kembali ke pertanyaan awal Anda, ya, konstruksi itu valid, dan while
|=
bukan merupakan jalan pintas yang setara untuk=
dan||
, itu menghitung apa yang Anda inginkan. Karena sisi kanan|=
operator dalam penggunaan Anda adalah operasi perbandingan bilangan bulat sederhana, fakta bahwa|
tidak ada hubungan pendek tidak signifikan.Ada beberapa kasus, ketika sirkuit pendek diinginkan, atau bahkan diperlukan, tetapi skenario Anda bukan salah satunya.
Sayangnya, tidak seperti beberapa bahasa lain, Java tidak memiliki
&&=
dan||=
. Hal ini dibahas dalam pertanyaan Mengapa Java tidak memiliki versi penugasan gabungan dari operator bersyarat dan dan bersyarat atau? (&& =, || =) .sumber
|
Ini bukan operator "jalan pintas" (atau hubungan arus pendek) seperti itu || dan && are (karena mereka tidak akan mengevaluasi RHS jika mereka sudah mengetahui hasil berdasarkan LHS) tetapi akan melakukan apa yang Anda inginkan dalam hal bekerja .
Sebagai contoh perbedaannya, kode ini akan baik-baik saja jika
text
null:boolean nullOrEmpty = text == null || text.equals("")
sedangkan ini tidak akan:
boolean nullOrEmpty = false; nullOrEmpty |= text == null; nullOrEmpty |= text.equals(""); // Throws exception if text is null
(Jelas Anda dapat melakukannya
"".equals(text)
untuk kasus khusus itu - saya hanya mencoba mendemonstrasikan prinsipnya.)sumber
Anda hanya bisa memiliki satu pernyataan. Dinyatakan dalam beberapa baris, pembacaannya hampir persis seperti kode sampel Anda, hanya saja yang kurang penting:
boolean negativeValue = defaultStock < 0 | defaultWholesale < 0 | defaultRetail < 0 | defaultDelivery < 0;
Untuk ekspresi yang paling sederhana, menggunakan
|
bisa lebih cepat daripada||
karena meskipun menghindari melakukan perbandingan, itu berarti menggunakan cabang secara implisit dan itu bisa berkali-kali lebih mahal.sumber
Meskipun mungkin berlebihan untuk masalah Anda, pustaka Guava memiliki sintaks yang bagus dengan
Predicate
s dan melakukan evaluasi sirkuit pendek atau / danPredicate
s.Pada dasarnya, perbandingan diubah menjadi objek, dikemas menjadi koleksi, dan kemudian diulangi. Untuk atau predikat, klik benar pertama akan kembali dari iterasi, dan sebaliknya untuk dan.
sumber
Jika ini 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 bertele-tele 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 'string perbandingan', dan juga memiliki keunggulan kinerja dari hubungan arus pendek (dengan biaya alokasi array dan pemanggilan metode).
Sunting: Bahkan lebih banyak keterbacaan dapat dengan mudah dicapai dengan menggunakan parameter varargs:
Tanda tangan metode adalah:
boolean checkIfAnyNegative(DataType ... data)
Dan panggilannya bisa terlihat seperti ini:
sumber
Ini adalah posting lama tetapi untuk memberikan perspektif yang berbeda untuk pemula, saya ingin memberikan contoh.
Saya pikir kasus penggunaan paling umum untuk operator gabungan serupa adalah
+=
. Saya yakin kita semua menulis sesuatu seperti ini:int a = 10; // a = 10 a += 5; // a = 15
Apa gunanya ini? Intinya adalah untuk menghindari boilerplate dan menghilangkan kode berulang.
Jadi, baris berikutnya melakukan hal yang persis sama, menghindari mengetik variabel
b1
dua kali di baris yang sama.sumber
longNameOfAccumulatorAVariable += 5;
vs.longNameOfAccumulatorAVariable = longNameOfAccumulatorVVariable + 5;
List<Integer> params = Arrays.asList (defaultStock, defaultWholesale, defaultRetail, defaultDelivery); int minParam = Collections.min (params); negativeValue = minParam < 0;
sumber
negativeValue = defaultStock < 0 || defaultWholesale < 0
dll. Selain ketidakefisienan dari semua tinju dan pembungkus yang terjadi di sini, saya tidak menemukan itu hampir semudah memahami apa arti kode Anda sebenarnya.|| boolean logis ATAU
| bitwise ATAU
| = bitwise inklusif OR dan operator penugasan
Alasan mengapa | = tidak melakukan shortcircit adalah karena ia melakukan bitwise ATAU bukan OR logis. Artinya:
Tutorial untuk operator java
sumber
|
integer bitwise OR tetapi juga logis OR - lihat Spesifikasi Bahasa Java 15.22.2.