Java?: Operatörü nedir ve ne işe yarar?


161

Java ile birkaç yıldır çalışıyorum, ancak yakın zamana kadar bu yapı üzerinde çalışmadım:

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

Bu muhtemelen çok basit bir soru, ama birisi bunu açıklayabilir mi? Nasıl okurum? Nasıl çalıştığını bildiğimden eminim.

  • eğer isHeredoğruysa, getHereCount()denir,
  • eğer isHereyanlış getAwayCount()denir.

Doğru? Bu yapıya ne denir?


2
Ayrıca bu sorunun C ++ sürümü için stackoverflow.com/questions/795286/what-does-do-in-c adresine bakın (sadece dün sorulmuştur).
Michael Myers

2
C / C ++ / Java dünyasının oldukça çirkin ve kafa karıştırıcı olduğunu düşünen ve veba gibi önleyecek insanlar arasında ve C onu tanıyamaz ve düşünmek için duraklamadan kullanamaz.
Paul Tomblin

3
Java'da genellikle en açık ve en basit durumların ötesinde kullanılması kötü bir form olarak kabul edilir. Kendinizi iç içe bulursanız, dışarı çıkmış olursunuz. Öte yandan, hızlı ve akıllı kodun netliğin üzerinde değerlendiği C kültüründe kabul edilebilir olarak kabul edilir.
Yishai

17
answer_to_question = (tanıma_operatörü)? (social_acceptance): (condescending_finger_wag)
Dan

Daha fazla bilgi için bu kaynağa başvurabilirsiniz .
Shiva

Yanıtlar:


189

Evet, kısayol

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

Buna koşullu operatör denir . Birçok kişi (hatalı olarak) üçlü operatör olarak adlandırır , çünkü Java, C, C ++ ve muhtemelen diğer birçok dilde tek üçlü (üç argüman) operatördür. Ama teorik olarak var olabilir sadece bir tane olabilir oysa başka Üçlü operatör olmak koşullu operatör .

Resmi ad Java Dil Spesifikasyonunda verilmiştir :

§15.25 Koşullu Operatör? :

Koşullu işleç ? :, diğer iki ifadeden hangisinin değerlendirileceğine karar vermek için bir ifadenin boole değerini kullanır.

Her iki dalın da dönüş değerlerine sahip yöntemlere yönlendirmesi gerektiğini unutmayın:

İkinci veya üçüncü işlenen ifadenin, bir geçersiz yöntemin çağrılması bir derleme zamanı hatasıdır.

Aslında, ifade ifadelerinin dilbilgisi ( §14.8 ) ile, bir koşullu ifadenin, bir geçersiz yöntemin çağrıldığı herhangi bir bağlamda görünmesine izin verilmez.

Yani, doSomething()ve doSomethingElse()geçersiz yöntemler ise, bunu sıkıştıramazsınız:

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

bunun içine:

someBool ? doSomething() : doSomethingElse();

Basit kelimeler:

booleanCondition ? executeThisPartIfBooleanConditionIsTrue : executeThisPartIfBooleanConditionIsFalse 

En altta ne yaptığını anlamıyorum yanlış. Sana ve hepsine inanıyorum. Sadece orijinaliyle aynı görünüyor. Bunun nedeni, yalnızca bir değer döndürüp döndürmeyebilecek ve bir sonraki kod kümesinin çalışmasına izin verebilecek başka bir işlevi çağırmaları mıdır?
johnny

8
DoSomething () ve doSomethingElse () geçersiz yöntemler olduğunu varsayıyorum. Spesifikasyonun son bitinin söylediği, üçlü operatörün bir değer döndürmesi gerektiğidir , bu nedenle işlenenlerin hiçbiri geçersiz yöntemler olamaz.
Michael Myers

Bundan biraz daha fazlasını söylüyor. Bir koşullu operatörün COULD görünmesi durumunda koşullu operatöre izin verilmediğini söylüyor. Örneğin, aşağıdaki ifadeler: VALID: String x = (false)? "X": "Y"; GEÇERLİ DEĞİL: (yanlış)? "X": "Y";
kenj0418

4
Gelecekte başka cumhurbaşkanlarının olması mümkün olsa da, Obama'ya "Başkan" olarak atıfta bulunmak gibi hatalı olmadığı için (2016'da) "üçlü operatör" olarak adlandırmak yanlış değildir.
Dawood ibn Kareem

2
@DawoodibnKareem Bence Michael kasten italikleştirmeye dahil theedildi the ternary operatorve bu demek oluyor ki hatalı, hatalı değil ternary operator. Üçlü operatör Michael söylediği gibi, bu sırayla hatalı olanı Michael söylediğini olan başka üçlü operatörler, olabilir varsaymak birini neden olabilecek, sadece biridir ve ben kabul ediyorum, ima, bu olur olmak hatalı bir varsayım.
Ghoti ve Cipsler

