Por que geralmente usamos || sobre |? Qual é a diferença?

219

Eu só estou me perguntando por que geralmente usamos OR lógico ||entre dois booleanos não bit a bit OU |, embora ambos estejam funcionando bem.

Quero dizer, veja o seguinte:

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 em |vez de ||? A mesma coisa com &e &&.

Eng.Fouad
fonte
16
A maioria das pessoas esquece isso | é um operador booleano sem curto-circuito, além de ser um operador bit a bit.
John Meagher
1
Detalhes sobre a diferença estão no JLS. Veja java.sun.com/docs/books/jls/third_edition/html/…
John Meagher
64
Eles não são os mesmos. Confira os tutoriais sobre eles, especialmente em relação à avaliação de curto-circuito vs avaliação ansiosa . ||e &&curto-circuito enquanto |e &estão ansiosos.
Hovercraft Cheio De Enguias
4
Por curiosidade, em que caso você realmente gostaria de usar as versões sem curto-circuito? Quase sempre vejo &&e ||, mas nunca & |. Se você está fazendo algo que depende de efeitos colaterais, não vejo por que você usaria algo assim, (a & b | c)já que alguém poderia pensar facilmente: "Eu posso otimizar isso usando as versões em curto-circuito".
Mike Bailey
2
E, é claro, eles têm precedência diferente.
Hot Licks

Respostas:

349

Se você usar os ||e &&formas, ao invés do |e &formas de estes operadores, Java não vai se preocupar em avaliar a direita operando sozinho.

É uma questão de se você deseja dar um curto-circuito na avaliação ou não - na maioria das vezes você deseja.

Uma boa maneira de ilustrar os benefícios do curto-circuito seria considerar o exemplo a seguir.

Boolean b = true;
if(b || foo.timeConsumingCall())
{
   //we entered without calling timeConsumingCall()
}

Outro benefício, como Jeremy e Peter mencionaram, para um curto-circuito é a verificação de referência nula:

if(string != null && string.isEmpty())
{
    //we check for string being null before calling isEmpty()
}

mais informações

Shawn
fonte
115
O exemplo canônico éfoo != null && foo.hasBar()
Jeremy
1
Se você adicionar sobre a possível exceção de referência nula usando | do comentário de @ Jeremy, então esta é uma ótima resposta.
Peter Kelly
Lembre-se também de que && e || significa uma instrução de ramificação no nível do código da máquina (lembre-se de que as ramificações podem causar previsões errôneas de ramificação); portanto, se você é um pedante em relação ao desempenho, use-as apenas quando forem realmente necessárias ( foo != null && foo.hasBar()) ou mais rápidas ( b || foo.timeConsumingCall()). 99% dos desenvolvedores não precisam se preocupar com esse nível de micro-otimização.
Jonathan Dickinson
3
Estou surpreso que ninguém tenha mencionado quando você deseja usar |. O cenário mais comum que eu uso é quando uma variável é modificada na verificação como (j> 3 | ++ i> 3) ou (++ i> 3 | modifiesGlobalAmongOtherThings () = true). Não é muito comum embora.
AndSoYouCode
8
Outro exemplo canônico é string == null || string.isEmpty();)
Peter Lawrey
83

| não faz avaliação de curto-circuito em expressões booleanas. ||parará de avaliar se o primeiro operando é verdadeiro, mas |não será.

Além disso, |pode ser usado para executar a operação OR bit a bit em valores de byte / short / int / long. ||não podes.

Michael Myers
fonte
Forneça uma resposta completa e eu aceito. Até agora, você é o primeiro a entender esse aspecto.
John Meagher
Faltando o aspecto bit a bit de |
John Meagher
63

Portanto, para aproveitar as outras respostas com um exemplo, o curto-circuito é crucial nas seguintes verificações defensivas:

if (foo == null || foo.isClosed()) {
    return;
}

if (bar != null && bar.isBlue()) {
    foo.doSomething();
}

Usar |e, em &vez disso, pode resultar em NullPointerExceptionser jogado aqui.

