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 Integer
adalah 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 instanceof
dan 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 int
nilai dari salah satu operan, memaksa nilai lainnya untuk unbox juga. Ini juga sangat mirip dengan i1 == i2
perbandingan reguler yang digunakan untuk int
nilai-nilai primitif .
Pilihan saya berlaku untuk i1 == +i2
& i1 > i2
gaya untuk Integer
objek, 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)
.