Java'da "mantıksal özel" veya "operatör" oluşturma


274

Gözlemler:

Java'nın mantıksal bir AND operatörü vardır.
Java'nın mantıksal bir VEYA işleci vardır.
Java'nın mantıksal bir NOT işleci vardır.

Sorun:

Güneşe göre Java'nın mantıksal bir XOR operatörü yoktur . Bir tanesini tanımlamak istiyorum.

Yöntem Tanımı:

Bir yöntem olarak basitçe aşağıdaki gibi tanımlanır:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}


Yöntem Çağrısı:

Bu yöntem şu şekilde çağrılır:

boolean myVal = logicalXOR(x, y);


Operatör Kullanımı:

Daha çok, aşağıdaki gibi kullanılan bir operatör olmasını tercih ederim:

boolean myVal = x ^^ y;


Soru:

Java'da yeni bir operatör tanımlama konusunda nasıl bir şey bulamıyorum. Nereden başlamalıyım?


1
ne? verdiğiniz bağlantı 'bitwise exclusive OR' içeriğine sahip
Mathew P. Jones

o zaman C ++ gibi yapabileceğiniz gibi Java operatörleri tanımlamak merak ediyor muydunuz?
avgvstvs

1
& & && arasındaki farkı yanlış anladığınız anlaşılıyor. Her ikisi de mantıksal işleçlerdir (bir boole'de). Starblue'nun cevabı daha geniş kapsamaktadır.
Vlasec

sadece öğreticide olmadığı için Java'nın sahip olmadığı anlamına gelmez - öğreticiler (her zaman) tam değildir. Bkz. Java Dil Spesifikasyonu 15.22.2
user85421

5
Deniyor !=adında bir mantıksal XNOR da var,==
Mark K Cowan

Yanıtlar:


695

Java mantıksal bir XOR operatörüne sahiptir , ^ (olduğu gibi a ^ b).

Bunun dışında Java'da yeni işleçler tanımlayamazsınız.

Düzenleme: İşte bir örnek:

public static void main(String[] args) {
    boolean[] all = { false, true };
    for (boolean a : all) {
        for (boolean b: all) {
            boolean c = a ^ b;
            System.out.println(a + " ^ " + b + " = " + c);
        }
    }
}

Çıktı:

false ^ false = false
false ^ true = true
true ^ false = true
true ^ true = yanlış

5
Bu, yazımı yazdığımda da hafızamdan kaçtı, ancak bence ^ mantıklı bir operatör olarak (hem de bitsel olarak) kullanabilirsiniz.
Neil Coffey

144
^ sadece bitsel bir operatör değildir. Aynı zamanda mantıklı bir operatördür. ^ Operatörü aşırı yüklenmiş. İntegral tipler veya boolean tipler üzerinde çalışır. Harika bir cevap için +1 javashlook. Eddie, JLS Bölüm 15.22.2, "Boolean Logical Operators &, ^ ve |" dan daha açık olamaz.
erickson

97
Ve elbette, cevap şu && ve || ifadenin 2. bölümünü değerlendirmeyi atlayacak ve & ve | her zaman ifadenin her iki bölümünü de değerlendirecektir (JLS okumamdan). Bir ^ ^ her zaman her iki parçayı da tanımlamak zorundadır, dolayısıyla ^ ile aynı şekilde davranır. Muhtemelen neden yoktur ^^
Eddie

81
@Eddie: Bu ve ^^ sadece bir ifadeye çok benziyor.
Michael Myers

5
Belki bir anlambilim meselesidir, ancak XOR söz konusu olduğunda, bitsel ve mantıksal aynı sonucu verir. Bu nedenle, farklı operatörlere gerek yoktur. Bir XOR işleci için basitleştirilmiş doğruluk tablosu X ^! X = 1'dir. XOR'da bir girişi kısa devre yapamazsınız, çünkü girişlerin farklı olup olmadığını belirlemeniz gerekir. Gerçek XOR geçidinin imalatını biliyorsanız, bunu anlamak çok daha kolaydır.
hfontanez

305

X! = Y değil mi?


5
X ve y boolean ise, xor ve! = İçin mantık tablosu aynıdır: t, t => f; t, f => t; f, t => t; f, f => f
Greg Case

81
Maurice: Arrgh, sadece aklımı patlattın! Bunu nasıl hiç fark etmedim?

8
@Milhous a != b != cÇalışmayacağını, ama çalışamayacağını mı söylüyorsun a ^ b ^ c? Bu durumda yanılıyorsunuz .
fredoverflow

3
Maurice, sadece harika! Yapacak çok şey olduğunda basit şeyleri gözden kaybetmek bana oluyor :)
sberezin

6
Bu approch içe doğru patlar ve her iki tarafın da sarıcı sınıflar olduğunda, new Boolean(true) != new Boolean(true)verir true.
Vlastimil Ovčáčík