Paul Bellora
fonte
Se você aplicou o padrão NullObject, isso não aconteceria (ou melhor, negaria a resposta). Além disso, eu diria que verificar se o foo é azul é algo interno ao foo. Se estiver azul, algo não deve fazer nada.
precisa saber é o seguinte
@ nicodemus13 - bons pontos, embora o padrão Null Object seja apenas desejável às vezes, e o corpo possa ser algo diferente de outra chamada foo. O "exemplo canônico" de Peter Lawrey é o melhor.
Paul Bellora
@ Khan: Sim, eu estava sendo bastante pernicioso, e o Objeto Nulo nem sempre é adequado. Acabei de adquirir o hábito de refatorar subconscientemente as coisas. Não há nada de particularmente errado com sua resposta.
precisa saber é o seguinte
39

Lógico ||e &&verifique o lado direito somente se necessário. O |e &verifique os dois lados toda vez.

Por exemplo:

int i = 12;
if (i == 10 & i < 9) // It will check if i == 10 and if i < 9
...

Reescreva-o:

int i = 12;
if (i == 10 && i < 9) // It will check if i == 10 and stop checking afterward because i != 10
...

Outro exemplo:

int i = 12;
if (i == 12 | i > 10) // It will check if i == 12 and it will check if i > 10
...

Reescreva-o:

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
...
Dair
fonte
18

Observe também uma armadilha comum: os operadores não preguiçosos têm precedência sobre os preguiçosos, portanto:

boolean a, b, c;
a || b && c; //resolves to a || (b && c)
a | b && c; //resolves to (a | b) && c

Tenha cuidado ao misturá-los.

Mister Smith
fonte
15

Além do curto-circuito, outra coisa a ter em mente é que fazer uma operação lógica bit a bit em valores que podem ser diferentes de 0 ou 1 tem um significado muito diferente da lógica condicional. Embora geralmente seja o mesmo para |e ||, com &e &&você obtém resultados muito diferentes (por exemplo, 2 & 4é 0 / falso, enquanto 2 && 4é 1 / verdadeiro).

Se o que você obtém de uma função é realmente um código de erro e está testando não-0-ness, isso pode importar bastante.

Isso não é um problema tão grande em Java, no qual você precisa tipicamente explicitar para booleano ou comparar com 0 ou algo semelhante, mas em outros idiomas com sintaxe semelhante (C / C ++ et al), pode ser bastante confuso.

Além disso, observe que & e | só pode ser aplicado a valores do tipo inteiro e nem tudo o que pode ser equivalente a um teste booleano. Novamente, em linguagens não Java, existem algumas coisas que podem ser usadas como booleanas com uma != 0comparação implícita (ponteiros, flutuadores, objetos com um operator bool()etc.) e os operadores bit a bit são quase sempre sem sentido nesses contextos.

fofo
fonte
3
Fico feliz que pelo menos alguém tenha mencionado todo o propósito da existência de operadores bit a bit.
ulidtko
9

O único momento em que você usaria |ou em &vez de ||ou &&é quando você tem expressões booleanas muito simples e o custo de atalho (ou seja, uma ramificação) é maior que o tempo que você economiza ao não avaliar as expressões posteriores.

No entanto, essa é uma micro-otimização que raramente importa, exceto no código de nível mais baixo.

Peter Lawrey
fonte
1
Seria interessante se o compilador faz isso automaticamente em alguns casos.
Starblue
Talvez o JIT pudesse, mas o compilador tende a lidar apenas com otimizações simples.
Peter Lawrey
2
Sim, também vi situações em que | é significativamente mais rápido que a sobrecarga de ramificação de ||, especialmente em CPUs com previsão de ramificação inexistente ou limitada. É raro, mas não inédito. Um dos meus colegas de trabalho entrou em uma guerra de reversão em algum código com um contratado porque ele estava (corretamente) usando | e o contratante continuava pensando que estava "errado".
fofo
4
@ Fofo, a moral da história é que, se você faz algo complicado, precisa comentar sobre o motivo pelo qual você fez isso ou seus esforços podem ser desperdiçados mais tarde. ;)
Peter Lawrey
1
Sim, eventualmente ele adicionou um comentário (na minha sugestão de como fazer com que o empreiteiro parasse de 'consertá-lo'), e está tudo bem.
fofo
8

|| é o lógico ou operador enquanto | é o operador bit a bit ou

boolean a = true;
boolean b = false;

if (a || b) {
}

