Toán tử (Operators)
Khái niệm.
Bây giờ chúng ta đã biết cách khai báo và khởi gán các giá
trị ban đầu cho các biến, có lẽ bạn muốn biết làm thế nào để làm việc giữa các
biến với nhau. Học toán tử trong ngôn ngữ lập trình Java sẽ là nơi tốt nhất để
bắt đầu làm việc đó. Các toán tử là các ký hiệu đặc biệt trình diễn để một,
hai, ba toán hạng liên kết với nhau và trả về một giá trị.
Chúng ta sẽ tìm hiều các toán tử trong ngôn ngữ lập trình
Java, nó có thể giúp ích cho bạn biết nơi mà toán tử nào được thực thi trước có
những toán tử được quyền ưu tiên. Các toán tử ở dưới liệt kê theo thứ
tự ưu tiên. Toán tử xuất hiện ở gần đầu bảng thì độ ưu tiên cao hơn. Toán tử có
độ ưu tiên cao hơn sẽ được tính toán trước toán tử có độ ưu tiên thấp hơn. Các
toán tử trong cùng dòng sẽ cùng độ ưu tiên. Khi các toán tử có cùng độ ưu tiên
xuất hiện trong biểu thức thì một quy tắc chi phối toán tử nào ưu tiên trước. Tất
cả toán tử nhị phân được đánh giá từ trái qua phải, toán tử gán được tính toán
từ phải qua trái.
Quyền ưu tiên của các toán tử
Operators |
Precedence |
postfix |
expr++ expr-- |
unary |
++expr --expr +expr -expr ~
! |
multiplicative |
* / % |
additive |
+ - |
shift |
<< >>
>>> |
relational |
< > <= >=
instanceof |
equality |
== != |
bitwise AND |
& |
bitwise exclusive OR |
^ |
bitwise inclusive OR |
| |
logical AND |
&& |
logical OR |
|| |
ternary |
? : |
assignment |
= += -= *= /= %= &= ^= |=
<<= >>= >>>= |
Trong ngôn ngữ lập trình nói chung, một số toán tử có xu hướng
xuất hiện nhiều hơn toán tử khác. Ví dụ, toán tử gán: "=
" xuất hiện phổ biến hơn các toán tử dịch phải bit cho
số có dấu ">>>”.
Với ý đó, sẽ trước hết bàn luận tập chung vào
các toán tử xuất hiện phổ biến để sử dụng quy tắc cơ bản, và tập chung cuối
cùng vào các toán tử ít phổ biến. Mỗi bàn luận sẽ có một mã nguồn ví dụ bạn có
thể biên dịch và chạy nó. Học với đầu ra của chương trình sẽ giúp cho bạn củng
cố về những điều đã học.
Phép gán, toán tử số học và phép toán một
ngôi.
Toán tử gán đơn
Một toán tử phổ biến mà bạn sẽ luôn bắt gặp đó là toán tử
gán “=”. Bạn đã thấy toán tử này trong lớp Bicycle; nó sẽ gán giá trị bên phải
cho toán hạng bên trái:
int cadence = 0; int speed = 0; int gear = 1;
Toán tử này cũng có thể được sử dụng để gán các đối tượng
tham chiếu. Sẽ tìm hiểu sâu hơn trong phần lớp và đối tượng ở các chương
sau.
Các toán tử số học.
Trong ngôn ngữ lập trình Java có cung cấp các phép cộng, trừ
,nhân và chia. Chúng ta sẽ thấy chúng trong các phép toán cơ bản. Chỉ có ký tự
có vẻ mới với bạn đó là ký hiệu “%”, đây là phép chia một toán hạng cho một số
khác và trả về phần còn lại (phần dư) là kết quả.
Toán tử số học trong Java
Operator |
Description |
+ |
Additive operator (also used for String
concatenation) |
- |
Subtraction operator |
* |
Multiplication operator |
/ |
Division operator |
% |
Remainder operator |
Với chương trình dưới đây, kiểm tra lại các toán tử số học:
class ArithmeticDemo { public static void main (String[] args) { int result = 1 + 2; // result is now 3 System.out.println("1 + 2 = " + result); int original_result = result; result = result - 1; // result is now 2 System.out.println(original_result + " - 1 = " + result); original_result = result; result = result * 2; // result is now 4 System.out.println(original_result + " * 2 = " + result); original_result = result; result = result / 2; // result is now 2 System.out.println(original_result + " / 2 = " + result); original_result = result; result = result + 8; // result is now 10 System.out.println(original_result + " + 8 = " + result); original_result = result; result = result % 7; // result is now 3 System.out.println(original_result + " % 7 = " + result); } }
Kết quả của chương trình này như sau:
1 + 2 = 3
3 - 1 = 2
2 * 2 = 4
4 / 2 = 2
2 + 8 = 10
Bạn có thể phối hợp các toán tử số học với với nhau để tạo
ra phép gán hợp nhất. Ví dụ:x+=1; và x=x+1; cả hai đều tăng giá trị của x lên
1.
Toán tử + có thể được sử dụng để nối (tham gia) hai chuỗi với
nhau như trong ví dụ ConcatDemo sau đây:
class ConcatDemo {
public static void main(String[] args){
String firstString = "This is";
String secondString = " a concatenated string.";
String thirdString = firstString+secondString;
System.out.println(thirdString);
}
}
Trong chương trình này, biến thirdString chứa nội
dung “This is a concatenated string.” Nhận được sau khi in ra nhập
xuất chuẩn.
Toán tử một ngôi.
Toán tử một ngôi chỉ yêu cầu một toán hạng; chugns thực thi
các phép toán như tăng/giảm giá trị cho một, phủ định một biểu thức hoặc đaoả
ngược một giá trị có kiều là boolean.
Toán tử một ngôi.
Operator |
Description |
+ |
Unary plus operator; indicates positive value
(numbers are positive without this, however) |
- |
Unary minus operator; negates an expression |
++ |
Increment operator; increments a value by 1 |
-- |
Decrement operator; decrements a value by 1 |
! |
Logical complement operator; inverts the value
of a boolean |
Trong chương trình UnaryDemo, kiểm tra các toán tử một ngôi.
class UnaryDemo {
public static void main(String[] args) {
int result = +1;
// result is now 1
System.out.println(result);
result--;
// result is now 0
System.out.println(result);
result++;
// result is now 1
System.out.println(result);
result = -result;
// result is now -1
System.out.println(result);
boolean success = false;
// false
System.out.println(success);
// true
System.out.println(!success);
}
}
Việc tăng/giảm có thể được áp dụng trước (prefix) hoặc sau (postfix)
cho các toán hạng. Mã nguồn result++; và ++result;
sẽ trả về kết quả là result tăng lên một đơn vị. Chỉ khác nhau là
trong hình thức tiền tố (++result
) thì giá trị được tăng rồi mới tính toán. Còn
hình thức hậu tố (result++
) thì tính toán với giá trị ban đầu của result.
Nếu chỉ thực thi tăng/giảm đơn giản thì không vấn đề gì với cả hai hình thức.
Nhưng nếu sử dụng toán tử là một phần của biểu thức lớn hơn, thì sự khác biệt là
đáng kể.
Trong ví dụ PrePostDemo
minh họa toán tử một ngôi
tiền tố/hậu tố (prefix/postfix).
class PrePostDemo { public static void main(String[] args){ int i = 3; i++; // prints 4 System.out.println(i); ++i; // prints 5 System.out.println(i); // prints 6 System.out.println(++i); // prints 6 System.out.println(i++); // prints 7 System.out.println(i); } }
Các toán tử bình đẳng, quan hệ và điều kiện. (Equality, Relational,
and Conditional Operators)
Các toán tử bình đẳng và quan hệ.
Các toán tử bình đẳng và quan hệ dùng để sử dụng cho mục đích
nếu một toán hạng lớn hơn, nhỏ hơn, bằng, hoặc không bằng toán tử khác. Phần lớn
các toán tử này sẽ trông rất quen thuộc với bạn. Nhớ rằng bạn phải sử dụng “==”
chứ không phải “=”, khi kiểm tra hai giá trị nguyên thủy bằng nhau.
== equal to != not equal to > greater than >= greater than or equal to < less than <= less than or equal to
Trong chương trình ComparisonDemo
kiểm tra các toán tử so sánh.
class ComparisonDemo {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
if(value1 == value2)
System.out.println("value1 == value2");
if(value1 != value2)
System.out.println("value1 != value2");
if(value1 > value2)
System.out.println("value1 > value2");
if(value1 < value2)
System.out.println("value1 < value2");
if(value1 <= value2)
System.out.println("value1 <= value2");
}
}
Đầu ra của chương trình là:
value1 != value2 value1 < value2 value1 <= value2
Các toán tử điều kiện
Toán tử && và || là các toán tử điều kiện AND và toán
tử điều kiện OR, là hai toán tử cho biểu thức logic.
Ví dụ ConditionalDemo1
kiểm tra các toán tử
này.
class ConditionalDemo1 {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
if((value1 == 1) && (value2 == 2))
System.out.println("value1 is 1 AND value2 is 2");
if((value1 == 1) || (value2 == 1))
System.out.println("value1 is 1 OR value2 is 1");
}
}
Một toán tử điều kiện khác là ?: toán tử này có thể được hiểu
là if-then-else (sẽ bàn trong phần các câu lệnh điều
khiển sau này). Toán tử này là toán tử bậc ba bởi vì sử dụng ba toán hạng.
Trong ví dụ dưới đây nếu someCondition là true
thì gán giá trị value1 cho result. Trường hợp còn lại
thì gán giá trị value2 cho result. Ví dụ ConditionalDemo2
kiểm tra toán tử ?:
class ConditionalDemo2 {
public static void main(String[] args){
int value1 = 1;
int value2 = 2;
int result;
boolean someCondition = true;
result = someCondition ? value1 : value2;
System.out.println(result);
}
}
Bởi vì someCondition là true, nên chương
trình này sẽ in giá trị “1” ra màn hình. Sử dụng toán tử ?: thay thế cho câu lệnh
if-then-else
nếu tọa code dễ đọc hơn; ở ví dụ này khi biểu thức gọn nhẹ hơn.
So sánh kiểu với toán tử instanceof.
Toán tử instanceof so sánh một đối tượng với một kiểu
dữ liệu cụ thể. Bạn có thể sử dụng để kiểm tra nếu một đối tượng là thể hiện của
một class, một thể hiện của một subclass, hoặc một thể hiện của một lớp mà được
thực thi bởi một interface cụ thể.
Ví dụ InstanceofDemo, định nghĩa một lớp con (có tên là Parent),
một interface đơn giản (tên là MyInterface) và một lớp con (có tên là Child) kế
thừa lớp cha và thực thi interface.
class InstanceofDemo {
public static void main(String[] args) {
Parent obj1 = new Parent();
Parent obj2 = new Child();
System.out.println("obj1 instanceof Parent: "
+ (obj1 instanceof Parent));
System.out.println("obj1 instanceof Child: "
+ (obj1 instanceof Child));
System.out.println("obj1 instanceof MyInterface: "
+ (obj1 instanceof MyInterface));
System.out.println("obj2 instanceof Parent: "
+ (obj2 instanceof Parent));
System.out.println("obj2 instanceof Child: "
+ (obj2 instanceof Child));
System.out.println("obj2 instanceof MyInterface: "
+ (obj2 instanceof MyInterface));
}
}
class Parent {}
class Child extends Parent implements MyInterface {}
interface MyInterface {}
Đầu ra của chương trình này là :
obj1 instanceof Parent: true obj1 instanceof Child: false obj1 instanceof MyInterface: false obj2 instanceof Parent: true obj2 instanceof Child: true obj2 instanceof MyInterface: true
Khi bạn sử dụng toán tử instanceof hãy
nhớ rằng nếu đối tượng là có giá trị là null thì không
là thể hiện của bất kỳ một lớp nào.
Toán tử Bitwise và các toán tử dịch bít.
Trong ngôn ngữ lập trình Java cũng cung cấp c ác toán tử thực
thi bitwise và các toán tử duchj bit trên các kiểu số. Các toán tử được bàn đến
trong phần này thường ít khi được sử dụng. Do vậy nó phạm vi sử dụng của chúng
hẹp; đơn giản là để cho các bạn biết là chúng có tồn tại.
Các toán tử bitwise một ngôi bổ sung “~” đảo ngược mẫu; nó có
thể áp dụng cho bất kỳ kiểu số nào, biến “0” thành “1” và biến “1” thành “0”. Ví
dụ, một byte gồm 8 bit, áp dụng toán tử này cho giá trị mẫu bit là “00000000” chuyển thành mẫu bit là “11111111”.
Ký hiệu toán tử dịch trái “<<” dịch một bít trong mẫu
sang trái, và ký hiệu dịch phải “>>” dịch một bít trong mẫu sang phải. Các
bit trong mẫu nhận toán trử bên trái và vị trí của số sẽ dịch sang bên tay phải
toán tử.
Toán tử bitwise & thực thi một thao tác cho bitwise AND.
Toán tử bitwise ^ thực thi một thao tác cho bitwise OR.
Toán tử bitwise | thực thi một thao tác bitwise bao gồm thao
tác OR.
Trong ví dụ BitDemo, sử dụng toán tử bitwise AND để in số 2
ra màn hình.
class BitDemo {
public static void main(String[] args) {
int bitmask = 0x000F;
int val = 0x2222;
// prints "2"
System.out.println(val & bitmask);
}
}
Tổng kết về toán tử.
Tổng kết về cách toán tử hỗ trợ trong lập trình Java như sau:
Phép gán
= Toán tử gán
Toán tử số học.
+ Toán tử cộng (cũng áp dụng cho việc nối 2 xâu
- Toán tử trừ
* Toán tử nhân
/ Toán tử chia
% Toán tử phần còn lại.
Toán tử một ngôi
+ Toán tử một ngôi cộng;
- Toán tử trừ một bậc, phủ định một biểu thức
++ Toán tử tăng một đơn vị
-- Toán tử giảm một đơn vị
! Toán tử logic đổi giá trị.
Toán tử bình đẳng và quan hệ.
== Equal to
!= Not equal to
> Greater than
>= Greater than or equal to
< Less than
<= Less than or equal to
Toán tử điều kiện.
&& Conditional-AND
|| Conditional-OR
?: Toán tử 3 ngôi (thể hiện ngắn của câu lệnh if-then-else
Toán tử so sánh kiểu
instanceof So sánh một đối tương với một kiểu cụ thể nào đó.
Toán tử Bitwise và dịch bít
~ Unary bitwise complement
<< Signed left shift
>> Signed right shift
>>> Unsigned right shift
& Bitwise AND
^ Bitwise exclusive OR
| Bitwise inclusive OR
Bài tập ôn tập
Bài 1 Xem đoạn code sau. Toán tử nào xuất hiện trong đó.
arrayOfInts[j] > arrayOfInts[j+1]
Bài 2. Xem đoạn code sau:
int i = 10;
int n = i++%5;
b.Giá trị cuối cùng của i và n là bao nhiêu nếu thay thế i++
bằng ++i.
Bài 3 Toán tử nào để đảo giá trị của kiểu boolean?
Bài 4. Toán tử nào
được dùng trong so sánh “=” hay “==”?
Bài 5. Giải thích đoạn code sau:
result = someCondition ? value1 : value2; |
Bài 6 Thay đổi chương trình sau bằng cách sử dụng phép gán
kép.
class ArithmeticDemo {public static void main (String[] args){int result = 1 + 2; // result is now 3System.out.println(result);result = result - 1; // result is now 2System.out.println(result);result = result * 2; // result is now 4System.out.println(result);result = result / 2; // result is now 2System.out.println(result);result = result + 8; // result is now 10result = result % 7; // result is now 3System.out.println(result);}}
Bài tập 7 Trong chương trình sau, hãy giải thích vì sao
số 6 được in ra 2 lần.
class PrePostDemo {public static void main(String[] args){int i = 3;i++;System.out.println(i); // "4"++i;System.out.println(i); // "5"System.out.println(++i); // "6"System.out.println(i++); // "6"System.out.println(i); // "7"}}