A minha opinião é usar um unário +para acionar o unboxing de um dos operandos ao verificar a igualdade de valor e simplesmente usar os operadores matemáticos. A justificativa a seguir:
Já foi mencionado que ==comparação para Integeré comparação de identidade, o que geralmente não é o que um programador deseja e que o objetivo é fazer comparação de valor; Ainda assim, eu fiz um pouco de ciência sobre como fazer essa comparação com mais eficiência, tanto em termos de compactação de código, correção e velocidade.
Eu usei o monte de métodos usual:
public boolean method1() {
Integer i1 = 7, i2 = 5;
return i1.equals( i2 );
}
public boolean method2() {
Integer i1 = 7, i2 = 5;
return i1.intValue() == i2.intValue();
}
public boolean method3() {
Integer i1 = 7, i2 = 5;
return i1.intValue() == i2;
}
public boolean method4() {
Integer i1 = 7, i2 = 5;
return i1 == +i2;
}
public boolean method5() { // obviously not what we want..
Integer i1 = 7, i2 = 5;
return i1 == i2;
}
e obteve esse código após a compilação e descompilação:
public boolean method1() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
return var1.equals( var2 );
}
public boolean method2() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2.intValue() == var1.intValue() ) {
return true;
} else {
return false;
}
}
public boolean method3() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2.intValue() == var1.intValue() ) {
return true;
} else {
return false;
}
}
public boolean method4() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2.intValue() == var1.intValue() ) {
return true;
} else {
return false;
}
}
public boolean method5() {
Integer var1 = Integer.valueOf( 7 );
Integer var2 = Integer.valueOf( 5 );
if ( var2 == var1 ) {
return true;
} else {
return false;
}
}
Como você pode ver facilmente, o método 1 chama Integer.equals()(obviamente), os métodos 2-4 resultam exatamente no mesmo código , desembrulhando os valores por meio de.intValue() e comparando-os diretamente, e o método 5 apenas aciona uma comparação de identidade, sendo a maneira incorreta de comparar valores.
Como (como já mencionado por exemplo, JS) equals()incorre em uma sobrecarga (é necessário fazer instanceofe uma conversão não verificada), os métodos 2 a 4 funcionam exatamente com a mesma velocidade, notavelmente melhor que o método 1 quando usado em loops apertados, já que o HotSpot não é provável otimizar os elencos & instanceof.
É bem parecido com outros operadores de comparação (por exemplo, </ >) - eles acionam o unboxing, enquanto o uso compareTo()não - mas desta vez, a operação é altamente otimizável pelo HS, poisintValue() é apenas um método getter (principal candidato a ser otimizado).
Na minha opinião, a versão 4 raramente usada é a maneira mais concisa - todo desenvolvedor experiente de C / Java sabe que o unary plus é na maioria dos casos igual a convertido para int/ .intValue()- embora possa ser um pouco WTF para alguns (principalmente aqueles que não usar o unário mais durante a vida útil), mostra sem dúvida a intenção de maneira mais clara e concisa - mostra que queremos um intvalor de um dos operandos, forçando o outro valor a desmarcar também. Também é indiscutivelmente o mais semelhante à i1 == i2comparação regular usada para intvalores primitivos .
Meu voto é para i1 == +i2& i1 > i2style para Integerobjetos, tanto por questões de desempenho quanto de consistência. Também torna o código portável para primitivas sem alterar nada além da declaração de tipo. Usar métodos nomeados parece introduzir ruído semântico para mim, semelhante ao bigInt.add(10).multiply(-3)estilo muito criticado .