int a = 0x0001;
a = a | 0x0002;
Jorge Ferreira
fonte
1
Falta isso | também é um operador booleano sem curto-circuito.
John Meagher
2
@ John Meagher: Isso está implícito, pois é bit a bit .
L̳o̳̳n̳̳g̳̳p̳o̳̳k̳̳e̳̳
@ L̲̳o̲̳̳n̲̳̳g̲̳̳p̲̳o̲̳̳k̲̳̳e̲̳̳ como você tornou seu nome um estilo diferente em seu perfil?
UdayKiran Pulipati
8

a | b: avalie b em qualquer caso

a || b: avalie b apenas se a for avaliado como falso

user18596
fonte
7

Além do fato de que | é um operador bit a bit: || é um operador de curto-circuito - quando um elemento é falso, ele não verifica os outros.

 if(something || someotherthing)
 if(something | someotherthing)

se algo é VERDADEIRO, || não avaliará algo, enquanto | vai fazer. Se as variáveis ​​em suas instruções if forem realmente chamadas de função, use || possivelmente está economizando muito desempenho.

Michael Stum
fonte
Por que você usaria | em uma declaração if. || é booleano | não é | só seria booleano se você já estiver trabalhando em dois valores booleanos.
FlySwat 18/09/08
Esta é a primeira resposta para obter tudo.
John Meagher
Esta resposta está incorreta. Se algo for FALSE, os dois operadores irão para o próximo operando. A diferença surge apenas quando o primeiro operando é verdadeiro.
Michael Myers
Para ruim, tem um exemplo absolutamente ridículo.
FlySwat 18/09/08
Não faço ideia por que alguém usaria | ou & em uma declaração if para comparação booleana simples, mas é perfeitamente legal, e eu realmente vi exemplos disso quando comecei a aprender programação.
Michael Stum
3
| is the binary or operator

|| is the logic or operator
Lucas S.
fonte
2
Falta isso | também é um operador booleano sem curto-circuito.
John Meagher
3

Os operadores ||e &&são chamados operadores condicionais , enquanto |e &são chamados operadores bit a bit . Eles servem a propósitos diferentes.

Operadores condicionais funcionam apenas com expressões que são avaliadas estaticamente booleannos lados esquerdo e direito.

Operadores bit a bit funcionam com qualquer operando numérico.

Se você deseja realizar uma comparação lógica, use operadores condicionais , pois adicionará algum tipo de segurança de tipo ao seu código.

Bruno Reis
fonte
Hum, |e &também são operadores condicionais. Por favor, veja o link no meu comentário para a postagem original.
Hovercraft Cheio De Enguias
@ Hovercraft Cheio De Enguias: Esse gráfico é um pouco enganador; está se referindo a eles como operadores condicionais SOMENTE no contexto de valores booleanos, onde eles são matematicamente equivalentes a operadores lógicos ansiosos. Quando você começa a lidar com coisas que possuem valores diferentes de 0 ou 1, valores de vírgula flutuante ou ponteiros ou qualquer outra coisa, a comparação é interrompida.
fofo
@ Fofo: não há nada de enganoso no gráfico, pois a discussão foi apenas sobre operadores booleanos. O fato de o |e &poder ser usado como operadores bit a bit é uma questão completamente separada.
Hovercraft Cheio De Enguias
1
Seria mais preciso se referir a eles como operadores bit a bit usados ​​em valores booleanos, e não como operadores booleanos. Eles simplesmente acontecem matematicamente equivalentes quando há apenas um bit.
fofo
2

Uma observação: Java possui | =, mas não um || =

Um exemplo de quando você deve usar || é quando a primeira expressão é um teste para ver se a segunda expressão explodiria. por exemplo, usando um único | no seguinte caso pode resultar em um NPE.

public static boolean isNotSet(String text) {
   return text == null || text.length() == 0;
}
Peter Lawrey
fonte
2

As outras respostas fizeram um bom trabalho ao cobrir a diferença funcional entre os operadores, mas as respostas podem se aplicar a praticamente todas as linguagens derivadas de C existentes hoje. A pergunta está marcada come, por isso, tentarei responder específica e tecnicamente à linguagem Java.

&e |podem ser operadores inteiros bit a bit ou operadores lógicos booleanos. A sintaxe para os operadores bit a bit e lógicos ( §15.22 ) é:

