Apa artinya "| ="? (operator pipa sama)

249

Saya mencoba mencari menggunakan Google Search dan Stack Overflow, tetapi tidak muncul hasil apa pun. Saya telah melihat ini di kode pustaka opensource:

Notification notification = new Notification(icon, tickerText, when);
notification.defaults |= Notification.DEFAULT_SOUND;
notification.defaults |= Notification.DEFAULT_VIBRATE;

Apa yang dimaksud dengan "| =" ( pipe equal operator)?

wtsang02
sumber
4
Saya ingin tahu apakah menambahkan sesuatu seperti pipe equal operatorke pertanyaan ini atau dokumentasi lain pada topik tidak akan membantu orang mencari.
Denys Séguret
10
@ EJP kalian berbicara tentang dokumen ini . Ini jelas memberi tahu para doks tidak memiliki dokumentasi tentang penggunaan ini.
wtsang02
36
Kecuali Anda tahu itu disebut pipa sama, sangat sulit untuk mencari tanpa meminta seseorang.
ataulm
@ataulm memang, menghabiskan beberapa waktu untuk mencari-cari istilah vertical baryang akhirnya membawa saya ke sini.
ruuter
1
Kemungkinan duplikat dari apa yang dilakukan operator | = di Java?
poring91

Jawaban:

323

|=membaca dengan cara yang sama seperti +=.

notification.defaults |= Notification.DEFAULT_SOUND;

sama dengan

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;

di mana |operator bit-bijaksana ATAU.

Semua operator direferensikan di sini .

Operator bit-wise digunakan karena, seperti sering, konstanta tersebut memungkinkan int untuk membawa bendera.

Jika Anda melihat konstanta itu, Anda akan melihat bahwa mereka memiliki kekuatan dua:

public static final int DEFAULT_SOUND = 1;
public static final int DEFAULT_VIBRATE = 2; // is the same than 1<<1 or 10 in binary
public static final int DEFAULT_LIGHTS = 4; // is the same than 1<<2 or 100 in binary

Jadi Anda bisa menggunakan bit-wise OR untuk menambahkan flag

int myFlags = DEFAULT_SOUND | DEFAULT_VIBRATE; // same as 001 | 010, producing 011

begitu

myFlags |= DEFAULT_LIGHTS;

berarti kami menambahkan bendera.

Dan secara simetris, kami menguji suatu bendera diset menggunakan &:

boolean hasVibrate = (DEFAULT_VIBRATE & myFlags) != 0;
Denys Séguret
sumber
2
Sama seperti j += 1;sama dengan j = j + 1;.
David Schwartz
1
@ ARS: Saya tidak bisa memikirkan contoh tandingan di Jawa (mungkin jika jitu volatile?), Tapi saya akan mengambil kata-kata Anda untuk itu.
David Schwartz
6
@DavidSchwartz Lihat ini
arshajii
2
boolean hasVibrate = DEFAULT_VIBRATE & myFlags;- dapatkah Anda menerjemahkan dari intmenjadi booleanseperti itu di Jawa? Itu akan berlaku di C, tapi saya pikir di Jawa itu harus ditulis sebagaiboolean hasVibrate = ((DEFAULT_VIBRATE & myFlags) == DEFAULT_VIBRATE);
BlueRaja - Danny Pflughoeft
1
@ DavidSchwartz Wow, perbandingan dengan itu +=akhirnya membuat saya mengerti. Terima kasih!
C4d
39

Anda sudah mendapat jawaban yang cukup untuk pertanyaan Anda. Tetapi mungkin jawaban saya membantu Anda lebih banyak tentang |=jenis operator biner.

Saya menulis tabel untuk operator bitwise :
Berikut ini valid:

----------------------------------------------------------------------------------------
Operator   Description                                   Example
----------------------------------------------------------------------------------------
|=        bitwise inclusive OR and assignment operator   C |= 2 is same as C = C | 2
^=        bitwise exclusive OR and assignment operator   C ^= 2 is same as C = C ^ 2
&=        Bitwise AND assignment operator                C &= 2 is same as C = C & 2
<<=       Left shift AND assignment operator             C <<= 2 is same as C = C << 2
>>=       Right shift AND assignment operator            C >>= 2 is same as C = C >> 2  
----------------------------------------------------------------------------------------

perhatikan semua operator adalah operator biner.

Juga Catatan: (untuk poin di bawah ini saya ingin menambahkan jawaban saya)

  • >>>adalah operator bitwise di Jawa yang disebut Pergeseran tidak bertanda
    tetapi >>>=bukan operator di Jawa. >>> = operator

  • ~ bitwise melengkapi bit, 0 to 1 and 1 to 0 (operator unary) tetapi ~=bukan operator.

  • Selain itu, !Disebut Logical NOT Operator, tetapi !=Memeriksa apakah nilai dua operan sama atau tidak, jika nilai tidak sama maka kondisinya menjadi benar. mis (A != B) is true. dimana A=!Bcara jika Byang truekemudian Amenjadi false(dan jika Bini falsekemudianA menjadi true).

