tl; dr meine meinung ist es, eine unäre zu verwenden+
die Unboxing auf einer der Operanden zu triggern , wenn für Wertgleichheit überprüft, und nur die Operatoren Mathematik anderweitig zu nutzen. Begründung folgt:
Es wurde bereits erwähnt, dass der ==
Vergleich für einen Integer
Identitätsvergleich ist, was normalerweise nicht das ist, was ein Programmierer möchte, und dass das Ziel darin besteht, einen Wertevergleich durchzuführen. noch, ich habe ein wenig getan Wissenschaft darüber , wie dieser Vergleich zu tun , am effizientesten, sowohl in der Bezeichnung des Code Kompaktheit, Korrektheit und Geschwindigkeit.
Ich habe die üblichen Methoden angewendet:
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;
}
und habe diesen Code nach dem Kompilieren und Dekompilieren erhalten:
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;
}
}
Wie Sie leicht sehen können, rufen Methode 1 Integer.equals()
(offensichtlich) auf, Methoden 2-4 führen zu genau demselben Code und entpacken die Werte mit.intValue()
und dann direktem Vergleich entpackt werden, und Methode 5 löst lediglich einen Identitätsvergleich aus, was der falsche Weg ist Werte vergleichen.
Da (wie bereits von z. B. JS erwähnt) equals()
ein Overhead entsteht (dies muss geschehen instanceof
und eine ungeprüfte Umwandlung), arbeiten die Methoden 2 bis 4 mit genau der gleichen Geschwindigkeit, die in engen Schleifen deutlich besser ist als Methode 1, da HotSpot dies nicht ist wahrscheinlich die Casts & zu optimieren instanceof
.
Ähnlich verhält es sich mit anderen Vergleichsoperatoren (z. B. <
/ >
) - sie lösen Unboxing aus, während sie dies compareTo()
nicht tun -, aber diesmal ist die Operation von HS seitdem in hohem Maße optimierbarintValue()
es sich nur um eine Getter-Methode handelt (Hauptkandidat für eine Optimierung).
Meiner Meinung nach ist die selten verwendete Version 4 die prägnanteste Methode - jeder erfahrene C / Java-Entwickler weiß, dass unäres Plus in den meisten Fällen gleichbedeutend mit int
/ ist .intValue()
-, während es für einige (meistens für diejenigen, die dies nicht getan haben) ein kleiner WTF- Moment sein kann (verwenden Sie unary plus in ihrem Leben nicht), es zeigt wohl die Absicht am klarsten und am knappsten - es zeigt, dass wir einen int
Wert für einen der Operanden wollen, wodurch der andere Wert ebenfalls zum Entpacken gezwungen wird. Es ist auch dem regulären i1 == i2
Vergleich, der für primitive int
Werte verwendet wird, unbestreitbar am ähnlichsten .
Meine Stimme gilt für i1 == +i2
& i1 > i2
Stil für Integer
Objekte, sowohl aus Gründen der Leistung als auch aus Gründen der Konsistenz. Außerdem kann der Code auf Grundelemente portiert werden, ohne dass etwas anderes als die Typdeklaration geändert werden muss. Die Verwendung benannter Methoden scheint mir semantisches Rauschen einzuführen, ähnlich dem viel kritisierten bigInt.add(10).multiply(-3)
Stil.