AndExpression:
  EqualityExpression 
  AndExpression & EqualityExpression

ExclusiveOrExpression:
  AndExpression 
  ExclusiveOrExpression ^ AndExpression

InclusiveOrExpression:
  ExclusiveOrExpression 
  InclusiveOrExpression | ExclusiveOrExpression

A sintaxe para EqualityExpressioné definida no §15.21 , que requer RelationalExpressiondefinido no §15.20 , que por sua vez requer ShiftExpressione ReferenceTypedefinido nos §15.19 e §4.3 , respectivamente. ShiftExpressionOs requisitos AdditiveExpressiondefinidos no §15.18 , que continuam a detalhar, definindo a aritmética básica, os operadores unários, etc. detalham ReferenceTypetodas as várias maneiras de representar um tipo. (Embora ReferenceTypenão inclua os tipos primitivos, a definição de tipos primitivos é finalmente necessária, pois eles podem ser o tipo de dimensão para uma matriz, que é a ReferenceType.)

Os operadores bit a bit e lógicos têm as seguintes propriedades:

  • Esses operadores têm precedência diferente, com &a maior e |a menor precedência.
  • Cada um desses operadores é sintaticamente associativo à esquerda (cada grupo da esquerda para a direita).
  • Cada operador é comutativo se as expressões do operando não tiverem efeitos colaterais.
  • Cada operador é associativo.
  • Os operadores bit a bit e lógicos podem ser usados ​​para comparar dois operandos do tipo numérico ou dois operandos do tipo boolean. Todos os outros casos resultam em um erro em tempo de compilação.

A distinção entre se o operador serve como operador bit a bit ou operador lógico depende se os operandos são "conversíveis em um tipo integral primitivo" ( §4.2 ) ou se são do tipo booleanou Boolean( §5.1.8 ).

Se os operandos são do tipo integral, a promoção numérica binária ( §5.6.2 ) é realizada nos dois operandos, deixando-os como longs ou ints para a operação. O tipo da operação será o tipo dos operandos (promovidos). Nesse ponto, &será AND bit a bit, ^será OR bit a bit exclusivo e |será OR bit a bit, inclusive. ( §15.22.1 )

Se os operandos forem booleanou Boolean, os operandos estarão sujeitos à conversão de unboxing, se necessário ( §5.1.8 ), e o tipo da operação será boolean. &resultará em truese ambos os operandos forem true, ^resultará em truese ambos operandos forem diferentes e |resultará em truese qualquer operando for true. ( §15.22.2 )

Por outro lado, && é o "Operador condicional-E" ( §15.23 ) e ||é o " Operador condicional-E " ( §15.24 ). Sua sintaxe é definida como:

ConditionalAndExpression:
  InclusiveOrExpression 
  ConditionalAndExpression && InclusiveOrExpression

ConditionalOrExpression:
  ConditionalAndExpression 
  ConditionalOrExpression || ConditionalAndExpression

&&é como &, exceto que ele avalia apenas o operando direito se o operando esquerdo estiver true. ||é como |, exceto que ele avalia apenas o operando direito se o operando esquerdo estiver false.

Condicional-E tem as seguintes propriedades:

  • O operador condicional e é associativamente à esquerda sintaticamente (agrupa da esquerda para a direita).
  • O operador condicional e é totalmente associativo em relação aos efeitos colaterais e ao valor do resultado. Ou seja, para qualquer expressão a, be cavaliação da expressão ((a) && (b)) && (c)produz o mesmo resultado, com os mesmos efeitos colaterais ocorrendo na mesma ordem, como avaliação da expressão (a) && ((b) && (c)).
  • Cada operando do operador condicional e deve ser do tipo booleanou Boolean, ou ocorre um erro em tempo de compilação.
  • O tipo de uma expressão condicional e é sempre boolean.
  • No tempo de execução, a expressão do operando do lado esquerdo é avaliada primeiro; se o resultado tiver um tipo Boolean, ele estará sujeito à conversão de unboxing ( §5.1.8 ).
  • Se o valor resultante for false, o valor da expressão condicional e é falsee a expressão do operando do lado direito não é avaliada.
  • Se o valor do operando do lado esquerdo for true, a expressão do lado direito será avaliada; se o resultado tiver um tipo Boolean, ele estará sujeito à conversão de unboxing ( §5.1.8 ). O valor resultante se torna o valor da expressão condicional-e.
  • Assim, &&calcula o mesmo resultado que &nos booleanoperandos. Difere apenas no fato de a expressão do operando do lado direito ser avaliada condicionalmente, e não sempre.