catatan: |tidak disebut pipa, melainkan disebut OR, pipa adalah terminologi shell mentransfer satu proses ke proses selanjutnya ..

Grijesh Chauhan
sumber
9
Saya mendapat kesan bahwa "pipa" adalah nama karakter, yang merupakan asal istilah shell. Tapi, melihat Wikipedia, itu sebenarnya disebut "bar vertikal" dan "pipa" khusus untuk perintah shell. Hanya ingin mengucapkan terima kasih karena menambahkan catatan tambahan itu!
Caleb Brinkman
18

Saya sedang mencari jawaban tentang apa yang |=ada di Groovy dan meskipun jawaban di atas benar, mereka tidak membantu saya memahami sepotong kode tertentu yang saya lihat.

Khususnya, ketika diterapkan pada variabel boolean "| =" akan mengaturnya menjadi TRUE saat pertama kali ia menemukan ekspresi yang benar di sisi kanan dan akan MEMEGANG nilai TRUE untuk semua | = panggilan berikutnya. Seperti gerendel.

Berikut ini contoh sederhana dari ini:

groovy> boolean result  
groovy> //------------ 
groovy> println result           //<-- False by default
groovy> println result |= false 
groovy> println result |= true   //<-- set to True and latched on to it
groovy> println result |= false 

Keluaran:

false
false
true
true

Sunting : Mengapa ini berguna?

Pertimbangkan situasi di mana Anda ingin tahu apakah ada yang berubah pada berbagai objek dan jika demikian beri tahu beberapa perubahan. Jadi, Anda akan mengatur hasChangesboolean dan mengaturnya ke |= diff (a,b)dan kemudian |= dif(b,c)dll. Ini adalah contoh singkat:

groovy> boolean hasChanges, a, b, c, d 
groovy> diff = {x,y -> x!=y}  
groovy> hasChanges |= diff(a,b) 
groovy> hasChanges |= diff(b,c) 
groovy> hasChanges |= diff(true,false) 
groovy> hasChanges |= diff(c,d) 
groovy> hasChanges 

Result: true
dbrin
sumber
10
Yap, hal yang sama berlaku di Jawa. Tetapi perlu dicatat bahwa operasi OR y|=exprtersebut bukan hubungan arus pendek (tidak seperti y = y || expr), artinya exprselalu dievaluasi. Ini tidak jelas bagi saya untuk pertama kalinya :) Jadi, penting untuk dicatat sebelum refactoring bahwa penggantian y|=expry=y||xadalah tidak semantik setara dalam hal exprsebenarnya memiliki efek samping.
NIA
1
Dan, mengingat hal ini, dalam kasus Anda dengan hasChangesitu mungkin akan lebih baik untuk memilih y=y||xbentuk untuk mendapatkan manfaat dari short-ciruit, karena ketika Anda menemukan perubahan itu sebenarnya tidak diperlukan untuk melakukan perbedaan yang berguna karena Anda sudah tahu jawabannya. (Terutama penting dalam situasi kehidupan nyata ketika objek yang dibandingkan rumit dan diffmembuat mereka tidak terlalu cepat)
NIA
@NIA Terima kasih atas suaranya. Ya saya setuju dengan poin Anda tentang hubungan arus pendek.
dbrin
2
@ FranklinYu tentu saja tidak detail implementasi. Non-korsleting tidak secara khusus disebutkan di tempat Anda direferensikan hanya karena itu bukan kekhasan - itu adalah perilaku default dan normal untuk sebagian besar operator. Keunikan sebenarnya adalah hubung singkat dari ||dan &&, dan dalam bagian yang sesuai 15,23 dan 15,24 spesifikasi fakta ini dinyatakan dengan jelas, dan perbedaan ini dari |dan &ditekankan.
NIA
2
@ FranklinYu Jadi saya pikir tidak perlu mengatakan sesuatu tentang ini lagi di bawah pada bagian yang Anda referensikan (15.26.2 "Operator penugasan Compund") hanya karena penugasan compond selalu non-hubungan pendek (tidak ada ||=dan &&=operator yang akan melanggar aturan dan membutuhkan penyebutan khusus).
NIA
13

Ini adalah pemendekan untuk ini:

notification.defaults = notification.defaults | Notification.DEFAULT_SOUND;

Dan |sedikit bijak ATAU.

Sampai Helge
sumber
3

Catatan: || = tidak ada. (logis atau) Anda dapat menggunakan

y= y || expr; // expr is NOT evaluated if y==true

atau

y = expr ? true : y;  // expr is always evaluated.
perempuan
sumber
4
Tidak cukup lengkap: Anda masih dapat menggunakan y |= exprdengan boolean dan itu memberikan hasil yang sama yseperti varian Anda dengan catatan penting bahwa itu bukan garis pendek , yang berarti bahwa expr selalu dievaluasi, bahkan dalam kasusy==true
NIA