74

Java'nın mantıksal bir AND operatörü vardır.
Java'nın mantıksal bir VEYA işleci vardır.

Yanlış.

Java

  • iki mantıksal AND operatörü: normal AND & & kısa devre AND &&, ve
  • iki mantıksal OR operatörü: normal OR | ve kısa devre VEYA ||

XOR sadece ^ olarak mevcuttur, çünkü kısa devre değerlendirmesi mümkün değildir.


2
İlginç bir yorum. Bu belgelenmiş mi?
user666412

1
Bence & ve | kısa devre değildir, çünkü bunlar bitsel operatörlerdir. Ve aslında onları kısa devre yapmak mümkün değil.
Krzysztof Jabłoński

3
@Krzysztof Jabłoński Sayılarda bitsel operatörler, ancak burada boole ifadelerinden bahsediyoruz.
starblue

3
@ user666412 Evet, Java Dil Spesifikasyonunda (başka nerede?).
starblue

18
2 VE işleci ve 2 VEYA işleci varsa, 'Java'nın mantıksal bir VE işleci vardır' ve 'Java'nın mantıksal bir OR işleci vardır' ifadeleri yanlış değildir. Tanım olarak bir şey 2 varsa o zaman da 1 var.
RyanfaeScotland

31

Belki arasındaki farkı yanlış &ve &&, |ve || kısayol operatörleri amacı &&ve|| ikinci işlenen değerlendirilecek gerekmez böylece ilk görenin değeri sonucunu belirlemek ve olmasıdır.

Bu, özellikle ikinci işlenenin hataya neden olması durumunda kullanışlıdır. Örneğin

if (set == null || set.isEmpty())
// or
if (list != null && list.size() > 0)

Ancak XOR ile , sonucu elde etmek için her zaman ikinci işleneni değerlendirmeniz gerekir, böylece tek anlamlı işlem olur ^.


20

Sadece yazabilirsin (a!=b)

Bu, aynı şekilde çalışır a ^ b.


9

Çünkü operatör aşırı yüklenmesi, özellikle dilden kasıtlı olarak bıraktıkları bir şeydir. Dize birleştirme ile biraz "aldattılar", ancak bunun ötesinde, böyle bir işlevsellik mevcut değildir.

(feragatname: Java'nın son 2 büyük sürümünde çalışmadım, bu yüzden şimdi varsa, çok şaşıracağım)


5
C ++ 'da yeni işleçler tanımlayamayacağınızı unutmayın. Tek yapabileceğiniz eskilere yeni anlamlar vermek.
David Thornley

7

Java'da aşırı yükleme yapan tek operatör Dizelerdeki + ( JLS 15.18.1 Dize Birleştirme İşleci + ).

Topluluk yıllardır 3'e bölünmüş, 1/3 istemiyor, 1/3 istiyor ve 1/3 umursamıyor.

Sembol olan yöntem adları oluşturmak için unicode kullanabilirsiniz ... bu nedenle kullanmak istediğiniz bir sembolünüz varsa myVal = x. $ (Y); burada $ sembol ve x ilkel değil ... ama bazı editörlerde tehlikeli olacak ve ilkel üzerinde yapamayacağınız için sınırlayıcı olacak.


7

Aşağıdaki kod:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}

gereksizdir.

Neden yazmıyorsunuz:

public static boolean logicalXOR(boolean x, boolean y) {
    return x != y;
}

?

Ayrıca, javashlook'un dediği gibi , zaten var^ operatör var.

!= ve ^ boolean işlenenler (durumunuz) için aynı şekilde *, ancak tamsayı işlenenler için farklı şekilde çalışın.

* Notlar:
1. boolean(ilkel tip) için aynı şekilde çalışırlar , ancakBoolean (nesne tipi) işlenenler için . Olarak Boolean(nesne türü) değerleri değere sahip olabilir null. Ve !=dönecek falseya trueda işlenenlerinden biri veya her ikisi de olduğunda null, bu durumda ^atılacaktır NullPointerException.
Bunlar aynı şekilde çalışacaktır, ancak kullanıldığında 2., bunlar örneğin farklı önceliğe sahiptir &: a & b != c & dolarak kabul edilecek a & (b != c) & dise, a & b ^ c & dolarak kabul edilecektir (a & b) ^ (c & d)(: AH, C gibi bir öncelik tablosu emmek offtopic).


1
Sevdiğim Boole değerleri için!=
GKalnytskyi

1
@GKalnytskyi Booleandeğerleri !=yanlış çalışıyor. İçin booleandeğerler tamam.
vadipp

2
! = ve ^ , boole işlenenleri için aynı şekilde çalışmaz . Öncelik nedeniyle "false & false! = True" ile "false & false ^ true" için farklı sonuçlar alırsınız.
Albert Hendriks

