Creazione di un operatore "logico esclusivo o" in Java


274

osservazioni:

Java ha un operatore logico AND.
Java ha un operatore logico OR.
Java ha un operatore NOT logico.

Problema:

Java ha nessun operatore XOR logico, in base a Sun . Vorrei definirne uno.

Definizione del metodo:

Come metodo è semplicemente definito come segue:

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


Metodo di chiamata:

Questo metodo viene chiamato nel modo seguente:

boolean myVal = logicalXOR(x, y);


Utilizzo dell'operatore:

Preferirei piuttosto avere un operatore, usato come segue:

boolean myVal = x ^^ y;


Domanda:

Non riesco a trovare nulla su come definire un nuovo operatore in Java. Dove dovrei iniziare?


1
che cosa? il link che hai fornito ha il contenuto 'OR bit a bit esclusivo'
Mathew P. Jones

ti chiedevi allora se potevi definire operatori in Java come puoi in C ++?
avgvstvs,

1
Sembra che tu abbia frainteso la differenza tra & e &&. Entrambi sono operatori logici (su un valore booleano). La risposta di Starblue la copre in modo più ampio.
Vlasec,

solo perché non è nel tutorial , non significa che Java non ce l'abbia - i tutorial non sono (sempre) completi. Vedi le specifiche del linguaggio Java 15.22.2
user85421

5
Si chiama !=, c'è anche un XNOR logico chiamato==
Mark K Cowan,

Risposte:


695

Java ha un operatore XOR logico , è ^ (come in a ^ b).

A parte questo, non è possibile definire nuovi operatori in Java.

Modifica: ecco un esempio:

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);
        }
    }
}

Produzione:

false ^ false = false
false ^ true = true
true ^ false = true
true ^ true = false

5
Questo è sfuggito alla mia memoria anche quando ho scritto il mio post, ma penso che PUOI usare ^ come operatore logico (oltre che bit a bit).
Neil Coffey,

144
^ non è solo un operatore bit a bit. È anche un operatore logico. L'operatore ^ è sovraccarico. Funziona su tipi integrali o tipi booleani. +1 per un'ottima risposta javashlook. Eddie, non diventa più esplicito di JLS Sezione 15.22.2, "Operatori logici booleani &, ^ e |".
Erickson,

97
E, naturalmente, la risposta è che && e || salterà la valutazione della seconda parte dell'espressione e & e | valuterò sempre entrambe le parti dell'espressione (dalla mia lettura di JLS). A ^^ dovrebbe sempre valutare entrambe le parti, per definizione, quindi si comporta in modo identico a ^. Probabilmente perché non c'è ^^
Eddie,

81
@Eddie: Quello e ^^ sembra troppo un emoticon.
Michael Myers

5
Forse è una questione di semantica, ma quando si tratta di XOR, bit a bit e logici producono lo stesso risultato. Pertanto, non sono necessari operatori distinti. La tabella di verità semplificata per un operatore XOR è X ^! X = 1. Non è possibile cortocircuitare un ingresso in XOR perché è necessario determinare se gli ingressi sono diversi. È molto più facile da capire se si conosce la fabbricazione dell'attuale gate XOR.
hfontanez,

305

Non è x! = Y?


5
Se xey sono booleani, la tabella logica per xor e! = Sono identici: t, t => f; t, f => t; f, t => t; f, f => f
Greg Case,

81
Maurice: Arrgh, mi hai fatto impazzire! Come non l'ho mai notato?

8
@Milhous Stai dicendo a != b != cche non funzionerà, ma lo a ^ b ^ cfarà? In tal caso, ti sbagli .
Fredoverflow

3
Maurizio, semplicemente geniale! Mi capita di perdere cose semplici alla vista quando c'è molto da fare :)
sberezin

6
Questo approccio implode quando entrambe le parti sono classi wrapper, new Boolean(true) != new Boolean(true)true.
Vlastimil Ovčáčík,

74

Java ha un operatore logico AND.
Java ha un operatore logico OR.

Sbagliato.

Java ha

  • due operatori logici AND: AND normale è & e il corto circuito AND è &&, e
  • due operatori OR logici: OR normale è | e il corto circuito OR è ||.

XOR esiste solo come ^, perché la valutazione del corto circuito non è possibile.


2
Commento interessante. È documentato?
user666412

1
Penso & e | non sono in corto circuito perché sono operatori bit per bit. E infatti non è possibile cortocircuitarli.
Krzysztof Jabłoński

3
@Krzysztof Jabłoński Sono operatori bit per bit sui numeri, ma qui stiamo parlando di espressioni booleane.
Starblue,

3
@ user666412 Sì, nelle specifiche del linguaggio Java (dove altro?).
Starblue,

18
Se ha 2 operatori AND e 2 operatori OR, le istruzioni "Java ha un operatore AND logico" e "Java ha un operatore OR logico" non sono sbagliate. Per definizione, se hai 2 di qualcosa, ne hai anche 1.
Ryanfae Scozia

31

Forse hai frainteso la differenza tra &e &&, |e || Lo scopo degli operatori di scelta rapida &&ed ||è che il valore del primo operando può determinare il risultato e quindi non è necessario valutare il secondo operando.

Ciò è particolarmente utile se il secondo operando comporterebbe un errore. per esempio

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

Tuttavia, con XOR , devi sempre valutare il secondo operando per ottenere il risultato, quindi l'unica operazione significativa è^ .


20

Puoi semplicemente scrivere (a!=b)

Funzionerebbe allo stesso modo di a ^ b.


9

