Apa itu Java?: Operator dipanggil dan apa fungsinya?

161

Saya telah bekerja dengan Java beberapa tahun, tetapi sampai saat ini saya belum menemukan konstruk ini:

int count = isHere ? getHereCount(index) : getAwayCount(index);

Ini mungkin pertanyaan yang sangat sederhana, tetapi bisakah seseorang menjelaskannya? Bagaimana saya membacanya? Saya cukup yakin saya tahu cara kerjanya.

  • jika isHerebenar, getHereCount()disebut,
  • jika isHerefalse getAwayCount()disebut.

Benar? Apa sebutan konstruk ini?

mainstringargs
sumber
2
Lihat juga stackoverflow.com/questions/795286/what-does-do-in-c untuk versi C ++ dari pertanyaan ini (sebenarnya baru saja ditanyakan kemarin).
Michael Myers
2
Perlu diingat bahwa dunia C / C ++ / Java terbagi rata secara merata antara orang-orang yang menganggapnya jelek dan membingungkan dan akan menghindarinya seperti wabah, dan orang-orang yang berpikir Anda tidak bisa benar-benar mengklaim tahu C, C ++ atau Java jika Anda tidak bisa mengenalinya dan menggunakannya tanpa berhenti untuk berpikir.
Paul Tomblin
3
Biasanya dianggap sebagai bentuk buruk di Jawa untuk menggunakannya di luar kasus yang paling jelas dan paling sederhana. Jika Anda menemukan diri Anda bersarang, Anda berada di luar. Di sisi lain, dalam budaya C di mana kode cepat dan pintar dinilai di atas kejelasan, itu dianggap dapat diterima.
Yishai
17
answer_to_question = (mengenali_operator)? (social_acceptance): (condescending_finger_wag)
Dan
Anda dapat merujuk sumber ini untuk informasi lebih lanjut.
Shiva

Jawaban:

189

Ya, itu adalah bentuk steno dari

int count;
if (isHere)
    count = getHereCount(index);
else
    count = getAwayCount(index);

Ini disebut operator kondisional . Banyak orang (secara keliru) menyebutnya operator ternary , karena itu satu-satunya operator ternary (tiga argumen) di Jawa, C, C ++, dan mungkin banyak bahasa lainnya. Namun secara teoritis mungkin ada operator ternary lain, sedangkan hanya ada satu operator kondisional .

Nama resmi diberikan dalam Spesifikasi Bahasa Jawa :

§15.25 Operator Bersyarat? :

Operator bersyarat ? :menggunakan nilai boolean dari satu ekspresi untuk memutuskan mana dari dua ekspresi lain yang harus dievaluasi.

Perhatikan bahwa kedua cabang harus mengarah ke metode dengan nilai pengembalian:

Ini adalah kesalahan waktu kompilasi untuk ekspresi operan kedua atau ketiga sebagai permohonan metode kosong.

Bahkan, dengan tata bahasa pernyataan ekspresi ( §14.8 ), itu tidak diizinkan untuk ekspresi bersyarat muncul dalam konteks apa pun di mana doa metode void bisa muncul.

Jadi, jika doSomething()dan doSomethingElse()merupakan metode batal, Anda tidak dapat mengompres ini:

if (someBool)
    doSomething();
else
    doSomethingElse();

dalam hal ini:

someBool ? doSomething() : doSomethingElse();

Kata-kata sederhana:

booleanCondition ? executeThisPartIfBooleanConditionIsTrue : executeThisPartIfBooleanConditionIsFalse 
Michael Myers
sumber
Saya tidak mengerti apa yang salah lakukan. Saya percaya Anda dan semua. Bagiku itu sama saja dengan aslinya. Apakah karena mereka hanya memanggil fungsi lain yang mungkin atau tidak mengembalikan nilai dan membiarkan kode berikutnya diatur untuk berjalan?
johnny
8
Saya berasumsi doSomething () dan doSomethingElse () adalah metode yang tidak berlaku. Apa yang dikatakan bit terakhir dari spesifikasi adalah bahwa operator ternary harus mengembalikan nilai, sehingga tidak ada operan yang dapat menjadi metode batal.
Michael Myers
Dikatakan sedikit lebih dari itu. Dikatakan operator bersyarat tidak diizinkan di mana metode batal COULD muncul. Jadi, misalnya, pernyataan berikut: VALID: String x = (false)? "X": "Y"; BUKAN VALID: (salah)? "X": "Y";
kenj0418
4
Tidaklah salah untuk menyebutnya sebagai "operator ternary", seperti halnya tidak salah (pada 2016) untuk menyebut Obama sebagai "Presiden", meskipun ada kemungkinan bahwa akan ada presiden lain di masa depan.
Dawood ibn Kareem
2
@ DawoodibnKareem Saya pikir Michael sengaja dimasukkan thedalam cetak miring the ternary operator, dan itu yang dia maksud adalah salah, bukan itu ternary operatorsalah. The ternary operator menyiratkan bahwa, sebagai Michael mengatakan, itu adalah satu-satunya, yang pada gilirannya dapat menyebabkan satu untuk menganggap tidak ada operator ternary lainnya, yang adalah apa yang Michael katakan adalah salah, dan saya setuju, itu akan menjadi asumsi yang salah.
Ghoti and Chips
32

Yang lain telah menjawab ini sampai tingkat yang wajar, tetapi seringkali dengan nama "operator ternary".

Menjadi pedant seperti saya, saya ingin memperjelas bahwa nama operator adalah operator kondisional atau "operator kondisional?:". Ini merupakan operator ternary (dalam hal ini memiliki tiga operan) dan hal itu terjadi untuk menjadi satu-satunya operator terner di Jawa saat ini.

Namun, speknya cukup jelas bahwa namanya adalah operator kondisional atau "operator kondisional?", Yang sama sekali tidak ambigu. Saya pikir itu lebih jelas untuk memanggilnya dengan nama itu, karena itu menunjukkan perilaku operator sampai batas tertentu (mengevaluasi suatu kondisi) daripada hanya berapa banyak operan yang dimilikinya.

Jon Skeet
sumber
3
Jawaban ini secara teknis benar. Namun, karena hanya ada satu operator ternary, Anda sering melihatnya disebut sebagai operator ternary. Meskipun nama ini tidak menyampaikan arti lengkap dari operator, itu adalah nama yang macet. Jika Anda menyebutkan nama "operator ternary", programmer tahu apa yang Anda bicarakan. Spesifikasi yang Anda sebutkan juga menyebut operator ini sebagai "Persyaratan Bersyarat" yang tampaknya lebih informatif. java.sun.com/docs/books/jls/third_edition/html/…
Gary
17
Saya hanya berpikir ada baiknya memanggil sesuatu dengan nama yang ditentukan. Secara khusus, jika Java pernah mendapatkan operator ternary lain, orang yang menggunakan istilah "operator kondisional" akan tetap benar dan tidak ambigu - tidak seperti mereka yang hanya mengatakan "operator ternary". Ya, frase "operator ternary" telah macet - jawaban saya adalah bagian dari upaya untuk "membatalkan" itu, sama seperti saya mencoba untuk memperbaiki klaim bahwa "objek dilewatkan dengan referensi".
Jon Skeet
1
Bolehkah saya mengarahkan Anda ke halaman ini dari Oracle yang berbicara tentang tiga "operator kondisional" tetapi hanya satu "operator ternary"? Jika Anda ingin memperjelas operator mana yang Anda maksud, mungkin lebih baik menggunakan nama yang digunakan kebanyakan orang. (Ya, saya tahu saya muncul di pesta persis ketika tuan rumah sedang mencuci piring terakhir).
Dawood ibn Kareem
@ Davidvidallallace: Menggunakan "operator kondisional?:" Lebih baik, IMO - akan mengedit untuk menjelaskan itu. Tetapi saya pikir perlu meyakinkan orang untuk menggunakan nama sebenarnya dari operator daripada berfokus pada satu aspek (berapa banyak operan yang dimilikinya) yang tidak ada hubungannya dengan perilakunya. (Ini juga tidak biasa untuk tutorial menjadi kurang tepat dari spesifikasi, yang memanggil &&operator kondisional dan, dan operator ||kondisional, atau hanya menggunakan "operator kondisional" untuk ?:.
Jon Skeet
Saya tidak tahu Jika seseorang mengatakan "operator kondisional" kepada saya, saya tidak akan yakin apa artinya. Di mana saya berasal (ujung dunia dari Anda) orang tidak menyebutnya begitu. Jika mereka mengatakan "operator ternary" atau "operator kait", maka saya mengerti. Saya mengagumi ambisi Anda, ingin mengubah cara orang berbicara. Jika ada yang bisa melakukannya, itu Anda. Tetapi saya tidak banyak berharap atau melihat banyak hal.
Dawood ibn Kareem
17

Menurut Spesifikasi Sun Java , itu disebut Operator Bersyarat. Lihat bagian 15.25. Anda benar tentang apa yang dilakukannya.

Operator bersyarat? : menggunakan nilai boolean dari satu ekspresi untuk memutuskan yang mana dari dua ekspresi lain yang harus dievaluasi.

Operator bersyarat secara sintaksis asosiatif (mengelompokkan kanan-ke-kiri), sehingga a? B: c? D: e? F: g artinya sama dengan a? B: (c? D: (e? F : g)).

ConditionalExpression:
        ConditionalOrExpression
        ConditionalOrExpression ? Expression : ConditionalExpression

Operator bersyarat memiliki tiga ekspresi operan; ? muncul di antara ekspresi pertama dan kedua, dan: muncul di antara ekspresi kedua dan ketiga.

Ekspresi pertama harus dari tipe boolean atau Boolean, atau kesalahan waktu kompilasi terjadi.

JRL
sumber
5
int count = isHere ? getHereCount(index) : getAwayCount(index);

berarti:

if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}
Romain Linsolas
sumber
5

