計(jì)算機(jī)的最基本用途之一就是執(zhí)行數(shù)學(xué)運(yùn)算,作為一門計(jì)算機(jī)語言,Java也提供了一套豐富的運(yùn)算符來操縱變量。
我們可以把運(yùn)算符分成以下幾組:
- 算術(shù)運(yùn)算符
- 位運(yùn)算符
- 關(guān)系運(yùn)算符
- 邏輯運(yùn)算符
- 賦值運(yùn)算符
- Instanceof運(yùn)算符
算術(shù)運(yùn)算符
運(yùn)算符顧明思義是一種符號(hào),它是連接一個(gè)以上的操作符,實(shí)現(xiàn)某種功能的運(yùn)算符。
我們就先來認(rèn)識(shí)一下算數(shù)運(yùn)算符把!
算術(shù)運(yùn)算符用在數(shù)學(xué)表達(dá)式中,主要實(shí)現(xiàn)的是算數(shù)運(yùn)算,如我們常見的加減乘除等。
表格中的實(shí)例假設(shè)整數(shù)變量a的值為7,變量b的值為3:
| 算術(shù)運(yùn)算符 | 描述 | 類型 | 例子 |
|---|---|---|---|
| + | 加法 - 相加運(yùn)算符兩側(cè)的值 | 雙目運(yùn)算符 | a+b等于10 |
| - | 減法 - 左操作數(shù)減去右操作數(shù) | 雙目運(yùn)算符 | a - b 等于4 |
| * | 乘法 - 相乘操作符兩側(cè)的值 | 雙目運(yùn)算符 | a * b 等于 21 |
| / | 除法 - 左操作數(shù)除以右操作數(shù) | 雙目運(yùn)算符 | a / b 等于 2 |
| % | 取余 - 左操作數(shù)初右操作數(shù)的余數(shù) | 雙目運(yùn)算符 | a % b 等于 1 |
| ++ | 自增 - 操作數(shù)的值加1 | 單目運(yùn)算符 | ++a(或a++) 等于 8 |
| -- | 自減 - 操作數(shù)的值減少1 | 單目運(yùn)算符 | --a(或a--) 等于 6 |
其中,自增(++)和自減(--)運(yùn)算符有兩種寫法:前綴(++i, --i)和后綴(i++, i--)。
- 前綴自增自減法(++i, --i):先進(jìn)行自增或自減運(yùn)算,在進(jìn)行表達(dá)式運(yùn)算。
- 后綴自增自減法(i++, i--):先進(jìn)行表達(dá)式運(yùn)算,再進(jìn)行自增或自減運(yùn)算。
我們可以編寫一下代碼來進(jìn)行直觀的感受:
public class Test {
public static void main(String args[]) {
int a = 5;
int b = 3;
int c = 3;
int d = 3;
System.out.println("a + b = " + (a + b));
System.out.println("a - b = " + (a - b));
System.out.println("a * b = " + (a * b));
System.out.println("a / b = " + (a / b));
System.out.println("a % b = " + (a % b));
System.out.println("a++ = " + (a++));
System.out.println("++a = " + (++a));
System.out.println("b-- = " + (b--));
System.out.println("--b = " + (--b));
System.out.println("c++ = " + (c++));
System.out.println("++d = " + (++d));
}
}
運(yùn)行結(jié)果:
a + b = 8
a - b = 2
a * b = 15
b / a = 1
b % a = 2
a++ = 5
++a = 7
b-- = 3
--b = 1
c++ = 3
++d = 4
大家可以發(fā)現(xiàn)++在變量的左邊和右邊,賦值得到的結(jié)果是不一樣的,自減也是同樣。
測(cè)試題:
public static void main(String[] args) {
int a = 10;
int b = 10;
int c = 10;
a = b++;
c = --a;
b = a--;
System.out.println(a);
System.out.println(b);
System.out.println(c);
}
public static void main(String[] args) {
int a = 1;
a = a++;
System.out.println(a);
int b = a++ * ++a;
System.out.println(b);
}
位運(yùn)算符
Java定義了位運(yùn)算符,應(yīng)用于整數(shù)類型(int)、長整型(long)、短整形(short)、字符型(char)和字節(jié)型(byte)等類型。位運(yùn)算時(shí)先轉(zhuǎn)換為二進(jìn)制,在按位運(yùn)算。
表格中的例子,變量a的值為60(00111100),變量b的值為13(00001101)
| 位運(yùn)算符 | 描述 | 例子 |
|---|---|---|
| & | 按位與 - 如果相對(duì)應(yīng)位都是1,則結(jié)果為1,否則為0 | (a&b),得到12,即0000 1100 |
| 丨 | 按位或 - 如果相對(duì)應(yīng)位都是0,則結(jié)果為0,否則為1 | (a丨b)得到61,即0011 1101 |
| ^ | 按位異或 - 如果相對(duì)應(yīng)位值相同,則結(jié)果為0,否則為1 | (a^b)得到49,即0011 0001 |
| ~ | 按位補(bǔ) - 翻轉(zhuǎn)操作數(shù)的每一位,即0變?yōu)?,1變?yōu)? | (~a)得到-61,即1100 0011 |
| << | 按位左移 - 左操作數(shù)按位左移右操作數(shù)指定的位數(shù) | a<<2得到240,即1111 0000 |
| >> | 按位右移 - 左操作數(shù)按位右移右操作數(shù)指定的位數(shù) | a>>2得到15,即1111 |
| >>> | 按位右移補(bǔ)零 - 左操作數(shù)的值按右操作數(shù)指定的位數(shù)右移,移動(dòng)得到的空位以零填充 | a>>>2得到15,即00001111 |
接下來輸入一下代碼,進(jìn)行驗(yàn)證:
public class Test {
public static void main(String args[]) {
int a = 60;
int b = 13;
System.out.println("a & b = " + (a & b));
System.out.println("a | b = " + (a | b));
System.out.println("a ^ b = " + (a ^ b));
System.out.println("~a = " + (~a));
System.out.println("a << 2 = " + (a << 2));
System.out.println("a >> 2 = " + (a >> 2));
System.out.println("a >>> 2 = " + (a >>> 2));
}
}
運(yùn)算結(jié)果:
a & b = 12
a | b = 51
a ^ b = 61
a << 2 = 240
a >> 2 = 15
a >>> 2 = 15
注意事項(xiàng):一個(gè)數(shù)異或同一個(gè)數(shù)兩次,結(jié)果還是本身
測(cè)試題:不借助第三個(gè)變量的前提下交換兩個(gè)整數(shù)變量的值
public class day2 {
public static void main(String[] args) {
int a = 3;
int b = 7;
System.out.println("交換前的值為:a=" + a + ", b=" + b);
a = a + b;
b = a - b;
a = a - b;
System.out.println("交換前的值為:a=" + a + ", b=" + b);
a = a ^ b;
b = a ^ b;
a = a ^ b;
System.out.println("交換前的值為:a=" + a + ", b=" + b);
}
}
邏輯運(yùn)算符
邏輯運(yùn)算符是通過運(yùn)算符將操作數(shù)或等式進(jìn)行邏輯判斷的語句。
表格中的例子中,假設(shè)布爾變量a為真,變量b為假:
| 邏輯運(yùn)算符 | 描述 | 類型 | 例子 |
|---|---|---|---|
| && | 與 - 當(dāng)且僅當(dāng)兩個(gè)操作數(shù)都為真,條件才為真 | 雙目運(yùn)算符 | (a&&b)為假 |
| 丨丨 | 或 - 兩個(gè)操作數(shù)任何一個(gè)為真,條件為真 | 雙目運(yùn)算符 | (a 丨丨b)為真 |
| ! | 非 - 用來反轉(zhuǎn)操作數(shù)的邏輯狀態(tài)。如果條件為真,則邏輯非運(yùn)算符將得到假 | 單目運(yùn)算符 | (!a)為假 |
| ^ | 異或 - 如果兩個(gè)操作數(shù)邏輯相同,則結(jié)果為假,否則為真 | 雙目運(yùn)算符 | (a^b)為真 |
我們可以通過“舉手表決”來理解邏輯運(yùn)算符
- 與 && :
a同意了(值為true),c也同意了(值為true),那這件事情肯定就OK了,所以a && c就為true;但是其中有一個(gè)人不同意,這件事情就不行,也就是a和c中,有一個(gè)為false,a && c就為false。 - 或 || :這件事情只要有一個(gè)人同意了,就可以了,所以
a和c中,有一個(gè)為true,a || c就為true。 - 非 ! :某個(gè)人原本同意,但非運(yùn)算使它的結(jié)果變?yōu)橄喾吹摹?code>a為
true,!a就是false;a為false,!a就是true。 - 異或 ^:兩個(gè)人的表決結(jié)果相同,就不通過;表決結(jié)果不同,才通過。所以
a和c中,一真一假結(jié)果為真,其它的都是假。
其中,當(dāng)使用與邏輯運(yùn)算符時(shí),在兩個(gè)操作數(shù)都為true時(shí),結(jié)果才為true,但是當(dāng)?shù)玫降谝粋€(gè)操作為false時(shí),其結(jié)果就必定是false,這時(shí)候就不會(huì)再判斷第二個(gè)操作了。
接下來輸入以下代碼,進(jìn)行驗(yàn)證把,同學(xué)們也可自行組織代碼驗(yàn)證一下。
public class Test {
public static void main(String args[]) {
boolean a = true;
boolean b = false;
System.out.println("a && b = " + (a && b));
System.out.println("a || b = " + (a || b));
System.out.println("!a = " + (!a));
System.out.println("a ^ b = " + (a ^ b));
}
}
運(yùn)行結(jié)果:
a && b = false
a || b = true
!a = false
a & b = true
賦值運(yùn)算符
賦值運(yùn)算符是指將右邊的操作數(shù)或運(yùn)算結(jié)果賦值給左邊的操作數(shù)。
| 賦值運(yùn)算符 | 描述 | 類型 | 例子 |
|---|---|---|---|
| = | 賦值 - 右操作數(shù)的值賦給左側(cè)操作數(shù) | 雙目運(yùn)算符 | a=c |
| += | 加等于 - 左操作數(shù)和右操作數(shù)相加賦值給左操作數(shù) | 雙目運(yùn)算符 | a+=c等價(jià)于a=a+c |
| -= | 減等于 - 左操作數(shù)和右操作數(shù)相減賦值給左操作數(shù) | 雙目運(yùn)算符 | a-=c等價(jià)于a=a-c |
| *= | 乘等于 - 左操作數(shù)和右操作數(shù)相乘賦值給左操作數(shù) | 雙目運(yùn)算符 | a=c等價(jià)于a=ac |
| /= | 除等于 - 左操作數(shù)和右操作數(shù)相除賦值給左操作數(shù) | 雙目運(yùn)算符 | a/=c等價(jià)于a=a/c |
| %= | 取余等于 - 左操作數(shù)和右操作數(shù)取模后賦值給左操作數(shù) | 雙目運(yùn)算符 | a%=c等價(jià)于a=a%c |
注意:除了上述的賦值運(yùn)算符外,還有位運(yùn)算和邏輯運(yùn)算的賦值運(yùn)算符,形式和方法同上。
接下來輸入以下代碼,進(jìn)行驗(yàn)證:
public class Test {
public static void main(String args[]) {
int a = 5;
int b = 3;
b += a;
System.out.println("b += a = " + b);
b = 3;
b -= a;
System.out.println("b -= a = " + b);
b = 3;
b *= a;
System.out.println("b *= a = " + b);
b = 3;
b /= a;
System.out.println("b /= a = " + b);
b = 3;
b %= a;
System.out.println("b %= a = " + b);
}
}
運(yùn)行結(jié)果:
b += a = 8
b -= a = -2
b *= a = 0
b %= a = 3
關(guān)系運(yùn)算符
關(guān)系運(yùn)算符生成的是一個(gè)boolean(布爾)結(jié)果,它們計(jì)算的是操作數(shù)的值之間的關(guān)系。如果關(guān)系是真實(shí)的,結(jié)果為true(真),否則,結(jié)果為false(假)。
表格中的例子中,假設(shè)變量a為3,變量b為5:
| 關(guān)系運(yùn)算符 | 描述 | 例子 |
|---|---|---|
| == | 等于 - 判斷兩個(gè)操作數(shù)的值是否相等,如果相等則條件為真 | (a==b)為false |
| != | 不等于- 判斷兩個(gè)操作數(shù)的值是否相等,如果不相等則條件為真 | (a!=b)為false |
| > | 大于 - 判斷左操作數(shù)的值是否大于右操作數(shù)的值,如果是那么條件為真 | (a>b)為false |
| < | 小于 - 判斷左操作數(shù)的值是否小于右操作數(shù)的值,如果是那么條件為真 | (a<b)為true |
| >= | 大于等于 - 判斷左操作數(shù)的值是否大于或等于右操作數(shù)的值,如果是那么條件為真 | (a>=b)為false |
| <= | 小于等于 - 判斷左操作數(shù)的值是否小于或等于右操作數(shù)的值,如果是那么條件為真 | (a<=b)為true |
接下來輸入以下代碼,進(jìn)行驗(yàn)證:
public class Test {
public static void main(String args[]) {
int a = 3;
int b = 5;
System.out.println("a == b = " + (a == b));
System.out.println("a != b = " + (a != b));
System.out.println("a > b = " + (a > b));
System.out.println("a < b = " + (a < b));
System.out.println("a >= b = " + (a >= b));
System.out.println("a <= b = " + (a <= b));
}
}
運(yùn)行結(jié)果:
a == b = false
a != b = true
a > b = false
a < b = true
a >= b = false
a <= b = true
強(qiáng)調(diào):
-
==和!=適用于所有的基本數(shù)據(jù)類型,其它關(guān)系運(yùn)算符不適用于boolean,因?yàn)?code>boolean值只有true和false,比較沒有任何意義。 -
==和!=也適用于所有對(duì)象,可以比較對(duì)象的引用是否相同。
引用:Java中的一切都是對(duì)象,但操作的標(biāo)識(shí)符實(shí)際是對(duì)象的一個(gè)引用。
例:
String s;
在這里,創(chuàng)建的是引用,不是對(duì)象。創(chuàng)建引用后,一種安全的做法是對(duì)其進(jìn)行初始化。
String s = "abc";
String s = new String("abc");
通常采用new操作符生成一個(gè)新對(duì)象,然后將引用與該對(duì)象相關(guān)聯(lián)。
來看下面的代碼:
public class Test {
public static void main(String args[]) {
Integer n1 = new Integer(2);
Integer n2 = new Integer(2);
System.out.println(n1 == n2);
System.out.println(n1 != n2);
}
}
在上面的代碼中,同學(xué)們認(rèn)為輸出的結(jié)果是什么呢,可能認(rèn)為先是true,再是false,因?yàn)閮蓚€(gè)對(duì)象是相同的。盡管兩個(gè)對(duì)象的內(nèi)容相同,但它們的引用卻不相同,==和!=比較的就是對(duì)象的引用,所以結(jié)果false,再是true,如下:
false
true
而想要比較對(duì)象的內(nèi)容是否相同時(shí),Java提供了一個(gè)特殊的方法equals(),它不適用與基本類型,基本類型使用==和!=進(jìn)行比較。
來看下面的代碼:
public class Test {
public static void main(String args[]) {
Integer n1 = new Integer(2);
Integer n2 = new Integer(2);
System.out.println(n1.equals(n2));
}
}
上述的代碼運(yùn)行結(jié)果:
true
注:但是當(dāng)自己創(chuàng)建了一個(gè)類時(shí),情況又會(huì)相反,因?yàn)閑quals()默認(rèn)比較引用,除非在自己的類中覆蓋equal()方法。
條件運(yùn)算符
同學(xué)們從上面我們可以發(fā)現(xiàn),我們把各類運(yùn)算符分為了單目運(yùn)算符和雙目運(yùn)算符,這是什么意思呢?單目運(yùn)算符(或一元運(yùn)算符)是只需要有一個(gè)操作數(shù)的運(yùn)算符,雙目運(yùn)算符(或二元運(yùn)算符)是需要兩個(gè)操作數(shù)的運(yùn)算符。
那有沒有三目運(yùn)算符呢?
條件運(yùn)算符?:便是唯一的一個(gè)三目運(yùn)算符了。
語法形式:布爾表達(dá)式?表達(dá)式1 : 表達(dá)式2
運(yùn)算過程:如果布爾表達(dá)式的值為true ,則返回 表達(dá)式1 的值,否則返回 表達(dá)式2 的值。
例如:
String str = (3<2) ? "3小于2" : "3大于2";
System.out.println(str);
分析一下上面的代碼,很明顯3<2是false,所以返回第二個(gè)表達(dá)式,即str = "3大于2"。
Instanceof運(yùn)算符
該運(yùn)算符用于操作對(duì)象實(shí)例,檢查該對(duì)象是否是一個(gè)待定類型(類類型或接口類型)。
instanceof運(yùn)算符使用格式如下:
(Object reference variable) instanceof (class/interface type)
如果運(yùn)算符左側(cè)變量所指的對(duì)象,是操作符右側(cè)類或接口(class/interface)的一個(gè)對(duì)象,那么結(jié)果為真。
下面是一個(gè)例子:
String name = "James";
boolean result = name instanceof String; // 由于name是String類型,所以返回真
如果被比較的對(duì)象兼容于右側(cè)類型,該運(yùn)算符仍然返回true。
看下面的例子:
class Vehicle {}
public class Car extends Vehicle {
public static void main(String[] args){
Vehicle a = new Car();
boolean result = a instanceof Car;
System.out.println( result);
}
}
以上實(shí)例編譯運(yùn)行的結(jié)果如下:
true
運(yùn)算符的優(yōu)先級(jí)
當(dāng)多個(gè)運(yùn)算符出現(xiàn)在一個(gè)表達(dá)式中,誰先誰后?這就涉及到運(yùn)算符的優(yōu)先級(jí)別的問題。在一個(gè)多運(yùn)算符的表達(dá)式中,運(yùn)算符優(yōu)先級(jí)不同會(huì)導(dǎo)致最后得出的結(jié)果差別甚大。
例如,(1+3)+(3+2)*2,這個(gè)表達(dá)式如果按加號(hào)最優(yōu)先計(jì)算,答案就是 18,如果按照乘號(hào)最優(yōu)先,答案則是 14。
再如,x = 7 + 3 * 2;這里x得到13,而不是20,因?yàn)槌朔ㄟ\(yùn)算符比加法運(yùn)算符有較高的優(yōu)先級(jí),所以先計(jì)算3 * 2得到6,然后再加7。
下表是運(yùn)算符的優(yōu)先級(jí)表:
| 優(yōu)先級(jí) | 運(yùn)算符 | 關(guān)聯(lián)性 |
|---|---|---|
| 1 | () 、[] | 從左到右 |
| 2 | ! 、+(正)、-(負(fù))、~、++、-- | 從右到左 |
| 3 | * 、/、% | 從左到右 |
| 4 | +、- | 從左到右 |
| 5 | << 、>>、 >>> | 從左到右 |
| 6 | <、<=、>、>=、instanceof | 從左到右 |
| 7 | ==、!= | 從左到右 |
| 8 | &(按位與) | 從左到右 |
| 9 | ^ | 從左到右 |
| 10 | 丨 | 從左到右 |
| 11 | && | 從左到右 |
| 12 | 丨丨 | 從左到右 |
| 13 | ?: | 從右到左 |
| 14 | =、+=、-=、*=、/=、%=、&=、丨=、 ^=、~=、 <<=、>>=、 >>>= | 從右到左 |
練習(xí)題
1.第一題
求出 j 的結(jié)果,寫出運(yùn)算步驟
public static void main(String[] args) {
int i=3,j;
j=(i++)+(i++)+(++i);
System.out.println(j);
}
它的運(yùn)算結(jié)果為13,j=(i++)+(i++)+(++i)的運(yùn)算步驟為(i++)=3,i=4, 第二個(gè)(i++)=4,i=5,第三個(gè)(++i)=6,i=6,之后相加,為13.
public static void main(String[] args) {
int a = 1;
a = a++;
System.out.println(a);
int b = a++ * ++a;
System.out.println(b);
}
求a,b,c最后的值
public static void main(String[] args) {
int a = 10;
int b = 10;
int c = 10;
a = b++;
c = --a;
b = a--;
System.out.println(a);
System.out.println(b);
System.out.println(c);
}