tl; dr pendapat saya adalah menggunakan unary +untuk memicu unboxing pada salah satu operan ketika memeriksa kesetaraan nilai, dan cukup gunakan operator matematika sebaliknya. Dasar pemikirannya sebagai berikut:
Telah disebutkan bahwa ==perbandingan Integeradalah perbandingan identitas, yang biasanya bukan yang diinginkan oleh seorang programmer, dan tujuannya adalah untuk melakukan perbandingan nilai; tetap, saya telah melakukan sedikit ilmu tentang bagaimana melakukan perbandingan itu paling efisien, baik dalam hal kekompakan kode, kebenaran dan kecepatan.
Saya menggunakan banyak metode:
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;
}
dan mendapatkan kode ini setelah kompilasi dan dekompilasi:
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;
}
}
Seperti yang dapat Anda lihat dengan mudah, metode 1 memanggil Integer.equals()(jelas), metode 2-4 menghasilkan kode yang persis sama , membuka nilai dengan menggunakan .intValue()dan kemudian membandingkannya secara langsung, dan metode 5 hanya memicu perbandingan identitas, menjadi cara yang salah untuk membandingkan nilai.
Karena (seperti yang telah disebutkan oleh JS misalnya) equals()menimbulkan overhead (yang harus dilakukan instanceofdan pemain yang tidak dicentang), metode 2-4 akan bekerja dengan kecepatan yang sama persis, lebih baik dari metode 1 saat digunakan dalam loop ketat, karena HotSpot tidak kemungkinan untuk mengoptimalkan gips & instanceof.
Ini sangat mirip dengan operator perbandingan lainnya (misalnya </ >) - mereka akan memicu unboxing, sementara menggunakan compareTo()tidak - tetapi kali ini, operasi ini sangat dioptimalkan oleh HS karena intValue()hanya metode pengambil (kandidat utama untuk dioptimalkan keluar).
Menurut pendapat saya, versi 4 yang jarang digunakan adalah cara yang paling ringkas - setiap pengembang C / Java berpengalaman tahu bahwa plus unary dalam banyak kasus sama dengan dilemparkan ke int/ .intValue()- sementara itu mungkin sedikit momen WTF untuk beberapa (kebanyakan mereka yang tidak dapat menggunakan unary plus dalam masa hidup mereka), ini bisa menunjukkan maksud yang paling jelas dan paling singkat - ini menunjukkan bahwa kita menginginkan intnilai dari salah satu operan, memaksa nilai lainnya untuk unbox juga. Ini juga sangat mirip dengan i1 == i2perbandingan reguler yang digunakan untuk intnilai-nilai primitif .
Pilihan saya berlaku untuk i1 == +i2& i1 > i2gaya untuk Integerobjek, baik untuk alasan kinerja & konsistensi. Itu juga membuat kode portabel untuk primitif tanpa mengubah apa pun selain tipe deklarasi. Menggunakan metode bernama sepertinya memperkenalkan kebisingan semantik kepada saya, mirip dengan gaya yang banyak dikritik bigInt.add(10).multiply(-3).