32

Diğerleri buna makul ölçüde cevap verdiler, ancak genellikle "üçlü operatör" adıyla cevap verdiler.

Sahip olduğum bilgiç olarak, operatörün adının koşullu operatör veya "koşullu operatör?:" Olduğunu açıkça belirtmek isterim. Bu bir üçlü operatörü (üç işlenen alır o) ve o anda Java sadece üçlü operatör olur.

Bununla birlikte, spesifikasyon, isminin koşullu operatör veya "koşullu operatör?:" Olduğu konusunda açık ve nettir . Sanırım bu isimle çağırmak daha açıktır, çünkü operatörün davranışını kaç tane işlenenden ziyade bir dereceye kadar (bir durumu değerlendirmek) gösterir.


3
Bu cevap teknik olarak doğrudur. Ancak, yalnızca bir üçlü operatör olduğundan, genellikle üçlü operatör olarak adlandırıldığını görürsünüz. Bu ad, operatörün tam anlamını yansıtmasa da, sıkışmış bir addır. "Üçlü operatör" isminden bahsederseniz, programcılar neden bahsettiğinizi bilirler. Bahsettiğiniz özellik aynı zamanda bu operatöre daha bilgilendirici görünen "Üçlü Koşullu" olarak da değinmektedir. java.sun.com/docs/books/jls/third_edition/html/…
Gary

17
Ben sadece tanımlanmış ismiyle bir şey demeye değer. Özellikle, Java başka bir üçlü operatör alırsa, "koşullu operatör" terimini kullanan kişiler, sadece "üçlü operatör" diyenlerin aksine, hala doğru ve açık olacaktır. Evet, "üçlü operatör" ifadesi takıldı - cevabım, "nesneler referansla geçti" iddiasını düzeltmeye çalıştığım gibi, "çözme" çabasının bir parçası.
Jon Skeet

1
Sizi Oracle'dan üç "koşullu işleç", yalnızca bir "üçlü operatör" den söz eden bu sayfaya yönlendirebilir miyim ? Hangi operatörü kastettiğinizi netleştirmek istiyorsanız, çoğu insanın kullandığı adı kullanmak daha iyidir. (Evet, ben ev sahibi bulaşıkları son yıkıyor gibi partide görünüyorum biliyorum).
Dawood ibn Kareem

@DavidWallace: "Koşullu işleç?:" Kullanmak daha iyidir, IMO - bunu netleştirmek için düzenleyecektir. Ancak, davranışları ile ilgisi olmayan bir yönüne (kaç operandı var) odaklanmak yerine insanları operatörün gerçek adını kullanmaya ikna etmeye değer olduğunu düşünüyorum. (Ayrıca &&, koşullu ve işleci ve ||koşullu veya işleci çağıran , ancak "koşullu işleci" kullanan belirtimden daha az kesin olmak için öğreticiler için nadir değildir ?:.
Jon Skeet

Bilmiyorum. Birisi bana "koşullu operatör" diyorsa, ne anlama geldiğinden emin olamayacağım. Nereden geldiğim (dünyanın karşıt ucu sizden) insanlar buna böyle demiyorlar. "Üçlü operatör" veya "kanca operatörü" derlerse anlıyorum. İnsanların konuşma şeklini değiştirmek isteyen tutkunuza hayran kaldım. Eğer biri yapabilirse, o sensin. Ama ne fazla ümit vermiyorum ne de anlam ifade ediyorum.
Dawood ibn Kareem

17

Göre Sun Java Şartname , bu Koşullu Operatör denir. Bkz. Bölüm 15.25. Ne yaptığı konusunda haklısın.

Koşullu operatör? : diğer iki ifadeden hangisinin değerlendirileceğine karar vermek için bir ifadenin boole değerini kullanır.

Koşullu işleç sözdizimsel olarak sağ çağrışımsaldır (sağdan sola gruplar), böylece a? B: c? D: e? F: g? B: (c? D: (e? F) ile aynı anlama gelir : g)).

ConditionalExpression:
        ConditionalOrExpression
        ConditionalOrExpression ? Expression : ConditionalExpression

Koşullu işleç üç işlenen ifadesine sahiptir; ? birinci ve ikinci ifadeler arasında ve: ikinci ve üçüncü ifadeler arasında görünür.

İlk ifade boolean veya Boolean türünde olmalıdır veya bir derleme zamanı hatası oluşur.


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

anlamına geliyor :

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

5

