[Tự học lập trình Java] Toán tử trong ngôn ngữ lập trình Java.

 

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 someConditiontrue 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;
a.Cho biết giá trị của i và sau đoạn code đó.

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 3
          System.out.println(result); 
          result = result - 1; // result is now 2
          System.out.println(result); 
          result = result * 2; // result is now 4
          System.out.println(result); 
          result = result / 2; // result is now 2
          System.out.println(result); 
          result = result + 8; // result is now 10
          result = result % 7; // result is now 3
          System.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"
    }
}

Mới hơn Cũ hơn

Biểu mẫu liên hệ