java - para - swing containers
¿Por qué usualmente usamos `||` no `|`, cuál es la diferencia? (27)
Me pregunto por qué usamos normalmente OR lógico ||
entre dos booleanos no en modo bit o |
, aunque ambos están funcionando bien.
Quiero decir, mira lo siguiente:
if(true | true) // pass
if(true | false) // pass
if(false | true) // pass
if(false | false) // no pass
if(true || true) // pass
if(true || false) // pass
if(false || true) // pass
if(false || false) // no pass
Podemos usar |
en lugar de ||
? Lo mismo con &
y &&
.
1). (Expresión1 | expresión2), | el operador evaluará expresión2 independientemente de si el resultado de expresión1 es verdadero o falso.
Ejemplo:
class Or
{
public static void main(String[] args)
{
boolean b=true;
if (b | test());
}
static boolean test()
{
System.out.println("No short circuit!");
return false;
}
}
2). (Expresión1 || expresión2), || el operador no evaluará expresión2 si expresión1 es verdadera.
Ejemplo:
class Or
{
public static void main(String[] args)
{
boolean b=true;
if (b || test())
{
System.out.println("short circuit!");
}
}
static boolean test()
{
System.out.println("No short circuit!");
return false;
}
}
Además del cortocircuito, otra cosa a tener en cuenta es que realizar una operación lógica a nivel de bits en valores que pueden ser distintos de 0 o 1 tiene un significado muy diferente al de la lógica condicional. Si bien es usualmente lo mismo para |
y ||
, con &
y &&
obtienes resultados muy diferentes (por ejemplo, 2 & 4
es 0 / falso, mientras que 2 && 4
es 1 / verdadero).
Si lo que obtiene de una función es en realidad un código de error y está comprobando que no es 0-ness, esto puede ser muy importante.
Esto no es un problema tan importante en Java en el que tiene que encasillar explícitamente a booleano o comparar con 0 o similar, pero en otros lenguajes con una sintaxis similar (C / C ++ y otros) puede ser bastante confuso.
Además, tenga en cuenta que & y | solo se puede aplicar a valores de tipo entero, y no a todo lo que puede ser equivalente a una prueba booleana. De nuevo, en lenguajes que no son Java, hay bastantes cosas que se pueden usar como un valor booleano con una comparación implícita != 0
(punteros, flotadores, objetos con un operator bool()
, etc.) y los operadores a nivel de bit casi siempre son Sin sentido en esos contextos.
Además del hecho de que | es un operador bitwise: || es un operador de cortocircuito: cuando un elemento es falso, no comprobará los otros.
if(something || someotherthing)
if(something | someotherthing)
si algo es VERDADERO, || no evaluará algo más, mientras que | haré Si las variables en sus sentencias if son en realidad llamadas a funciones, use || posiblemente esté ahorrando mucho rendimiento.
Cuando tuve esta pregunta, creé el código de prueba para tener una idea de esto.
public class HelloWorld{
public static boolean bool(){
System.out.println("Bool");
return true;
}
public static void main(String []args){
boolean a = true;
boolean b = false;
if(a||bool())
{
System.out.println("If condition executed");
}
else{
System.out.println("Else condition executed");
}
}
}
En este caso, solo cambiamos el valor del lado izquierdo de si la condición agrega a o b.
||
Escenario, cuando el lado izquierdo es verdadero [if (a || bool ())]
salida "If condition executed"
||
Escenario, cuando el lado izquierdo es falso [if (b || bool ())]
Salida-
Bool
If condition executed
Conclusion of ||
Cuando se usa ||
, el lado derecho solo verifica cuando el lado izquierdo es falso.
|
Escenario, cuando el lado izquierdo es verdadero [if (a | bool ())]
Salida-
Bool
If condition executed
|
Escenario, cuando el lado izquierdo es falso [if (b | bool ())]
Salida-
Bool
If condition executed
Conclusion of |
Cuando se utiliza |
, compruebe ambos lados izquierdo y derecho.
Echa un vistazo a:
http://java.sun.com/docs/books/tutorial/java/nutsandbolts/operators.html
| es bitwise inclusive O
|| es lógico o
El no cortocircuito puede ser útil. A veces quieres asegurarte de que dos expresiones evalúen. Por ejemplo, supongamos que tiene un método que elimina un objeto de dos listas separadas. Es posible que desee hacer algo como esto:
class foo {
ArrayList<Bar> list1 = new ArrayList<Bar>();
ArrayList<Bar> list2 = new ArrayList<Bar>();
//Returns true if bar is removed from both lists, otherwise false.
boolean removeBar(Bar bar) {
return (list1.remove(bar) & list2.remove(bar));
}
}
Si su método, en cambio, utilizara el operando condicional, no podría eliminar el objeto de la segunda lista si la primera lista devolviera el valor falso.
//Fails to execute the second remove if the first returns false.
boolean removeBar(Bar bar) {
return (list1.remove(bar) && list2.remove(bar));
}
No es increíblemente útil, y (como en la mayoría de las tareas de programación) se podría lograr con otros medios. Pero es un caso de uso para operandos bitwise.
Entonces, para aprovechar las otras respuestas con un ejemplo, el cortocircuito es crucial en los siguientes controles defensivos:
if (foo == null || foo.isClosed()) {
return;
}
if (bar != null && bar.isBlue()) {
foo.doSomething();
}
Utilizando |
y &
lugar podría resultar en una NullPointerException
lanzada aquí.
Hay muchos casos de uso que sugieren por qué debería ir para ||
en lugar de |
. Algunos casos de uso tienen que usar |
Operador para comprobar todas las condiciones.
Por ejemplo, si desea verificar la validación de formularios y quiere mostrar al usuario todos los campos no válidos con textos de error en lugar de solo un primer campo no válido.
||
el operador seria
if(checkIfEmpty(nameField) || checkIfEmpty(phoneField) || checkIfEmpty(emailField)) {
// invalid form with one or more empty fields
}
private boolean checkIfEmpty(Widget field) {
if(field.isEmpty()) {
field.setErrorMessage("Should not be empty!");
return true;
}
return false;
}
Entonces, con el fragmento de nameField
anterior, si el usuario envía el formulario con TODOS los campos vacíos, SOLAMENTE se mostrará el campo de nombre con un mensaje de error. Pero, si lo cambias a,
if(checkIfEmpty(nameField) | checkIfEmpty(phoneField) | checkIfEmpty(emailField)) {
// invalid form with one or more empty fields
}
Mostrará el mensaje de error adecuado en cada campo, independientemente de true
condiciones true
.
Lógica ||
y &&
marque el lado derecho solo si es necesario. El |
y &
comprobar ambos todo el tiempo.
Por ejemplo:
int i = 12;
if (i == 10 & i < 9) // It will check if i == 10 and if i < 9
...
Reescribalo
int i = 12;
if (i == 10 && i < 9) // It will check if i == 10 and stop checking afterward because i doesn''t = 10
...
Otro ejemplo:
int i = 12;
if (i == 12 | i > 10) // It will check if i == 12 and it will check if i > 10
...
Reescribalo
int i = 12;
if (i == 12 || i > 10) // It will check if i == 12, it does, so it stops checking and executes what is in the if statement
...
La única vez que usarías |
o &
lugar de ||
o &&
es cuando tiene expresiones booleanas muy simples y el costo del corte corto (es decir, una rama) es mayor que el tiempo que ahorra al no evaluar las expresiones posteriores.
Sin embargo, esta es una microoptimización que rara vez importa, excepto en el código de nivel más bajo.
La diferencia básica entre ellos es que | Primero convierte los valores a binarios y luego realiza la operación o el bit bit. Mientras tanto, || no convierte los datos en binarios y solo ejecuta la expresión o en su estado original.
int two = -2; int four = -4;
result = two | four; // bitwise OR example
System.out.println(Integer.toBinaryString(two));
System.out.println(Integer.toBinaryString(four));
System.out.println(Integer.toBinaryString(result));
Output:
11111111111111111111111111111110
11111111111111111111111111111100
11111111111111111111111111111110
Lea más: http://javarevisited.blogspot.com/2015/01/difference-between-bitwsie-and-logical.html#ixzz45PCxdQhk
Las otras respuestas han hecho un buen trabajo al cubrir la diferencia funcional entre los operadores, pero las respuestas podrían aplicarse a casi todos los lenguajes derivados de C existentes en la actualidad. La pregunta está etiquetada con java , por lo que me esforzaré por responder específicamente y técnicamente para el lenguaje Java.
&
y |
pueden ser Operadores enteros de Bitwise o Operadores lógicos booleanos. La sintaxis para los operadores lógicos y §15.22 ( §15.22 ) es:
AndExpression:
EqualityExpression
AndExpression & EqualityExpression
ExclusiveOrExpression:
AndExpression
ExclusiveOrExpression ^ AndExpression
InclusiveOrExpression:
ExclusiveOrExpression
InclusiveOrExpression | ExclusiveOrExpression
La sintaxis para EqualityExpression
se define en §15.21 , que requiere RelationalExpression
definida en §15.20 , que a su vez requiere ShiftExpression
y ReferenceType
definidos en §15.19 y §4.3 , respectivamente. ShiftExpression
requiere AdditiveExpression
definido en §15.18 , que continúa profundizando, definiendo la aritmética básica, operadores unarios, etc. ReferenceType
profundiza en todas las diversas formas de representar un tipo. (Aunque ReferenceType
no incluye los tipos primitivos, la definición de los tipos primitivos se requiere en última instancia, ya que pueden ser el tipo de dimensión para una matriz, que es un ReferenceType
).
Los operadores lógicos y bitwise tienen las siguientes propiedades:
- Estos operadores tienen diferente precedencia, con
&
tienen la mayor prioridad y|
La precedencia más baja.- Cada uno de estos operadores es sintácticamente asociativo a la izquierda (cada grupo de izquierda a derecha).
- Cada operador es conmutativo si las expresiones de los operandos no tienen efectos secundarios.
- Cada operador es asociativo.
- Los operadores binarios y lógicos se pueden usar para comparar dos operandos de tipo numérico o dos operandos de tipo
boolean
. Todos los demás casos dan como resultado un error en tiempo de compilación.
La distinción entre si el operador sirve como operador bit a bit o como operador lógico depende de si los operandos son "convertibles a un tipo integral primitivo" ( §4.2 ) o si son de tipo boolean
o Boolean
( §5.1.8 ).
Si los operandos son tipos integrales, la promoción numérica binaria ( §5.6.2 ) se realiza en ambos operandos, dejándolos como long
s o int
s para la operación. El tipo de operación será el tipo de los operandos (promovidos). En ese momento, &
será bitwise AND, ^
será bitwise exclusivo OR, y |
será bitwise inclusivo O. ( §15.22.1 )
Si los operandos son boolean
o Boolean
, los operandos estarán sujetos a la conversión unboxing si es necesario ( §5.1.8 ), y el tipo de operación será boolean
. &
resultará true
si ambos operandos son true
, ^
resultará true
si ambos operandos son diferentes, y |
resultará en true
si cualquiera de los operandos es true
. ( §15.22.2 )
En contraste, &&
es el "Operador y condicional" ( §15.23 ) y ||
es el "operador condicional" ( §15.24 ). Su sintaxis se define como:
ConditionalAndExpression:
InclusiveOrExpression
ConditionalAndExpression && InclusiveOrExpression
ConditionalOrExpression:
ConditionalAndExpression
ConditionalOrExpression || ConditionalAndExpression
&&
es como &
, excepto que solo evalúa el operando derecho si el operando izquierdo es true
. ||
es como |
, excepto que solo evalúa el operando derecho si el operando izquierdo es false
.
Condicional-Y tiene las siguientes propiedades:
- El condicional y el operador son sintácticamente asociativos a la izquierda (se agrupan de izquierda a derecha).
- El condicional y el operador son totalmente asociativos con respecto a los efectos secundarios y el valor del resultado. Es decir, para cualquier expresión
a
,b
, yc
, la evaluación de la expresión((a) && (b)) && (c)
produce el mismo resultado, con los mismos efectos secundarios que ocurren en el mismo orden, como la evaluación de la expresión(a) && ((b) && (c))
.- Cada operando del condicional y del operador debe ser de tipo
boolean
oBoolean
, o se produce un error en tiempo de compilación.- El tipo de una expresión y condicional es siempre
boolean
.- En el tiempo de ejecución, la expresión del operando de la izquierda se evalúa primero; si el resultado tiene el tipo
Boolean
, se somete a conversión de §5.1.8 ( §5.1.8 ).- Si el valor resultante es
false
, el valor de condicional y expresión esfalse
y la expresión del operando de la derecha no se evalúa.- Si el valor del operando de la izquierda es
true
, entonces se evalúa la expresión de la derecha; si el resultado tiene el tipoBoolean
, se somete a conversión de §5.1.8 ( §5.1.8 ). El valor resultante se convierte en el valor de la expresión-condicional.- Por lo tanto,
&&
calcula el mismo resultado que&
en operandosboolean
. Sólo difiere en que la expresión del operando de la derecha se evalúa condicionalmente en lugar de siempre.
Condicional o tiene las siguientes propiedades:
- El condicional o el operador es sintácticamente asociativo a la izquierda (se agrupa de izquierda a derecha).
- El operador condicional o es totalmente asociativo con respecto a los efectos secundarios y el valor del resultado. Es decir, para cualquier expresión
a
,b
, yc
, evaluación de la expresión((a) || (b)) || (c)
((a) || (b)) || (c)
produce el mismo resultado, con los mismos efectos secundarios que ocurren en el mismo orden, como evaluación de la expresión(a) || ((b) || (c))
(a) || ((b) || (c))
.- Cada operando del condicional o del operador debe ser de tipo
boolean
oBoolean
, o se produce un error en tiempo de compilación.- El tipo de una expresión-condicional es siempre
boolean
.- En el tiempo de ejecución, la expresión del operando de la izquierda se evalúa primero; si el resultado tiene el tipo
Boolean
, se somete a conversión de §5.1.8 ( §5.1.8 ).- Si el valor resultante es
true
, el valor de condicional o expresión estrue
y la expresión del operando de la derecha no se evalúa.- Si el valor del operando de la izquierda es
false
, se evalúa la expresión de la derecha; si el resultado tiene el tipoBoolean
, se somete a conversión de §5.1.8 ( §5.1.8 ). El valor resultante se convierte en el valor de la expresión-condicional.- Por lo tanto,
||
calcula el mismo resultado que|
En operandosboolean
oBoolean
. Sólo difiere en que la expresión del operando de la derecha se evalúa condicionalmente en lugar de siempre.
En resumen, como @JohnMeagher ha señalado repetidamente en los comentarios, &
y |
son, de hecho, operadores booleanos sin cortocircuito en el caso específico de los operandos que son boolean
o Boolean
. Con buenas prácticas (es decir, sin efectos secundarios), esta es una diferencia menor. Sin embargo, cuando los operandos no son boolean
o Boolean
, los operadores se comportan de manera muy diferente: las operaciones lógicas y de bits no se comparan bien en el alto nivel de programación de Java.
Los operadores ||
y &&
se llaman operadores condicionales , mientras que |
y &
se llaman operadores bitwise . Sirven diferentes propósitos.
Los operadores condicionales solo funcionan con expresiones que evalúan estáticamente a boolean
en ambos lados, izquierdo y derecho.
Los operadores bitwise trabajan con cualquier operandos numéricos.
Si desea realizar una comparación lógica, debe usar operadores condicionales , ya que agregará algún tipo de seguridad de tipo a su código.
Si usas el ||
y &&
formas, en lugar de la |
y &
formas de estos operadores, Java no se molestará en evaluar el operando de la mano derecha solo.
Es una cuestión de si desea realizar un cortocircuito en la evaluación o no, la mayor parte del tiempo que desee.
Una buena manera de ilustrar los beneficios del cortocircuito sería considerar el siguiente ejemplo.
Boolean b = true;
if(b || foo.timeConsumingCall())
{
//we entered without calling timeConsumingCall()
}
Otro beneficio, como mencionaron Jeremy y Peter, para el cortocircuito es la verificación de referencia nula:
if(string != null && string.isEmpty())
{
//we check for string being null before calling isEmpty()
}
También note un error común: los operadores no perezosos tienen prioridad sobre los perezosos, así que:
boolean a, b, c;
a || b && c; //resolves to a || (b && c)
a | b && c; //resolves to (a | b) && c
Ten cuidado al mezclarlos.
Una diferencia principal es que || y && exhiben "cortocircuitos", por lo que el RHS solo se evaluará si es necesario.
Por ejemplo
if (a || b) {
path1...
} else {
path2..
}
Arriba, si a es verdadero, entonces b no se probará y se ejecutará path1. Si | se usó entonces ambos lados serían evaluados incluso si ''a'' es verdadero.
Vea Here y here , para un poco más de información.
Espero que esto ayude.
Una nota al margen: Java tiene | = pero no un || =
Un ejemplo de cuando debes usar || es cuando la primera expresión es una prueba para ver si la segunda expresión explotaría. Por ejemplo, utilizando una sola | en el siguiente caso podría resultar en una NPE.
public static boolean isNotSet(String text) {
return text == null || text.length() == 0;
}
Usualmente lo uso cuando hay un operador de pre incremento y post incremento. Mira el siguiente código:
package ocjpPractice;
/**
* @author tithik
*
*/
public class Ex1 {
public static void main(String[] args) {
int i=10;
int j=9;
int x=10;
int y=9;
if(i==10 | ++i>j){
System.out.println("it will print in first if");
System.out.println("i is: "+i);
}
if(x==10 ||++x>y){
System.out.println("it will print in second if");
System.out.println("x is: "+x);
}
}
}
salida:
se imprimirá primero si
yo es: 11
se imprimirá en segundo lugar si
x es: 10
Ambos if
bloques son iguales pero el resultado es diferente. cuando hay |
, se evaluarán ambas condiciones. Pero si es ||
, no evaluará la segunda condición ya que la primera condición ya es verdadera.
un | b: evaluar b en cualquier caso
a || b: evalúa b solo si a se evalúa como falso
| = bitwise o, || = lógica o
| Es un operador bit a bit. || Es un operador lógico.
Uno tomará dos bits o los dos.
Uno determinará la verdad (esto o aquello) Si esto es verdad o es verdad, entonces la respuesta es verdadera.
Ah, y la gente responde a estas preguntas rápidamente.
|| devuelve un valor booleano mediante OR de dos valores (por eso se conoce como LOGICAL o)
ES DECIR:
if (A || B)
Devolvería verdadero si A o B es verdadero, o falso si ambos son falsos.
| es un operador que realiza una operación bitwise en dos valores. Para entender mejor las operaciones de bitwise, puedes leer aquí:
|| es el operador lógico mientras que | es el bitwise o el operador.
boolean a = true;
boolean b = false;
if (a || b) {
}
int a = 0x0001;
a = a | 0x0002;
|| es una lógica yy | es un poco sabio o.
| es bit a bit o, || es lógico o.
|
No hace evaluación de cortocircuito en expresiones booleanas. ||
dejará de evaluar si el primer operando es verdadero, pero |
no lo hare
Además, |
se puede utilizar para realizar la operación OR en modo bit a los valores de byte / short / int / long. ||
no poder.
| is the binary or operator
|| is the logic or operator