Tam olarak doğru değil, kesin olmak gerekirse:

  1. isHere true olursa , getHereCount () sonucu döndürülür
  2. Diğer : getAwayCount () sonucu döndürülür

Bu "geri döndü" çok önemlidir. Bu yöntemler demektir gerekir bir değer döndürmek ve bu değer olmalıdır yerde atanabilir.

Ayrıca, if-else sürümüyle tam olarak sözdizimsel olarak eşdeğer değildir . Örneğin:

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

İf-else ile kodlanırsa, her zaman daha fazla bayt kodu ile sonuçlanır.


Javac'ın aynı bayt kodunu oluşturmak için özgür olduğuna inanıyorum. Her ne kadar doğru olsanız da, eşdeğer olmayan karanlık köşe vakaları vardır.
Tom Hawtin - tackline

Evet tabi ki. Benim için, koşullu operatörün gerçek değeri verdiğim örnektir. Alternatif: // gasp !! String temp = str1; eğer (kontrol) sıcaklık + = str2; başka sıcaklık + = str3; temp + = str4; dönüş sıcaklığı; veya StringBuilder ekleme işlemini elle kodlama. Birincisi ciddi verimlilik sorunu yaşıyor, ikincisi ise çok ayrıntılı ve fazla kazanç olmadan özenli bir çaba.
RichN

4

Üçlü, koşullu; domates, domates. Bunun için gerçekten değerli olan şey değişken başlatmadır. (Benim gibi) değişkenleri tanımlandıkları yerde başlatmaktan hoşlanıyorsanız, koşullu üçlü operatör (her ikisi için de), değeri hakkında koşulluluk olduğu durumlarda bunu yapmanıza izin verir. Nihai alanlarda özellikle dikkat çekicidir, ancak başka yerlerde de yararlıdır.

Örneğin:

