tl; dr ý kiến của tôi là sử dụng một unary +
để kích hoạt unboxing trên một trong các toán hạng khi kiểm tra sự bằng nhau về giá trị và chỉ cần sử dụng các toán tử toán học theo cách khác. Lý do sau:
Người ta đã đề cập rằng ==
so sánh Integer
là so sánh nhận dạng, thường không phải là điều mà một lập trình viên muốn, và mục đích là để so sánh giá trị; Tuy nhiên, tôi đã thực hiện một khoa học nhỏ về cách thực hiện so sánh đó một cách hiệu quả nhất, cả về độ gọn nhẹ của mã, độ chính xác và tốc độ.
Tôi đã sử dụng một loạt các phương thức thông thường:
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;
}
và nhận được mã này sau khi biên dịch và dịch ngược:
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;
}
}
Như bạn có thể dễ dàng thấy, các cuộc gọi phương thức 1 Integer.equals()
(rõ ràng), các phương thức 2-4 dẫn đến chính xác cùng một mã , hủy kết nối các giá trị bằng phương thức .intValue()
và sau đó so sánh chúng trực tiếp và phương thức 5 chỉ kích hoạt so sánh nhận dạng, là cách không chính xác so sánh các giá trị.
Vì (như đã được đề cập bởi ví dụ: JS) equals()
phát sinh chi phí hoạt động (nó phải làm instanceof
và không được chọn), nên các phương thức 2-4 sẽ hoạt động với tốc độ chính xác như nhau, tốt hơn đáng kể so với phương pháp 1 khi được sử dụng trong các vòng lặp chặt chẽ, vì HotSpot không có khả năng tối ưu hóa các diễn viên & instanceof
.
Nó khá giống với các toán tử so sánh khác (ví dụ <
/>
) - chúng sẽ kích hoạt unboxing, trong khi sử dụng compareTo()
sẽ không - nhưng lần này, hoạt động được HS tối ưu hóa rất cao vì intValue()
chỉ là phương thức getter (ứng cử viên chính được tối ưu hóa).
Theo tôi, hiếm khi sử dụng phiên bản 4 là cách ngắn gọn nhất - mọi nhà phát triển C / Java dày dạn đều biết rằng unary plus trong hầu hết các trường hợp tương đương với int
/ .intValue()
- trong khi đó có thể là một khoảnh khắc WTF nhỏ đối với một số người (chủ yếu là những người đã không Không sử dụng unary plus trong suốt cuộc đời của họ), có thể cho thấy mục đích rõ ràng và chặt chẽ nhất - nó cho thấy rằng chúng tôi muốn một int
giá trị của một trong các toán hạng, cũng buộc giá trị kia phải bỏ hộp. Nó cũng đặc biệt giống với i1 == i2
so sánh thông thường được sử dụng cho các int
giá trị nguyên thủy .
Phiếu bầu của tôi dành cho i1 == +i2
& i1 > i2
phong cách cho Integer
các đối tượng, cả vì lý do hiệu suất và tính nhất quán. Nó cũng làm cho mã di động trở thành nguyên thủy mà không thay đổi bất cứ điều gì ngoài khai báo kiểu. Sử dụng các phương pháp được đặt tên có vẻ như giới thiệu tiếng ồn ngữ nghĩa với tôi, tương tự như bigInt.add(10).multiply(-3)
phong cách bị chỉ trích nhiều .