1
@AlbertHendriks, daha iyi onlar söyleyebilirim işe aynı ancak farklı olması önceliklidir (Bu terminolojinin meselesi olsa da).
Sasha

6

Java için var arg XOR yöntemi İşte ...

public static boolean XOR(boolean... args) {
  boolean r = false;
  for (boolean b : args) {
    r = r ^ b;
  }
  return r;
}

Zevk almak


Bu çok garip bir davranış sergileyecek gibi geliyor. Örn. XOR(true,true,true)Doğru döndürür, bu çağrılan bir yöntemden beklediğiniz gibi görünmemektedir XOR. Beklediğim davranış her zaman yanlış döndürür (ki elbette yardımcı olmaz)
Richard Tingle

5

Mantıksal münhasır- veya Java'da çağrılır !=. ^Arkadaşlarınızı karıştırmak istiyorsanız da kullanabilirsiniz .


2

Sen kullanabilirsiniz xtend (telkin Operatörleri ve operatörler) aşırı yük operatörleri ve Java üzerinde 'kalmak' için


Xtend'in düzeltme kodunu geçersiz kılmanıza izin vermediğini unutmayın ^; kullanmalısın bool_1.xor(bool_2). İşin garibi, ayrıştırıcı , şapka kullanmanıza bile izin vermiyor ; xorboolean'lar ve bitwiseXortamsayılar için kullanmalısınız . Elbette, başka bir operatörü aşırı yükleyebilirsiniz, ancak bu çok kafa karıştırıcı olacaktır.
Kelvin

2

Sorduğun şey pek mantıklı değil. Yanlış olmadıkça, Mantıksal işlemleri AND ve VEYA gibi yapmak için XOR kullanmanızı öneririz. Sağladığınız kod aslında neye başvurduğumu gösteriyor:

public static boolean logicalXOR(boolean x, boolean y) {
    return ( ( x || y ) && ! ( x && y ) );
}

İşlevinizin boole girişleri vardır ve boolelarda bit olarak XOR kullanıldığında sonuç sağladığınız kodla aynı olur. Başka bir deyişle, bitsel XOR, tek tek bitleri (booleans) karşılaştırırken veya tek tek bitleri daha büyük değerlerle karşılaştırırken zaten etkilidir. Bunu bağlama koymak için, ikili değerler açısından sıfır olmayan herhangi bir değer DOĞRU ve yalnızca SIFIR yanlıştır.

Bu nedenle XOR'un Mantıksal AND'in uygulandığı şekilde uygulanması için, yalnızca bir bitli (aynı sonucu ve verimliliği veren) ikili değerleri kullanırsınız veya ikili değerin bit yerine bir bütün olarak değerlendirilmesi gerekir. Başka bir deyişle, (010 ^^ 110) = 100 yerine (010 ^^ 110) = FALSE ifadesi. Bu, anlamsal anlamın çoğunu işlemden kaldıracak ve yine de kullanmamanız gereken mantıksal bir testi temsil edecektir.


1

A ve B, doğruluk tablosunun aynı görünmesi için! = Xor ile aynı olması için boole değerleri olmalıdır. ! (A == B) lol da kullanabilirsiniz.


1

Çok popüler sınıfı kullanıyorum "org.apache.commons.lang.BooleanUtils"

Bu yöntem birçok kullanıcı tarafından test edilmiştir ve güvenlidir. İyi eğlenceler. Kullanımı:

boolean result =BooleanUtils.xor(new boolean[]{true,false});

0

Boole veri türü bir tamsayı gibi saklandığından, bit operatörü ^ boole değerleriyle birlikte kullanılırsa XOR işlemi gibi işlev görür.

//©Mfpl - XOR_Test.java

    public class XOR_Test {
        public static void main (String args[]) {
            boolean a,b;

            a=false; b=false;
            System.out.println("a=false; b=false;  ->  " + (a^b));

            a=false; b=true;
            System.out.println("a=false; b=true;  ->  " + (a^b));

            a=true;  b=false;
            System.out.println("a=true;  b=false;  ->  " + (a^b));

            a=true; b=true;
            System.out.println("a=true; b=true;  ->  " + (a^b));

            /*  output of this program:
                    a=false; b=false;  ->  false
                    a=false; b=true;  ->  true
                    a=true;  b=false;  ->  true
                    a=true; b=true;  ->  false
            */
        }
    }

0

İşte bir örnek:

2 int değeri verildiğinde, biri negatifse diğeri pozitifse true değerini döndürün. "Negatif" parametresi doğru değilse, yalnızca her ikisi de negatifse true değerini döndürün.

    public boolean posNeg(int a, int b, boolean negative) {
      if(!negative){
        return (a>0 && b<0)^(b>0 && a<0);
      }
      else return (a<0 && b<0);
    }

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.