public class Foo {
    final double    value;

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

Bu operatör olmadan - hangi adla olursa olsun - alanı sonlandırmamalı veya sadece başlatmak için bir işlev yazmalısınız. Aslında, bu doğru değil - yine de en azından Java'da if / else kullanılarak başlatılabilir. Ama bunu daha temiz buluyorum.



3

Bu yapıya Bilgisayar Bilimi ve Programlama tekniklerinde Üçlü Operatör denir .
Ve Wikipedia aşağıdaki açıklamayı önerir:

Bilgisayar biliminde, üçlü bir operatör (bazen yanlış bir üçüncül operatör olarak adlandırılır) üç argüman alan bir operatördür. Argümanlar ve sonuç farklı tiplerde olabilir. C benzeri sözdizimi kullanan birçok programlama dili, koşullu bir ifadeyi tanımlayan üçlü bir işleç,?: İçerir.

Sadece Java'da değil, bu sözdizimi PHP, Objective-C içinde de mevcuttur.

Aşağıdaki bağlantıda, bunu anlamak için sessiz olan aşağıdaki açıklamayı verir:

Üçlü operatör, 3 girişte çalışan bir işlemdir. İf-else ifadesi için bir kısayoldur ve koşullu işleç olarak da bilinir.

Perl / PHP'de şu şekilde çalışır:
boolean_condition ? true_value : false_value

C / C ++ 'da şu şekilde çalışır:
logical expression ? action for true : action for false

Bu, çok karmaşık olmayan bazı mantıksal koşullar için okunabilir olabilir, aksi takdirde , koşullu mantığın kombinasyonuyla If-Else bloğunu kullanmak daha iyidir .

If-Else bloklarını bu Ternary işleci ile bir kod deyimi satırı için basitleştirebiliriz .
Örneğin:

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

Aşağıdakilere eşit olabilir:

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

Yani ifadenize başvurursak:

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

Aslında aşağıdaki If-Else bloğunun % 100 eşdeğeri :

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

Bu kadar!
Umarım bu birine yardımcı olmuştur!
Şerefe!


2

Doğru. Bu oluyor adlandırılan üçlü operatör . Bazıları buna koşullu operatör de diyor .


9
Alice Harikalar Diyarında'ndan alıntı yapmak için üçlü operatör olarak adlandırılır, ancak adı Koşullu Operatördür.
Paul Tomblin

Ancak adı soru işareti kolon operatörü olarak adlandırılır.
Michael Myers

1
Adlandırma adlandırma sesi biraz C ++ ish. Soru işareti iki nokta üst üste operatörü?: (Bir jeton) Elvis operatörü olarak bilinir.
Tom Hawtin - tackline

2

Üçlü Operatörü (? :)

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.

1

Koşullu operatöre benzer bazı yeni operatörler için bir teklifle ilgilenebilirsiniz . Geçersiz güvenlik operatörleri aşağıdaki gibi kodları etkinleştirir:

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

Otomatik kutu açma işleminin gerçekleştiği yerlerde özellikle kullanışlıdır.

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

JDK 7'nin "Project Coin" başlığı altında daha ayrıntılı değerlendirilmek üzere seçilmiştir .


Bu operatör Project Coin'teki favorilerimden biri değil. Sınırlı kullanışlılık, okunması sezgisel değil ve sadece tüm çıkışlar gibi çirkin. Belki de üzerimde büyüyecekti.
Michael Myers

Ben de büyük bir hayran değilim. Bu bir Neal Gafter önerisi ve şeyleri ortalama insanınızdan farklı görme eğilimi gösteren ortalama Java programlayıcınızdan çok farklı görme eğilimindedir. Nulls ile biraz yardım isteyebileceğim tek yer, foreach döngüsünde, yinelenebilir boş olup olmadığını sınama ve otomatik kutu açma.
erickson

IIRC <Neal önermedi. Bunu sadece bir teklifin nasıl yazıldığına dair basit bir örnek olarak kullandı. Proje para posta listesi arşivi hakkında daha fazla bilgi.
Tom Hawtin - tackline

Teklifin girişini okudum ve haklısın. Joda'dan Stephen Colebourne ve "Java 7 yok" ünü.
erickson

1

Aslında 3'ten fazla argüman alabilir. Örneğin, bir sayının pozitif, negatif veya sıfır olup olmadığını kontrol etmek istiyorsak, bunu yapabiliriz:

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

hangisi if, else if, else kullanmaktan daha iyidir.


0

Koşullu operatördür ve if deyimlerinin yazılmasının sadece kısa bir yoludur.

Bir değer döndüren bir ifade olduğundan, diğer ifadelerin bir parçası olarak kullanılabilir.


0

Evet haklısın. ?: tipik olarak "üçlü koşullu operatör" olarak adlandırılır ve genellikle basitçe "üçlü operatör" olarak adlandırılır. Koşullu if / else koşulunun kısaltılmış halidir.

Üçlü Koşullu Operatör


0

Bu operatörü gerçekten çok beğendim, ancak okuyucu dikkate alınmalıdır.

Kod kompaktlığı her zaman onu okumak için harcanan zamanla dengelenmelidir ve bazı oldukça ciddi kusurları vardır.

Her şeyden önce, Orijinal Asker'in davası var. Sadece bir saatini yayınlayarak ve cevapları okuyarak geçirdi. Yazarın her şeyi yazması ne kadar sürdü?: Tüm hayatı boyunca bir if / then olarak. Emin olmak için bir saat değil.

İkincisi, C benzeri dillerde, koşulların satırdaki ilk şey olduğunu basitçe bilme alışkanlığı kazanırsınız. Ruby'yi kullanırken bunu fark ettim ve şöyle çizgilerle karşılaştım:

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

Eğer uzun zamandır Ruby kullanıcısı olsaydım, muhtemelen bu hatla bir sorunum olmazdı, ancak C'den geliyor, "callMethodWhatever" i satırdaki ilk şey olarak gördüğünüzde, yürütülmesini bekliyorsunuz. ?: Daha az şifreli, ama yine de bir okuyucuyu atacak kadar sıra dışı.

Bununla birlikte, avantaj, çizgilerin 1 boşluğunda 3 satırlık bir if ifadesi yazabildiğinizde karnınızda gerçekten harika bir duygu. Bunu inkar edemem :) Ama dürüst olmak gerekirse, sadece nadir olması nedeniyle orada insanların% 90'ı tarafından daha okunabilir olması gerekmez.

Gerçekten bir Boole ve değerlere dayalı bir ödev olduğunda, onunla bir sorunum yok, ancak kolayca kötüye kullanılabilir.


0

Koşullu ifadeler tamamen farklı bir stildir ve ifadede açık bir ifade yoktur.

Sözdizimi: boolean-expression? ifade1: ifade2;

Bu koşullu ifadenin sonucu şudur:

boole ifadesi doğruysa ifade1;

aksi takdirde sonuç ifade2'dir.

Daha fazla sayıda num1 ve num2 değişkenini maksimuma atamak istediğinizi varsayalım. Koşullu ifadeyi kullanarak bir ifade yazabilirsiniz: max = (num1> num2)? num1: num2;

Not: Semboller? ve: şartlı ifadede birlikte görünür. Koşullu bir işleç oluştururlar ve üçlü işlenen kullandıkları için üçlü işleç olarak da adlandırılırlar. Java'daki tek üçlü operatördür.

alıntı:: Y. Daniel Liang tarafından Java Programlama 10. basımına giriş sayfa 126 - 127

Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.