Saya punya kode berikut:
if(!partialHits.get(req_nr).containsKey(z) || partialHits.get(req_nr).get(z) < tmpmap.get(z)){
partialHits.get(z).put(z, tmpmap.get(z));
}
di mana partialHits
adalah HashMap.
Apa yang akan terjadi jika pernyataan pertama benar? Akan Jawa masih memeriksa kedua pernyataan? Karena pernyataan pertama benar, yang HashMap tidak boleh mengandung kunci tertentu, sehingga jika kedua pernyataan diperiksa, saya akan mendapatkan NullPointerException
.
Jadi dalam kata-kata sederhana, jika kita memiliki kode berikut
if(a && b)
if(a || b)
akan Jawa check b
jika a
adalah palsu dalam kasus pertama dan jika a
adalah benar dalam kasus kedua?
Tidak, itu tidak akan dievaluasi. Dan ini sangat berguna. Misalnya, jika anda perlu untuk menguji apakah sebuah String tidak null atau kosong, anda dapat menulis:
if (str != null && !str.isEmpty()) {
doSomethingWith(str.charAt(0));
}
atau, cara lain di sekitar
if (str == null || str.isEmpty()) {
complainAboutUnusableString();
} else {
doSomethingWith(str.charAt(0));
}
Jika kita tidak't memiliki 'sirkuit pendek' di Jawa, kita'd menerima banyak NullPointerExceptions di atas baris kode.
Jawa memiliki 5 berbeda boolean membandingkan operator: &, &&, |, ||, ^
& dan && adalah "dan" operator | dan || "atau" operator, ^ adalah "xor"
Single yang akan memeriksa setiap parameter, terlepas dari nilai-nilai, sebelum memeriksa nilai-nilai dari parameter.
Dua yang pertama akan memeriksa kiri parameter dan nilainya dan jika benar
(||
) atau false
(&&
) meninggalkan kedua tak tersentuh.
Suara compilcated? Contoh mudah harus membuat jelas:
Diberikan untuk semua contoh:
String aString = null;
DAN:
if (aString != null & aString.equals("lala"))
Kedua parameter yang diperiksa sebelum evaluasi dilakukan dan NullPointerException akan dilemparkan untuk parameter kedua.
if (aString != null && aString.equals("lala"))
Parameter pertama adalah memeriksa dan kembali palsu
, sehingga kedua parameter won't diperiksa, karena hasilnya adalah palsu
pula.
Yang sama ATAU:
if (aString == null | !aString.equals("lala"))
Akan menaikkan NullPointerException, terlalu.
if (aString == null || !aString.equals("lala"))
Parameter pertama adalah memeriksa dan mengembalikan true
, sehingga kedua parameter won't diperiksa, karena hasilnya adalah benar
pula.
XOR dapat't dapat dioptimalkan, karena itu tergantung pada kedua parameter.
Tidak ada itu tidak akan diperiksa. Perilaku ini disebut short-circuit evaluasi dan adalah fitur dalam banyak bahasa, termasuk Jawa.
Semua jawaban di sini adalah besar, tetapi hanya untuk menggambarkan dari mana ini berasal dari, untuk pertanyaan-pertanyaan seperti ini's baik untuk pergi ke sumber: Bahasa Jawa Spesifikasi.
Pasal 15:23, Bersyarat-operator And (&&), mengatakan:
&& operator seperti & (§15.22.2), tetapi mengevaluasi kanan operan hanya jika nilai dari operan tangan-kiri adalah benar. [...] Pada waktu berjalan, tangan kiri operan ekspresi dievaluasi terlebih dahulu [...] jika nilai yang dihasilkan adalah palsu, nilai kondisional dan ekspresi adalah palsu dan tangan kanan operan ekspresi tidak dievaluasi. Jika nilai dari sisi kiri operan adalah benar, maka tangan kanan ekspresi dievaluasi [...] nilai yang dihasilkan menjadi nilai kondisional dan ekspresi. Dengan demikian, && menghitung hasil yang sama seperti & boolean pada operan. Ini berbeda hanya dalam bahwa tangan kanan operan ekspresi dievaluasi kondisional bukan selalu.
Dan demikian pula, Bagian 15:24, Bersyarat-operator Or (||), mengatakan:
| | operator lebih suka | (§15.22.2), tetapi mengevaluasi kanan operan hanya jika nilai dari operan tangan-kiri adalah palsu. [...] Pada waktu berjalan, tangan kiri operan ekspresi dievaluasi pertama; [...] jika nilai yang dihasilkan adalah benar, nilai bersyarat-atau ekspresi adalah benar dan tepat-tangan operan ekspresi tidak dievaluasi. Jika nilai dari operan tangan-kiri adalah palsu, maka tangan kanan ekspresi yang dievaluasi; [...] nilai yang dihasilkan menjadi nilai bersyarat-atau ekspresi. Dengan demikian, || menghitung hasil yang sama seperti pada boolean atau Boolean operan. Ini berbeda hanya dalam bahwa tangan kanan operan ekspresi dievaluasi kondisional bukan selalu.
Sedikit berulang-ulang, mungkin, tapi konfirmasi terbaik dari bagaimana mereka bekerja. Demikian pula conditional operator (?:) hanya mengevaluasi sesuai 'setengah' (kiri setengah jika nilai adalah benar, setengah benar jika itu's palsu), yang memungkinkan penggunaan ungkapan-ungkapan seperti:
int x = (y == null) ? 0 : y.getFoo();
tanpa NullPointerException.
Tidak, jika benar (dalam atau
test), b tidak akan diuji, sebagai hasil dari tes akan selalu benar, apa pun nilai b berekspresi.
Membuat tes sederhana:
if (true || ((String) null).equals("foobar")) {
...
}
akan tidak melempar NullPointerException
!
Sirkuit pendek di sini berarti bahwa kedua kondisi tidak't dievaluasi.
Jika ( A && B ) akan mengakibatkan hubung singkat jika A adalah Palsu.
Jika ( A && B ) akan tidak hasil di Sirkuit pendek jika A adalah Benar.
Jika ( A || B ) akan mengakibatkan hubung singkat jika A adalah Benar.
Jika ( A || B) tidak hasil di sirkuit pendek jika A adalah Palsu.
Ya, sirkuit pendek evaluasi untuk ekspresi boolean adalah perilaku default di semua C-seperti keluarga.
Fakta yang menarik adalah bahwa Java juga menggunakan &
dan |
sebagai logika operand (mereka yang kelebihan beban, dengan int
jenis mereka diharapkan bitwise operasi) untuk mengevaluasi semua ketentuan dalam ekspresi, yang juga berguna ketika anda membutuhkan efek samping.
Ini kembali ke dasar perbedaan antara & dan &&, | dan ||
BTW anda melakukan tugas-tugas yang sama berkali-kali. Tidak yakin jika efisiensi adalah masalah. Anda bisa menghapus beberapa duplikasi.
Z z2 = partialHits.get(req_nr).get(z); // assuming a value cannout be null.
Z z3 = tmpmap.get(z); // assuming z3 cannot be null.
if(z2 == null || z2 < z3){
partialHits.get(z).put(z, z3);
}