Tidak sepenuhnya benar, tepatnya:

  1. jika isHere benar, hasil getHereCount () dikembalikan
  2. otheriwse hasil getAwayCount () dikembalikan

Itu "dikembalikan" sangat penting. Itu berarti metode harus mengembalikan nilai dan nilai itu harus diberikan di suatu tempat.

Juga, itu tidak persis sama dengan sintaksis dengan versi if-else. Sebagai contoh:

String str1,str2,str3,str4;
boolean check;
//...
return str1 + (check ? str2 : str3) + str4;

Jika dikodekan dengan if-else akan selalu menghasilkan lebih banyak bytecode.

RichN
sumber
Saya percaya javac bebas untuk menghasilkan bytecode yang sama. Meskipun Anda benar bahwa ada kasus sudut tidak jelas di mana mereka tidak setara.
Tom Hawtin - tackline
Ya tentu saja. Bagi saya, manfaat sebenarnya dari operator kondisional adalah contoh yang saya berikan. Alternatifnya adalah: // terkesiap !! String temp = str1; if (centang) temp + = str2; selain itu temp + = str3; temp + = str4; temp kembali; atau handcoding operasi penambahan StringBuilder. Yang pertama menderita masalah efisiensi serius sementara yang kedua terlalu bertele-tele dan merupakan upaya yang melelahkan tanpa banyak keuntungan.
RichN
4

Ternary, bersyarat; tomat, tomatoh. Apa yang benar-benar berharga adalah inisialisasi variabel. Jika (seperti saya) Anda suka menginisialisasi variabel di mana mereka didefinisikan, operator ternary kondisional (karena keduanya) memungkinkan Anda untuk melakukan itu dalam kasus di mana ada persyaratan tentang nilainya. Terutama terkenal di bidang terakhir, tetapi berguna di tempat lain juga.

misalnya:

public class Foo {
    final double    value;

    public Foo(boolean positive, double value) {
        this.value = positive ? value : -value;
    }
}

Tanpa operator itu - dengan nama apa pun - Anda harus membuat field non-final atau menulis fungsi hanya untuk menginisialisasi itu. Sebenarnya, itu tidak benar - masih dapat diinisialisasi menggunakan if / else, setidaknya di Java. Tapi saya menemukan pembersih ini.