Condicional-Or tem as seguintes propriedades:

  • O operador condicional ou é associativamente à esquerda sintaticamente (agrupa da esquerda para a direita).
  • O operador condicional ou é totalmente associativo em relação aos efeitos colaterais e ao valor do resultado. Ou seja, para qualquer expressão a, be cavaliação da expressão ((a) || (b)) || (c)produz o mesmo resultado, com os mesmos efeitos colaterais ocorrendo na mesma ordem, como avaliação da expressão (a) || ((b) || (c)).
  • Cada operando do operador condicional ou deve ser do tipo booleanou Boolean, ou ocorre um erro em tempo de compilação.
  • O tipo de uma expressão condicional ou é sempre boolean.
  • No tempo de execução, a expressão do operando do lado esquerdo é avaliada primeiro; se o resultado tiver um tipo Boolean, ele estará sujeito à conversão de unboxing ( §5.1.8 ).
  • Se o valor resultante for true, o valor da expressão condicional ou é truee a expressão do operando do lado direito não é avaliada.
  • Se o valor do operando do lado esquerdo for false, a expressão do lado direito será avaliada; se o resultado tiver um tipo Boolean, ele estará sujeito à conversão de unboxing ( §5.1.8 ). O valor resultante se torna o valor da expressão condicional-ou.
  • Assim, ||calcula o mesmo resultado que |on booleanou Booleanoperandos. Difere apenas no fato de a expressão do operando do lado direito ser avaliada condicionalmente, e não sempre.

Resumindo, como @JohnMeagher apontou repetidamente nos comentários, &e |são, de fato, operadores booleanos sem curto-circuito no caso específico dos operandos serem um booleanou outro Boolean. Com boas práticas (ou seja, sem efeitos secundários), essa é uma pequena diferença. Quando os operandos não são booleans ou Booleans, no entanto, os operadores se comportam de maneira muito diferente: as operações bit a bit e lógicas simplesmente não se comparam bem no alto nível da programação Java.

Brian S
fonte
2

1). (Expressão1 | expressão2), | O operador avaliará a expressão2, independentemente de o resultado da expressão1 ser verdadeiro ou falso.

Exemplo:

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). (Expressão1 || expressão2), || O operador não avaliará a expressão2 se a expressão1 for verdadeira.

Exemplo:

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;
    }
}
Veeresh
fonte
1

|| retorna um valor booleano OR'ing dois valores (é por isso que é conhecido como LOGICAL or)

IE:

if (A || B) 

Retornaria true se A ou B for true ou false se ambos forem falsos.

| é um operador que executa uma operação bit a bit em dois valores. Para entender melhor as operações bit a bit, você pode ler aqui:

http://en.wikipedia.org/wiki/Bitwise_operation

FlySwat
fonte
1

Uma diferença principal é que || e && exibem "curto-circuito"; portanto, o RHS será avaliado apenas se necessário.

Por exemplo

if (a || b) {
    path1...
} else {
    path2..
}

Acima, se a for verdadeiro, b não será testado e o caminho1 será executado. Se | foi usado, os dois lados serão avaliados mesmo se 'a' for verdadeiro.

Veja aqui e aqui , para um pouco mais de informação.

Espero que isto ajude.

Alex H
fonte
1

Um curto-circuito não pode ser útil. Às vezes, você deseja garantir que duas expressões sejam avaliadas. Por exemplo, digamos que você tenha um método que remova um objeto de duas listas separadas. Você pode fazer algo assim:

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

Se, em vez disso, seu método usasse o operando condicional, ele falharia em remover o objeto da segunda lista se a primeira lista retornasse false.

//Fails to execute the second remove if the first returns false.
boolean removeBar(Bar bar) {
    return (list1.remove(bar) && list2.remove(bar));
}

Não é incrivelmente útil e (como na maioria das tarefas de programação), você pode consegui-lo com outros meios. Mas é um caso de uso para operandos bit a bit.