Questo perché il sovraccarico dell'operatore è qualcosa che hanno deliberatamente lasciato fuori dalla lingua. Hanno "imbrogliato" un po 'con concatenazione di stringhe, ma oltre a ciò, tale funzionalità non esiste.

(dichiarazione di non responsabilità: non ho lavorato con le ultime 2 versioni principali di Java, quindi se è ora, rimarrò molto sorpreso)


5
Ricordare che non è possibile definire nemmeno nuovi operatori in C ++. Tutto quello che puoi fare è dare nuovi significati a quelli vecchi.
David Thornley,

7

L'unico sovraccarico dell'operatore in Java è + on Strings ( JLS 15.18.1 String Concatenation Operator + ).

La community è stata divisa in 3 per anni, 1/3 non la vuole, 1/3 la vuole e 1/3 non se ne cura.

Puoi usare unicode per creare nomi di metodi che sono simboli ... quindi se hai un simbolo che vuoi usare puoi fare myVal = x. $ (Y); dove $ è il simbolo e x non è una primitiva ... ma sarà un po 'complicato in alcuni editor e sarà un limite dato che non puoi farlo su una primitiva.


7

Il seguente codice:

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

è superfluo.

Perché non scrivere:

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

?

Inoltre, come diceva javashlook , esiste già^ operatore.

!=e ^funziona in modo identico * per operandi booleani (il tuo caso), ma in modo diverso per operandi interi.

* Note:
1. Funzionano in modo identico per operandi boolean(tipo primitivo), ma non Boolean(tipo oggetto). Come Boolean(tipo di oggetto) i valori possono avere valore null. E !=tornerà falseo truequando uno o entrambi i suoi operandi lo sono null, mentre in questo caso ^verrà generato NullPointerException.
2. Sebbene funzionino in modo identico, hanno una precedenza diversa, ad es. Se utilizzati con &: a & b != c & dsaranno trattati come a & (b != c) & d, mentre a & b ^ c & dsaranno trattati come (a & b) ^ (c & d)(offtopic: ahi, la tabella di priorità in stile C fa schifo).


1
Mi piacciono i valori booleani!=
GKalnytskyi,

1
@GKalnytskyi per i Booleanvalori !=funziona in modo errato. Per i booleanvalori va bene.
vadipp,

2
! = e ^ non funzionano in modo identico per gli operandi booleani. Otterrai risultati diversi per "false & false! = True" rispetto a "false & false ^ true" a causa della precedenza.
Albert Hendriks il

1
@AlbertHendriks, direi che funzionano in modo identico, ma hanno una precedenza diversa (anche se è solo una questione di terminologia).
Sasha,

6

Ecco un metodo XOR var arg per java ...

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

Godere


Sembra che abbia un comportamento molto strano. Ad esempio, XOR(true,true,true)restituisce true, che non sembra quello che ti aspetteresti da un metodo chiamato XOR. Il mio comportamento previsto sarebbe che ritorni sempre falso (il che ovviamente non è utile)
Richard Tingle,

5

Viene chiamato esclusivo logico o in Java !=. Puoi anche usarlo ^se vuoi confondere i tuoi amici.


2

È possibile utilizzare Xtend (Operatori Infix e Sovraccarico operatore) per sovraccaricare gli operatori e 'rimanere' su Java


Nota che Xtend non ti consente di ignorare il cursore ^; devi usare bool_1.xor(bool_2). Stranamente, il parser non ti consente nemmeno di usare il cursore; devi usare xorper i booleani e bitwiseXorper i numeri interi. Ovviamente potresti sovraccaricare un altro operatore, ma questo sarebbe molto confuso.
Kelvin,

2

Quello che stai chiedendo non avrebbe molto senso. A meno che non sia sbagliato, stai suggerendo di voler utilizzare XOR per eseguire le operazioni logiche allo stesso modo di AND e OR. Il codice fornito in realtà mostra ciò a cui mi riferisco:

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

La tua funzione ha input booleani e quando XOR bit a bit viene usato su booleani il risultato è lo stesso del codice che hai fornito. In altre parole, XOR bit a bit è già efficace quando si confrontano singoli bit (booleani) o si confrontano i singoli bit in valori più grandi. Per metterlo nel contesto, in termini di valori binari qualsiasi valore diverso da zero è VERO e solo ZERO è falso.

Quindi, per XOR essere applicato nello stesso modo in cui viene applicato Logical AND, si utilizzerebbero solo i valori binari con un solo bit (fornendo lo stesso risultato ed efficienza) oppure il valore binario dovrebbe essere valutato nel suo complesso anziché per bit. In altre parole, l'espressione (010 ^^ 110) = FALSE anziché (010 ^^ 110) = 100. Ciò eliminerebbe la maggior parte del significato semantico dall'operazione e rappresenta un test logico che non dovresti usare comunque.


1

A e B dovrebbero essere valori booleani da creare! = Uguale a xor in modo che la tabella di verità sia uguale. Puoi anche usare! (A == B) lol.


1

Sto usando la classe molto popolare "org.apache.commons.lang.BooleanUtils"

Questo metodo è testato da molti utenti e sicuro. Divertiti. Uso:

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

0

Poiché il tipo di dati booleano è memorizzato come un numero intero, l'operatore di bit ^ funziona come un'operazione XOR se utilizzato con valori booleani.

//©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

Ecco un esempio:

Dati 2 valori int, restituisce vero se uno è negativo e uno è positivo. Tranne se il parametro "negativo" è vero, quindi restituisce vero solo se entrambi sono negativi.

    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);
    }

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.