Carl Manaster
sumber
3

Konstruk ini disebut Operator Ternary dalam Teknik dan Programing Ilmu Komputer.
Dan Wikipedia menyarankan penjelasan berikut:

Dalam ilmu komputer, operator ternary (kadang-kadang salah disebut operator tersier) adalah operator yang mengambil tiga argumen. Argumen dan hasil dapat dari berbagai jenis. Banyak bahasa pemrograman yang menggunakan sintaks mirip-C menampilkan operator ternary,?:, Yang mendefinisikan ekspresi kondisional.

Tidak hanya di Jawa, sintaks ini tersedia dalam PHP, Objective-C juga.

Di tautan berikut ini memberikan penjelasan berikut, yang cukup bagus untuk memahaminya:

Operator ternary adalah beberapa operasi yang beroperasi pada 3 input. Ini adalah jalan pintas untuk pernyataan if-else, dan juga dikenal sebagai operator bersyarat.

Dalam Perl / PHP berfungsi sebagai:
boolean_condition ? true_value : false_value

Dalam C / C ++ berfungsi sebagai:
logical expression ? action for true : action for false

Ini mungkin dapat dibaca untuk beberapa kondisi logis yang tidak terlalu rumit atau lebih baik menggunakan blok If-Else dengan kombinasi yang diinginkan dari logika kondisional.

Kita dapat menyederhanakan blok If-Else dengan operator ternary ini untuk satu baris pernyataan kode.
Sebagai contoh:

if ( car.isStarted() ) {
     car.goForward();
} else {
     car.startTheEngine();
}

Mungkin sama dengan yang berikut ini:

( car.isStarted() ) ? car.goForward() : car.startTheEngine();

Jadi, jika kami merujuk pada pernyataan Anda:

int count = isHere ? getHereCount(index) : getAwayCount(index);

Ini sebenarnya setara 100% dari blok If-Else berikut :

int count;
if (isHere) {
    count = getHereCount(index);
} else {
    count = getAwayCount(index);
}

Itu dia!
Semoga ini bisa membantu seseorang!
Bersulang!

Randika Vishman
sumber
2

Benar. Ini disebut dengan operator ternary . Beberapa juga menyebutnya operator bersyarat .

cletus
sumber
9
Mengutip Alice In Wonderland, itu disebut operator ternary, tetapi namanya adalah Operator Bersyarat.
Paul Tomblin
Namun nama itu disebut operator tanda tanya-tanda titik dua.
Michael Myers
1
Penamaan penamaan terdengar agak C ++ ish. Tanda tanya operator titik dua?: (Satu tanda) dikenal sebagai operator Elvis.
Tom Hawtin - tackline
2

Operator Ternary (? :)

The ternary operator is an operator that takes three arguments. The first 
argument is a comparison argument, the second is the result upon a true 
comparison, and the third is the result upon a false comparison.
Darsy
sumber
1

Anda mungkin tertarik pada proposal untuk beberapa operator baru yang mirip dengan operator bersyarat. Operator null-safe akan mengaktifkan kode seperti ini:

String s = mayBeNull?.toString() ?: "null";

Ini akan menjadi sangat nyaman di mana auto-unboxing terjadi.

Integer ival = ...;  // may be null
int i = ival ?: -1;  // no NPE from unboxing

Ini telah dipilih untuk dipertimbangkan lebih lanjut di bawah "Project Coin" JDK 7.

erickson
sumber
Operator itu bukan salah satu favorit saya dari Project Coin. Kegunaan terbatas, tidak intuitif untuk dibaca, dan sekadar jelek karena semua keluar. Mungkin itu akan tumbuh pada saya.
Michael Myers
Sebenarnya saya bukan penggemar berat. Ini adalah proposal Neal Gafter, dan ia cenderung melihat sesuatu yang sangat berbeda dari programmer Java pada umumnya, yang cenderung melihat sesuatu secara berbeda dari rata-rata manusia. Satu-satunya tempat yang mungkin saya suka sedikit bantuan dengan null adalah di loop foreach, menguji apakah iterable adalah null, dan auto-unboxing.
erickson
IIRC <Neal tidak mengusulkannya. Dia hanya menggunakannya sebagai contoh sederhana tentang cara menulis proposal. Rincian lebih lanjut tentang arsip milis proyek koin.
Tom Hawtin - tackline
Saya baru saja membaca pengantar proposal, dan Anda benar. Ini Stephen Colebourne dari Joda dan ketenaran "tidak ada Java 7".
erickson
1