ktbiz
fonte
1

A diferença básica entre eles é que | primeiro converte os valores em binário e depois executa o bit ou operação. Enquanto isso, || não converte os dados em binários e apenas executa a expressão ou em seu 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

Leia mais: http://javarevisited.blogspot.com/2015/01/difference-between-bitwsie-and-logical.html#ixzz45PCxdQhk

Avinash Nath
fonte
Falso quando os operandos são booleanos e formatação estúpida.
Marquês de Lorne
2
Isso me ajudou a entender por que Long.valueOf (100 | 200) = 236. Aqui está o porquê: 0 1 1 0 0 1 0 0 | 1 1 0 0 1 0 0 0 = 1 1 1 0 1 1 0 0 = 128 64 32 0 8 4 0 0 = 236
donlys
1

Quando tive essa pergunta, criei o código de teste para ter uma idéia sobre isso.

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

 }
}

Nesse caso, apenas alteramos o valor do lado esquerdo de se a condição adicionar a ou b.

|| Cenário, quando o lado esquerdo for verdadeiro [if (a || bool ())]

resultado "If condition executed"

|| Cenário, quando o lado esquerdo for falso [if (b || bool ())]

Resultado-

Bool
If condition executed

Conclusion of || Quando usado ||, o lado direito verifica apenas quando o lado esquerdo é falso.

| Cenário, quando o lado esquerdo for verdadeiro [if (a | bool ())]

Resultado-

Bool
If condition executed

| Cenário, quando o lado esquerdo for falso [if (b | bool ())]

Resultado-

Bool
If condition executed

Conclusion of | Quando usar |, verifique os lados esquerdo e direito.

JustCode
fonte
0

| = bit a bit ou, || = lógica ou

MagicKat
fonte
2
Falta isso | também é um operador booleano sem curto-circuito.
John Meagher
0

normalmente eu uso quando há pré-incremento e pós-incremento. Veja o seguinte 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);
    }
    }
}

resultado:

ele será impresso primeiro se
eu for: 11

ele será impresso primeiro se
x for: 10

os dois ifblocos são iguais, mas o resultado é diferente. quando houver |, ambas as condições serão avaliadas. Mas, se for ||, não avaliará a segunda condição, pois a primeira condição já é verdadeira.

Tithi
fonte
1
Acho isso muito confuso
Nim Chimpsky
0

Existem muitos casos de uso que sugerem por que você deveria procurar ||e não |. Alguns casos de uso precisam usar o |operador para verificar todas as condições.

Por exemplo, se você deseja verificar a validação do formulário e deseja mostrar ao usuário todos os campos inválidos com textos de erro, em vez de apenas um primeiro campo inválido.

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

Portanto, com o snippet acima, se o usuário enviar o formulário com TODOS os campos vazios, APENAS nameFieldserá mostrado com mensagem de erro. Mas, se você mudar para,

   if(checkIfEmpty(nameField) | checkIfEmpty(phoneField) | checkIfEmpty(emailField)) {
      // invalid form with one or more empty fields
   }

Ele mostrará uma mensagem de erro adequada em cada campo, independentemente das truecondições.

Bharath Mg
fonte
0

Depois de ler atentamente, este tópico ainda não está claro para mim, se o uso |como operador lógico estiver em conformidade com as práticas padrão do Java.

Modifiquei recentemente o código em uma solicitação pull que aborda um comentário em que

if(function1() | function2()){
  ...
}

teve que ser alterado para

boolean isChanged = function1();
isChanged |= function2();
if (isChanged){
  ...
}

Qual é a versão realmente aceita?

A documentação Java não é mencionada |como um operador OR lógico, sem curto-circuito.

Não estou interessado em votar, mas mais em descobrir o padrão ?! Ambas as versões de código estão compilando e funcionando conforme o esperado.

Dan M
fonte
-1

|| é um lógico ou e | é um pouco sábio ou.

Steve Moyer
fonte
-2

| é um operador bit a bit. || é um operador lógico.

Um vai levar dois bits e ou eles.

Determinaremos a verdade (isto ou aquilo) Se isso é verdade ou aquilo é verdade, então a resposta é verdadeira.

Ah, e as pessoas respondem a essas perguntas rapidamente.

scubabbl
fonte