Sebenarnya butuh lebih dari 3 argumen. Sebagai contoh jika kita ingin memeriksa apakah angka positif, negatif atau nol kita dapat melakukan ini:

String m= num > 0 ? "is a POSITIVE NUMBER.": num < 0 ?"is a NEGATIVE NUMBER." :"IT's ZERO.";

yang lebih baik daripada menggunakan if, else if, else.

Dipuji
sumber
0

Ini adalah operator bersyarat, dan ini lebih dari sekadar cara penulisan pernyataan singkat.

Karena itu adalah ekspresi yang mengembalikan nilai, itu dapat digunakan sebagai bagian dari ekspresi lainnya.

justinhj
sumber
0

Ya kamu benar. ?: biasanya disebut "operator kondisional ternary", sering disebut sebagai "operator ternary". Ini adalah versi singkat dari standar jika / jika kondisional.

Operator Bersyarat Ternary

Gary
sumber
0

Saya kebetulan sangat suka operator ini, tetapi pembaca harus dipertimbangkan.

Anda selalu harus menyeimbangkan kekompakan kode dengan waktu yang dihabiskan untuk membacanya, dan dalam hal ini memiliki beberapa kekurangan yang cukup parah.

Pertama-tama, ada kasus Penanya Asli. Dia hanya menghabiskan satu jam memposting tentang itu dan membaca tanggapan. Berapa lama lagi penulis akan menulis setiap:? Seandainya sepanjang masa hidupnya. Tidak satu jam untuk memastikan.

Kedua, dalam bahasa mirip-C, Anda terbiasa mengetahui bahwa conditional adalah hal pertama dalam barisan. Saya perhatikan ini ketika saya menggunakan Ruby dan menemukan garis-garis seperti:

callMethodWhatever(Long + Expression + with + syntax) if conditional

Jika saya sudah lama menjadi pengguna Ruby, saya mungkin tidak akan memiliki masalah dengan baris ini, tetapi berasal dari C, ketika Anda melihat "callMethodWh Apapun" sebagai hal pertama dalam baris tersebut, Anda berharap akan dieksekusi. The?: Kurang samar, tetapi masih cukup tidak biasa untuk membuang pembaca.

Keuntungannya, bagaimanapun, adalah perasaan yang sangat keren di perut Anda ketika Anda dapat menulis pernyataan 3-baris jika dalam 1 spasi. Tidak dapat menyangkal itu :) Tapi jujur, tidak selalu lebih mudah dibaca oleh 90% orang di luar sana hanya karena 'kelangkaannya.

Ketika itu benar-benar tugas yang didasarkan pada Boolean dan nilai-nilai saya tidak punya masalah dengan itu, tetapi dapat dengan mudah disalahgunakan.

Bill K.
sumber
0

Ekspresi bersyarat dalam gaya yang sama sekali berbeda, tanpa eksplisit jika dalam pernyataan.

Sintaksnya adalah: ekspresi boolean? ekspresi1: ekspresi2;

Hasil dari ekspresi kondisional ini adalah

ekspresi1 jika ekspresi boolean benar;

jika tidak hasilnya adalah ekspresi2.

Misalkan Anda ingin menetapkan jumlah variabel num1 dan num2 yang lebih besar ke maks. Anda cukup menulis pernyataan menggunakan ekspresi kondisional: max = (num1> num2)? num1: num2;

Catatan: Simbol? dan: tampil bersama dalam ekspresi kondisional. Mereka membentuk operator bersyarat dan juga disebut operator ternary karena menggunakan tiga operan. Ini adalah satu-satunya operator ternary di Jawa.

dikutip dari: Intro to Java Programming edisi ke-10 oleh Y. Daniel Liang halaman 126 - 127

Ged
sumber