【Java】運算符(算術、賦值、比較(關係)、邏輯、條件、位運算符)

運算符

運算符:
1、算術運算符
2、賦值運算符
3、比較運算符(關係運算符)
4、邏輯運算符
5、條件運算符
6、位運算符
表達式:操作數+運算符

1、按照操作數個數的分類:

(1)一元運算符:操作數只有一個

例如:正號(+),負號(-),自增(++),自減(–),邏輯非(!),按位取反(~)

(2)二元運算符:操作數有兩個

例如:加(+),減(-),乘(*),除(/),模(%)

​ 大於(>),小於(<),大於等於(>=),小於等於(<=),等於(==),不等於(!=)

​ 賦值(=,+=,-=,*=,/=,%=,>>=,<<=。。。)

​ 邏輯與(&),邏輯或(|),邏輯異或(^),短路與(&&),短路或(||)

​ 左移(<<),右移(>>),無符號右移(>>>),按位與(&),按位或(|),按位異或(^)

(3)三元運算符:操作數三個

例如: ? :

2、Java基本數據類型的運算符:

(1)算術運算符

(2)賦值運算符

(3)比較運算符

(4)邏輯運算符

(5)條件運算符

(6)位運算符(難)

1、 算術運算符

加法:+

減法:-

乘法:*

除法:/

注意:整數與整數相除,只保留整數部分

取模:% 取餘 被模數%模數

注意:取模結果的正負號只看被模數

特殊:模數的負號被忽略

正號:+

+:作爲單目運算時表示正數 正號:+
與其他基本數據類型計算時當做加法用 a + b

在JAVA中:+ 還表示拼接
只要+兩邊有一個是字符串,那麼就是拼接,結果仍然是字符串
a + “+”:a變量的值 拼接上 “+”符號 ,當與字符串String類型進行運算時表示連接,計算結果是字符串String類型 “菜”+“牛” “菜牛”

負號:-

-作爲單目運算符時表示負數 -5
與其他基本數據類型計算時當做減法用 a-b

自增:++

自減:–

原則:自增與自減

++/–在前的,就先自增/自減,後取值

++/–在後的,就先取值,後自增/自減

整個表達式的掃描,是從左往右掃描,如果後面的先計算的,那麼前面的就暫時先放到“操作數棧”中

對於自增變量本身來說,++在前或在後都一樣,自增變量都要加1
i++或++i,i就是自增變量

對於表達式來說,i++和++i不一樣的,++在前,先自增,再進行其他運算,++在後,先進行其他運算,然後再自增

代碼示例:

int i = 1;
i++;//i=2

int j = 1;
++j;//j=2

int a = 1;
int b = a++;//(1)先取a的值“1”放操作數棧(2)a再自增,a=2(3)再把操作數棧中的"1"賦值給b,b=1

int m = 1;
int n = ++m;//(1)m先自增,m=2(2)再取m的值“2”放操作數棧(3)再把操作數棧中的"2"賦值給n,n=1

int i = 1;
int j = i++ + ++i * i++;
/*
從左往右加載
(1)先算i++
①取i的值“1”放操作數棧
②i再自增 i=2
(2)再算++i
①i先自增 i=3
②再取i的值“3”放操作數棧
(3)再算i++
①取i的值“3”放操作數棧
②i再自增 i=4
(4)先算乘法
用操作數棧中3 * 3 = 9,並把9壓會操作數棧
(5)再算求和
用操作數棧中的 1 + 9 = 10
(6)最後算賦值
j = 10
*/

2、 賦值運算符

基本賦值運算符:=

擴展賦值運算符:+=,-=,*=,/=,%=…

賦值:assign
最基本的賦值運算符:=

Java中賦值,永遠是把等號=右邊的賦值給左邊的變量。
右邊如果是常量值,那麼就把常量的值直接賦值給左邊的變量;
右邊如果是變量,那麼就把變量的值直接賦值給左邊的變量;
右邊如果是表達式,那麼就把表達式的運算結果直接賦值給左邊的變量;

擴展的賦值運算符:
+=,-=,*=,/=,%=
注意:
(1)+=等,中間是不能有空格的,即不能寫成 + =
(2)如果結果的類型與左邊的變量不在一樣時,隱含了強制類型轉換

注意:所有的賦值運算符的=左邊一定是一個變量

擴展賦值運算符=右邊的計算結果的類型如果比左邊的大的話會強制類型轉換,所以結果可能有風險。

擴展賦值運算符的計算:(1)賦值最後算(2)加載數據的順序是把左邊的變量的值先加載,再去與右邊的表達式進行計算

int i = 1;
int j = 5;
j *= i++ + j++;//j = j *(i++ + j++);
/*
(1)先加載j的值“5”
(2)在計算i++
①先加載i的值“1”
②再i自增,i=2
(3)再計算j++
①先加載j的值"5"
②再j自增,j=6
(4)算  加法
i + 5 = 6
(5)算乘法
5 * 6 = 30
(6)賦值
j = 30
*/

3、 比較運算符

關係運算符,比較運算符:運算的結果只有true或false的布爾值
(1)> < >= <= !=
(2)== 判斷是否相等,一定要與=賦值運算符區分開
(3)instanceof,引用數據類型的關係運算符.

大於:>

小於:<

大於等於:>=

小於等於:<=

等於:== 注意區分賦值運算符的=

不等於:!=

注意:比較表達式的運算結果一定只有true/false

比較表達式可以作爲

(1)條件

(2)邏輯運算符的操作數

4、 邏輯運算符

邏輯運算符的操作數必須是布爾值,結果也是布爾值

邏輯與:&
運算規則:只有左右兩邊都爲true,結果才爲true。
例如:true & true 結果爲true
false & true 結果爲false
true & false 結果爲false
false & false 結果爲false
邏輯或:|
運算規則:只要左右兩邊有一個爲true,結果就爲true。

​ 求的就是個性,不同,兩個操作數不同時,結果爲真,如果相同就爲假

​ 例如:true | true 結果爲true
​ false | true 結果爲true
​ true | false 結果爲true
​ false | false 結果爲false
邏輯異或:^
​ 運算規則:只有左右兩邊不同,結果才爲true。
​ 例如:true ^ true 結果爲false
​ false ^ true 結果爲true
​ true ^ false 結果爲true
​ false ^ false 結果爲false

邏輯非:!
運算規則:布爾值取反
例如:!true 爲false
!false 爲true

短路與:&&
運算規則:只有左右兩邊都爲true,結果才爲true。
例如:true & true 結果爲true
true & false 結果爲false
false & ? 結果就爲false
它和邏輯與不同的是當&&左邊爲false時,右邊就不看了。

短路或:||
運算規則:只要左右兩邊有一個爲true,結果就爲true。
例如:true | ? 結果爲treu
false | true 結果爲true
false | false 結果爲false
它和邏輯或不同的是當||左邊爲true時,右邊就不看了。

開發中一般用短路與和短路或比較多

面試題:&& 和 &的區別?

&&當左邊爲false,右邊不計算

&不管左邊是true還是false,右邊都要計算

5、 條件運算符

? :

語法格式:

條件表達式 ? 結果表達式1 : 結果表達式2

注意條件表達式結果必須是布爾類型

運算規則:

整個表達式的結果:當條件表達式爲true時,就取結果表達式1的值,否則就取結果表達式2的值

代碼示例:

1boolean類型
boolean marry = true;
System.out.println(marry? "已婚" : "未婚");2)求最值
int i = 3;
int j = 5;
int max = i>=j ? i : j;
//當i>=j時,max就賦值爲i的值,否則就賦值爲j的值


(3)求三個數的最大值
//找出三個整數中的最大值
int x = 3;
int y = 2;
int z = 5;
	
int max = x>=y ? x : y;
//運行到這裏,max中存的是x,y中較大者
		
max = max >= z ? max : z;
		
System.out.println("max = " + max);

6、 位運算符

位運算符
效率很高,但是可讀性不好
因爲它是基於二進制補碼直接運算的。
數軸來移動 比較好點來理解 不要這樣理解右移除以2的幾次方左移乘以2的幾次方
用得好很高的效率 但可能很多程序員理解不好的

位運算符:操作數是整數
左移 << :右邊補0
右移 >> :左邊補0或1,原數最高位是1,就補1,原數最高位是0,就補0
無符號右移 >>>:左邊補0

二進制位 變化 移動

/**
 * 位運算符 - 移位
 * 1、>> 向右移位,使用方法爲 x >> n 表示 x 向右移動 n 位
 *      對於正數來說,向右移位時,高位補0,低位被擠掉
 *      對於負數來說,向右移位時,高位補1,低位被擠掉
 * 
 * 2、<< 向左移位,使用方法爲 x << n 表示 x 向左移動 n 位
 *      不論是正數還是負數,向左移位時,都是擠掉高位,低位補0
 * 
 * 3、>>> 無符號右移
 *      不論是正數還是負數,向右移位時,高位一律補0,低位被擠掉
 * 
 * 4、Java 中沒有 <<< 運算符 【劃重點】  有<<就行了
 */

eg:

public class BitOperator1 {

    public static void main(String[] args) {
        
        // 被 final 修飾的變量被稱作【最終變量】,它是最終的、不可更改的變量 【不要當做"常量"對待】
        final int x = 5 ; // 0b00000000_00000000_00000000_00000101
        System.out.println( x );
        // 嘗試再次爲 final 修飾的變量賦值
        // x = 6 ; // 錯誤: 無法爲最終變量x分配值

        // 將 最終變量 x 中存儲的數值向右移動1位後賦值給 y 變量
        int y = x >> 1 ; // 0b0_00000000_00000000_00000000_0000010
        System.out.println( y );

        int z = x << 1 ; // 0b0000000_00000000_00000000_00000101_0
        System.out.println( z );

        System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

        // -5【原碼】: 1000_0000_0000_0000_0000_0000_0000_0101
        // -5【反碼】: 1111_1111_1111_1111_1111_1111_1111_1010
        // -5【補碼】: 1111_1111_1111_1111_1111_1111_1111_1011
        final int m = -5 ; // 0b1111_1111_1111_1111_1111_1111_1111_1011
        System.out.println( m );

        int n = m >> 1 ; // // 0b1_1111_1111_1111_1111_1111_1111_1111_101
        //【補碼】1_1111_1111_1111_1111_1111_1111_1111_101
        //【反碼】1_1111_1111_1111_1111_1111_1111_1111_100
        //【原碼】1_0000_0000_0000_0000_0000_0000_0000_011
        System.out.println( n );

        System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

        int p = m << 1 ; //  0b111_1111_1111_1111_1111_1111_1111_1011_0
        //【補碼】111_1111_1111_1111_1111_1111_1111_1011_0
        //【反碼】111_1111_1111_1111_1111_1111_1111_1010_1
        //【原碼】100_0000_0000_0000_0000_0000_0000_0101_0
        System.out.println( p );

        System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

        int r = 0x7FFFFFFF ;
        System.out.println( r );
        int s = r << 1 ;
        System.out.println( s );

    }

}
public class BitOperator2 {

    public static void main(String[] args) {
        
        final int x = 5 ; // 0b00000000_00000000_00000000_00000101
        final int y = -5 ; // 0b1111_1111_1111_1111_1111_1111_1111_1011

        System.out.println( x >> 1 ); // 0b0_00000000_00000000_00000000_0000010
        System.out.println( y >> 1 ); // 0b1_1111_1111_1111_1111_1111_1111_1111_101

        System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

        System.out.println( x >>> 1 ); // 0b0_00000000_00000000_00000000_0000010
        System.out.println( y >>> 1 ); // 0b0_1111_1111_1111_1111_1111_1111_1111_101

    }

}

<<

​ 運算規則:左移幾位感覺就相當於乘以2的幾次方

​ 二進制補碼左移n位,右邊補0

右移:>>

​ 運算規則:右移幾位感覺就相當於除以2的幾次方

無符號右移:>>>

​ 運算規則:往右移動後,左邊空出來的位直接補0,不看符號位

/**
 * 位運算符 
 * 1、|  按位或 ( 逐位或 )
 * 2、&  按位與 ( 逐位與 )
 * 3、^ 按位異或 (逐位異或 )
 * 4、~ 按位取反 (逐位取反) 【注意連符號位也一起取反】
 */

eg:

public class BitOperator4 {

    public static void main(String[] args) {
        
        final int x = 5 ; // 0b00000000_00000000_00000000_00000101
        final int y = 7 ; // 0b00000000_00000000_00000000_00000111

        //【 5 】0b00000000_00000000_00000000_00000101
        //【 7 】0b00000000_00000000_00000000_00000111
        int a = x | y ; // 按位或: 0b00000000_00000000_00000000_00000111
        System.out.println( a );

        //【 5 】0b00000000_00000000_00000000_00000101
        //【 7 】0b00000000_00000000_00000000_00000111
        int b = x & y ; // 按位與: 0b00000000_00000000_00000000_00000101
        System.out.println( b );

        //【 5 】0b00000000_00000000_00000000_00000101
        //【 7 】0b00000000_00000000_00000000_00000111
        int c = x ^ y ; // 按位異或: 0b00000000_00000000_00000000_00000010
        System.out.println( c );

        System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

        int r = 5 ; // 0b00000000_00000000_00000000_00000101
        int s = 7 ; // 0b00000000_00000000_00000000_00000111
        System.out.println( "r = " + r + " , s = " + s );

        // int temp = s ; s = r ; r = temp ;
        r = r ^ s ; // 0b00000000_00000000_00000000_00000010
        s = r ^ s ; // 0b00000000_00000000_00000000_00000101
        r = r ^ s ; // 0b00000000_00000000_00000000_00000111

        System.out.println( "r = " + r + " , s = " + s );

        System.out.println( "~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~ ~" );

        int j = 5 ; // 0b00000000_00000000_00000000_00000101
        // 注意使用 ~ 按位取反時,會對整數的符號位也取反
        int k = ~j ; //0b11111111_11111111_11111111_11111010
        //【補碼】 11111111_11111111_11111111_11111010
        //【反碼】 11111111_11111111_11111111_11111001
        //【原碼】 10000000_00000000_00000000_00000110
        System.out.println( "j = " + j + " , k = " + k );

    }

}

按位與:&

​ 運算規則:

​ 1 & 1 結果爲1

​ 1 & 0 結果爲0

​ 0 & 1 結果爲0

​ 0 & 0 結果爲0

按位或:|

​ 運算規則:

​ 1 | 1 結果爲1

​ 1 | 0 結果爲1

​ 0 | 1 結果爲1

​ 0 & 0 結果爲0

按位異或:^

​ 運算規則:

​ 1 ^ 1 結果爲0

​ 1 ^ 0 結果爲1

​ 0 ^ 1 結果爲1

​ 0 ^ 0 結果爲0

按位取反:~

​ 運算規則:~0就是1

​ ~1就是0

如何區分&,|,^是邏輯運算符還是位運算符?

如果操作數是boolean類型,就是邏輯運算符,如果操作數是整數,那麼就位運算符。

總結

在這裏插入圖片描述

位運算符:操作數是整數

左移 << :右邊補0

右移 >> :左邊補0或1,原數最高位是1,就補1,原數最高位是0,就補0

無符號右移 >>>:左邊補0

按位與 & :二進制對應位置取與 ,同時爲1才爲1,否則爲0

按位或 | :二進制對應位置取或 ,有一個爲1就爲1

按位異或運算 ^ :二進制對應位置取異或 ,兩者不同才爲1

按位取反 ~ :二進制對應位置取反 ,原來是1,變爲0,原來是0變爲1

說明:位運算符都是機器數直接運算的

7、 運算符優先級

在這裏插入圖片描述

算符優先級:
(1)賦值類運算符是最低的,即賦值最後算
(2)條件運算符
(3)||-> &&-> |-> ^-> & 短路 邏輯
(4)比較運算符
(5)左移右移的位運算符 << >> >>> 無符號右移:>>>
(6)算術運算符
乘、除、模高於加和減
(7)自增,自減,以及按位取反,非 ! ~
(8).(面向對象用)和()

我們如果要準確的記憶每一種運算符的優先級是困難的。
我們遵循一個原則:
(1)表達式不要寫太複雜,可以分爲多行
(2)如果非要混合運算,那麼先算的用()括起來

關於&,|,^,看左右兩邊的操作數是boolean值,還是整數,來決定是邏輯運算符還是位運算符。
整數是位運算符 ^ 異或 運算符

提示說明:

(1)表達式不要太複雜

(2)先算的使用()

8、 運算符操作數類型說明

1、算術運算符

數字和單個字符可以使用算術運算符。

其中+,當用於字符串時,表示拼接。

2、賦值運算符

右邊的常量值、表達式的值、變量的值的類型必須與左邊的變量一致或兼容(可以實現自動類型轉換)或使用強制類型轉換可以成功。

3、比較運算符

其他的比較運算符都是隻能用於8種基本數據類型。

其中的==和!=可以用於引用數據類型的比較,用於比較對象的地址。(後面講)

int i = 10;
int j = 10;
System.out.println(i==j);//true

char c1 = '帥';
char c2 = '帥';
System.out.println(c1 == c2);//true

4、邏輯運算符

邏輯運算符的操作數必須是boolean值

5、條件運算符

?前面必須是條件,必須是boolean值

結果表達式1和結果表達式2要保持類型一致或兼容

6、位運算符

一般用於整數系列

以上運算符都是針對基本數據類型設計的。

能夠用於引用數據類型只有基本的賦值運算符=,和比較運算符中的==和!=。其他運算符都不能用於引用數據類型。

其中字符串類型還有一個+,表示拼接。

9、code

算術運算符

/*
運算符:
1、算術運算符
加:+
減:-
乘:*
除:/
	特殊:整數/整數,結果只保留整數部分
取模(取餘):%
	特殊:只看被模數的正負號
	被模數%模數
什麼是取模呢  取餘呢
2%3=2
正號:+
負號:-
自增 自己加自己不是的  是自己增加1
自增:++
	對於自增變量本身來說,都會+1.
	但是++在前還是在後,對於整個表達式的計算來說是不一樣的。
	++在前,先自增,然後取自增後變量的值,
	++在後,先取變量的值,然後變量自增。
	但是不管怎麼樣,自增變量的取值與自增操作一前一後一定是一起完成的。
自減:--
	類同自增

*/
class Test05_Arithmetic{
    public static void main(String[] args){
        int x = 10;
        int y = 3;

        //System.out.println("x + y = " + x + y);//變爲拼接
        System.out.println("x + y = " + (x + y));
        System.out.println("x - y = " + (x - y));
        System.out.println("x * y = " + (x * y));
        System.out.println("x / y = " + (x / y));
        System.out.println("x % y = " + (x % y));

        System.out.println("----------------------------------");
        //特殊:只看被模數的正負號
        System.out.println("5%2 = " + 5%2);//1
        System.out.println("-5%2 = " + -5%2);//-1
        System.out.println("5%-2 = " + 5%-2);//1
        System.out.println("-5%-2 = " + -5%-2);//-1

        System.out.println("----------------------------------");
        int a = -3;
        System.out.println(-a);//3

        System.out.println("----------------------------------");
        int i = 2;
        i++;
        System.out.println("i = " + i);//3

        int j = 2;
        ++j;
        System.out.println("j = " + j);//3

        System.out.println("----------------------------------");
        int m = 1;
        int n = ++m;//m先自增,然後把m的值取出來賦值給n
        System.out.println("m = " + m);//2
        System.out.println("n = " + n);//2

        System.out.println("----------------------------------");
        int p = 1;
        int q = p++;//(1)先取出p的值"1",先放到一個“操作數棧”,(2)然後p變量完成自增(3)把剛纔放在“操作數棧”中的值賦值給q
        System.out.println("p = " + p);//2
        System.out.println("q = " + q);//1
        System.out.println("q = " + (q = q++));//1
        System.out.println("q = " + q);//1
        System.out.println("----------------------------------");
        int z = 1;
        z = z++;//(1)先取出z的值"1",先放到一個“操作數棧”,(2)然後z自增,變爲2(3)把剛纔放在“操作數棧”中的值賦值給z
        System.out.println("z = " + z);//1
        System.out.println("z = " + z++);//1
        System.out.println("z = " + z);//2
        System.out.println("z = " + ++z);//3

        System.out.println("----------------------------------");
        int b = 1;
        int c = 2;
		/*
		第一個:b++
		(1)先取b的值“1”,先放到一個“操作數棧”,
		(2)緊接着b就自增了,b=2
		操作數棧
		第二步:++b
		(1)先b自增,b=3
		(2)緊接着再取b的值“3”,先放到一個“操作數棧”,
		第三步:++b
		(1)先b自增,b=4
		(2)緊接着再取b的值“4”,先放到一個“操作數棧”,
		第四步:c++
		(1)先取c的值“2”,先放到一個“操作數棧”,
		(2)緊接着c自增,c=3
		第五步:算乘 ++b和c++的乘法部分
		4*2 = 8 然後在壓回“操作數棧”,
		第六步:再算 b++ + ++b + 乘的結果
			1 + 3 + 8 = 12
		*/
        int d = b++ + ++b + ++b * c++;
        System.out.println("b = " + b);//4
        System.out.println("c = " + c);//3
        System.out.println("d = " + d);//12
    }
}

練習

class Test06_Exer3{
    public static void main(String[] args){
        int i = 1;
        int j = 2;
		/*
		第一步:++i
		(1)先自增,i=2
		(2)在取i的值“2”,放起來
		第二步:j
		(1)取j的值“2”,放起來
		第三步:++i
		(1)先自增,i=3
		(2)在取i的值"3",放起來
		第四步:求乘積
		2 * 3 = 6,結果放起來
		第五步:求和
		2 + 6 = 8
		*/
        System.out.println(++i + j * ++i);
    }
}
/*
已知一個三位數,例如:483,如何用代碼求出它的百位、十位、個位數
*/
class Test07_Exer4{
    public static void main(String[] args){
        int num = 483;

        int bai = num / 100;// 483/100 4
        //int shi = num/10%10;// 483/10 48  48%10 8
        int shi = num%100/10;// 483%100 83 83/10 8
        int ge = num % 10;// 483%10 3

        System.out.println(num + "的百位:" + bai + ",十位:" + shi +",個位:" + ge);
        //483的百位:4,十位:8,個位:3
    }
}
//字符串拼接
class Test08_Exer6{
    public static void main(String[] args){
        int no = 10;
        String str = "abcdef";
        String str1 = str + "xyz" + no;//abcdefxyz10

        str1 = str1 + "123";//abcdefxyz10123
        char c = '國';

        double pi = 3.1416;
        str1 = str1 + pi;//abcdefxyz101233.1416

        boolean b = false;
        boolean t = true;
        System.out.println("" + b + t);//falsetrue
        System.out.println(b + "" + t);//falsetrue
        /*
         System.out.println(b + t + "");
         Error:(22, 30) java: 二元運算符 '+' 的操作數類型錯誤
            第一個類型:  boolean
            第二個類型: boolean
        * */
        str1 = str1 + b;//abcdefxyz101233.1416false
        str1 = str1 + c;//abcdefxyz101233.1416false國
        String f = "false";
        System.out.println(b + f);//falsefalse
        System.out.println(f + b);//falsefalse

        System.out.println("str1 = " + str1);
    }
}
//什麼是求和  什麼是拼接
class Test08_Exer7{
    public static void main(String[] args){
		/*
		String str1 = 4;
		左邊是String字符串類型,右邊是4int類型,它們之間無法自動類型轉換
		*/
        //String str1 = 4;
        String str2 = 3.5f + "";
        System.out.println(str2);   //3.5
        System.out .println(3+4+"Hello!");  //7Hello!
        System.out.println("Hello!"+3+4); // Hello!34
        System.out.println('a'+1+"Hello!");   // 98Hello!
        System.out.println("Hello"+'a'+1);  //Helloa1
    }
}
class Test08_Exer8{
    public static void main(String[] args){
        short s = 5;
//        s = s-2;   //short - int,結果是int
        // int賦值給short Error:(8, 14) java: 不兼容的類型: 從int轉換到short可能會有損失

        byte b = 3;
//          b = b + 4;    //byte + int,結果是int
        //Error:(12, 17) java: 不兼容的類型: 從int轉換到byte可能會有損失
        b = (byte)(b+4);   //可以
        System.out.println(b);// 3+4 7
        char c = 'a';
        int  i = 5;
        float d = .314F;//非標準寫法,如果整數部分是0,可以省略0,但不能省略小數點
        double result = c+i+d;   //char + int + float,結果是float,然後自動升級爲double


        byte byte1 = 5;
        short short1 = 3;
//        short t = short1 + byte1;  //short + byte,結果是int
        //Error:(24, 26) java: 不兼容的類型: 從int轉換到short可能會有損失
        int t = short1 + byte1;  //short + byte,結果是int
        System.out.println(t);//8
    }
}

賦值運算符

/*
運算符:
2、賦值運算符
(1)基本的賦值運算符:=

賦值操作:永遠是把=右邊的常量值、變量中值、表達式計算的值賦值給=左邊的變量,
即=左邊只能是一個變量。

運算的順序:把右邊的整個表達式先算完,纔會做最後的賦值操作。

(2)擴展的賦值運算符
例如:
+=
-=
*=
/=
%=
...


*/
class Test09_Assign{
    public static void main(String[] args){
        int x = 1;
        int y = 2 ;
        int z = 3;
//        x + y = z;//=左邊只能是一個變量
        //Error:(31, 11) java: 意外的類型
        //  需要: 變量
        //  找到:    值

        byte b1 = 1;
        byte b2 = 2;
        //b2 = b1 + b2;//右邊byte + byte結果是int
        b2 += b1;//等價於  b2 = (byte)(b2 + b1);
        System.out.println("b1 = " + b1);//1
        System.out.println("b2 = " + b2);//3

        System.out.println("---------------------------");
        //運算的順序:把右邊的整個表達式先算完,纔會做最後的賦值操作。
        int i = 1;
        int j = 5;
        /*
        第一步 i++
        (1)先取i的值 放起來
        (2)i自增,i=2
        第二步 求和
        1 + 5  = 6
        第三步 乘
        j * (和) = 5 * 6 = 30
        第四步 賦值 把乘積賦值給j
         */
        j *= i++ + j;
        System.out.println("i = " +  i);//2
        System.out.println("j = " +  j);//30
    }
}

比較運算符

*
運算符:
3、比較運算符
大於:>
小於:<
大於等於:>=
小於等於:<=
等於:==
	注意,謹防與賦值的=混淆
不等於:!=

比較運算符,計算完後的結果只有兩個:true,false
說明比較運算符的表達式,可以作爲(1)判斷的條件(2)邏輯運算符的操作數

比較運算符能夠用於基本數據類型,不能用於引用數據類型。
除了==!=,關於引用數據類型時它倆的意義後面再講。
操作數幾元
一元運算符:操作數只有一個
	例如:a++  其中a就是操作數
		-a   其中a就是操作
二元運算符:需要兩個操作數
	例如:求和   a+b  其中a和b就是操作
		  比較大小  age>=18  其中的age和18都是操作數
三元運算符:需要三個操作數
	...
*/
class Test10_Compare{
    public static void main(String[] args){
		/*
		有一個變量age,表示年齡,判斷是否成年(滿足18歲)

		*/
        int age = 26;

        System.out.println("是否成年:" + (age>=18));//是否成年:true
//        System.out.println("是否成年:" + age>=18);//這是先字符串拼接的

		/*
		比較運算符作爲條件
		*/
        if(age >= 18){
            System.out.println("祝你玩得愉快!");
        }else{
            System.out.println("未成年不得進入!");
        }

		/*
		有一個變量,存儲的是boolean類型的值
		*/
        boolean flag = false;
        if(flag == true){//不會修改flag裏面的值
            System.out.println("條件成立1");
        }
        //與上面的語句是等價的
        if(flag){
            System.out.println("條件成立2");
        }

        if(flag = true){//不是比較,而是賦值,結果仍然是布爾值,只要是布爾值就可以作爲條件
            System.out.println("條件成立3");
        }
        System.out.println("flag = " + flag);

		/*
		有一個變量,存儲的是其他類型的值
		*/
        int num = 1;
        if(num == 1){
            System.out.println("num=1");
        }
        //true false  纔是  最終的情況
        //if(num = 1){//錯誤的,因爲num=1是賦值表達式,結果還是int,int值是不能作爲條件的
        //	System.out.println("num=1");
        //}
    }
}

邏輯運算符

/*
運算符:
4、邏輯運算符
邏輯與:&
	類似於:且
	true & true 結果爲true
	true & false 結果爲false
	false & true 結果爲false
	false & false 結果爲false

多個條件是否兩個都成立 兩個都滿足的
邏輯或:|
	類似於:或
	true | true 結果爲true
	true | false 結果爲true
	false | true 結果爲true
	false | false 結果爲false
	滿足一個  爲true
邏輯非:!
	類似於:取反
	!true 結果爲false
	!false 結果爲true
邏輯異或:^
	類似於:求不同
	true ^ true 結果爲false
	true ^ false 結果爲true
	false ^ true 結果爲true
	false ^ false 結果爲false
	求不同  不同的爲true   一樣的爲false
短路與:&&
	結果:和&是一樣的
	運算規則:如果&&的左邊已經是false,右邊就不看了
	true & true 結果爲true
	true & false 結果爲false
	false & ? 結果爲false
	false & ? 結果爲false
	段路運算
短路或:||
	結果:和|是一樣的
	運算規則:如果||左邊已經是true,右邊就不看了
	true | ? 結果爲true
	true | ? 結果爲true
	false | true 結果爲true
	false | false 結果爲false
*/
class Test11_Logic{
    public static void main(String[] args){
		/*
		判斷成績是否在70和80之間
		數學:70<=score<=80
		Java中:
		*/
        int score = -78;

		/*
		Test11_Logic.java:14: 錯誤: 二元運算符 '<=' 的操作數類型錯誤
                if( 70<=score<=80){
                             ^
		  第一個類型:  boolean   70<=score的運算結果是true或false
		  第二個類型: int
		1 個錯誤
		false<=80 int
		*/
        //if( 70<=score<=80){
        //	System.out.println("良好");
        //}

        if(70<=score & score<=80){
            System.out.println("良好");
        }

		/*
		假設成績合理範圍[0,100]
		判斷成績是否小於0 或 大於100,輸出成績有誤
		*/
        if(score<0 | score>100){
            System.out.println("成績有誤");
        }

		/*
		假設成績合理範圍[0,100]
		判斷成績是否在合理範圍內
		*/
        if(score>=0 & score<=100){

        }
        //或下面這麼寫
        if(!(score<0 | score>100)){

        }

        System.out.println(true ^ true);
        System.out.println(true ^ false);
        System.out.println(false ^ true);
        System.out.println(false ^ false);

		/*
		短路與:&&
		短路或:||
		*/
        int i = 1;
        int j;
		/*
		第一步:i++
		(1)先取i的值“1”,放起來
		(2)在i自增,i=2
		第二步:算比較
		放起來的“1” == 1比較,成立
		&&左邊是true,不會短路
		第三步:++i
		(1)先自增i=3
		(2)再取i的值“3”,放起來
		第四步:比較
		放起來的“3” == 2比較,結果是false,不成立
		第五步:
		左邊的true && 右邊的false運算,結果爲false,總的if不成立,走else
		*/
        //if(i++ == 1 && ++i == 2){
        //	j = 1;
        //}else{
        //	j = 2;
        //}

		/*
		第一步:i++
		(1)先取i的值“1”,放起來
		(2)在i自增,i=2
		第二步:算比較
		放起來的“1” == 1比較,成立
		||左邊是true,會發生短路,右邊不看了(++i == 2)沒運算

		第三步:
		true || ?,結果爲true,總的if成立
		*/
        if(i++ == 1 || ++i == 2){
            j = 1;
        }else{
            j = 2;
        }
        System.out.println("i = " + i);
        System.out.println("j = " + j);
    }
}

練習

class Test12_Exer1{
    public static void main(String[] args){
        int x = 1;
        int y = 1;
		/*
		第一步:x++
		(1)先取x的值“1”
		(2)再x自增x = 2
		第二步:比較
		用“1”與2比較, 1==2,不成立,false

		因爲&不是短路與,不管左邊是怎麼樣,右邊繼續

		第三步:++y
		(1)自增 y = 2
		(2)取y的值“2”
		第四步:比較
		用“2”與2比較  2 == 2,成立,true

		第五步:邏輯
		false & true,結果爲false,總的if不成立
		*/
        if(x++ == 2 & ++y==2){
            x = 7;
        }
        //&  兩個都要處理的
        System.out.println("x = " + x + ",y = " + y);//x = 2,y = 2
    }
}
class Test12_Exer2{
    public static void main(String[] args){
        int x = 1;
        int y = 1;
		/*
		第一步:x++
		(1)先取x的值“1”
		(2)再x自增x = 2
		第二步:比較
		用“1”與2比較, 1==2,不成立,false

		因爲&&是短路與,左邊爲false,右邊就不看了



		第三步:邏輯
		false & ?,結果爲false,總的if不成立
		*/
		//x=1 y=1
        if(x++ == 2 && ++y==2){
            x = 7;
        }
        System.out.println("x = " + x + ",y = " + y);//x = 2,y = 1
    }
}
class Test12_Exer3{
    public static void main(String[] args){
        int x = 1;
        int y = 1;
		/*
		第一步:x++
		(1)先取x的值“1”
		(2)再x自增x = 2
		第二步:比較
		用“1”與1比較, 1==1,成立,true

		中間是|,不是短路或,右邊要繼續
		第三步:++y
		(1)y先自增,y=2
		(2)再去y的值“2”
		第四步:比較
		用“2”與1比較  2==1,不成立,結果爲false


		第五步:邏輯
		true & false,結果爲true,總的if成立,要執行x = 7
		*/
		//
        if(x++ == 1 | ++y==1){
            x = 7;
        }
        System.out.println("x = " + x + ",y = " + y);//x = 7,y = 2
    }
}
class Test12_Exer4{
    public static void main(String[] args){
        int x = 1;
        int y = 1;
		/*
		第一步:x++
		(1)先取x的值“1”
		(2)再x自增x = 2
		第二步:比較
		用“1”與1比較, 1==1,成立,true

		中間是||,是短路或,左邊已經爲true,會發生短路現象,右邊不看了


		第五步:邏輯
		true & ?,結果爲true,總的if成立,要執行x = 7
		*/
		// x = 1  ; y =1
        if(x++ == 1 || ++y==1){
            x = 7;
        }
        System.out.println("x = " + x + ",y = " + y);//x = 7,y = 1
    }

class Test13_Exer{
    public static void main(String[] args){
        boolean x = true;
        boolean y = false;
        short z = 42;
		/*
		第一步:z++
		(1)先取z的值“42”
		(2)z自增 z=43
		第二步:比較
		用“42”與42比較,條件成立,true

		中間是&&,短路與,但是沒有滿足短路現象。右邊繼續
		第三步:
		取y的值false
		第四步:
		比較,用"false"與true比較,條件不成立,false
		第五步:
		true && false,結果爲false,if條件不成立,z++不執行
		*/
        if((z++==42) && (y==true))
            z++;

		/*
		||左邊:x=false,這是賦值運算,結果仍然是false
		中間||,是短路或,但是沒有滿足短路現象,右邊繼續
		右邊:
		++z:先自增z=44,然後取z的值“44”,然後與45進行比較,結果爲false
		左邊的false || 右邊的false,結果還是false,if不成立,z++不執行
		*/
        if((x=false) || (++z==45))
            z++;
        System.out.println("z = " + z);//44
    }
}
class Test13_Exer2{
    public static void main(String[] args){
        boolean x = true;
        boolean y = false;
        short z = 42;


		/*
		這裏y=true是賦值,結果還是true,表示條件成立,並且y的值已經變爲true
		*/
        if(y=true)
		/*
		第一步:z++
		(1)先取z的值“42”
		(2)z自增 z=43
		第二步:比較
		用“42”與42比較,條件成立,true

		中間是&&,短路與,但是沒有滿足短路現象。右邊繼續
		第三步:
		取y的值true
		第四步:
		比較,用"true"與true比較,條件成立,true
		第五步:
		true && true,結果爲true,if條件成立,z++執行
		z = 44
		*/
            if((z++==42) && (y==true))
                z++;

		/*
		||左邊:x=false,這是賦值運算,結果仍然是false
		中間||,是短路或,但是沒有滿足短路現象,右邊繼續
		右邊:
		++z:先自增z=45,然後取z的值“45”,然後與45進行比較,結果爲true
		左邊的false || 右邊的true,結果還是true,if成立,z++執行,z=46
		*/
        if((x=false) || (++z==45))
            z++;
        System.out.println("z = " + z);//46
    }
}

條件運算符

/*
運算符:
5、條件運算符,
因爲它是唯一的三元運算符,所以也稱爲三元運算符

條件表達式 ? 結果表達式1 : 結果表達式2

整個表達式包含三個部分。
運算規則:如果條件表達式成立,就取結果表達式1的值,否則就取結果表達式2的值

*/
class Test14_Condition{
    public static void main(String[] args){
        boolean marry = false;
        System.out.println(marry ? "已婚" : "未婚");

        //找出x和y中的最大值
        int x = 4;
        int y = 4;
        int max = x>=y ? x : y;
		/*
		等價於
		if(x>=y){
			max = x;
		}else{
			max = y;
		}
		*/
        System.out.println(x + "," + y + "中的最大值是:" + max);
        int a = 4;
        int b = 5;
        int m;
        if (a >= b){
            m = a;
        }else{
            m = b;
        }
        System.out.println(a + ","+  + b + ","+"m:" + m);
        int temp = a;
        a = b;
        b = temp;
        m = a>=b ? a : b;
        System.out.println();
        System.out.println(a + ","+  + b + ","+"m:" + m);


    }
}

位運算符

/*
運算符:(瞭解)
6、位運算符
效率很高,但是可讀性不好
因爲它是基於二進制補碼直接運算的。
數軸來移動 比較好點來理解  不要這樣理解右移除以2的幾次方
用得好很高的效率 但可能很多程序員理解不好的

左移:<<
	運算規則:<<幾位,就乘以2的幾次方
			二進制補碼左移n位,右邊補0
右移:>>
	運算規則:>>幾位,就除以2的幾次方
			二進制補碼右移n位,左邊補0還是1,看最高位
無符號右移:>>>
	運算規則:二進制補碼右移n位,左邊補0,對於負數來說,移完後,變爲正數
沒有 <<<    因爲就是<<  嗯嗯
按位與:&
	1 & 1 結果1
	1 & 0 結果0
	0 & 1 結果0
	0 & 0 結果0
按位或:|
	1 | 1 結果1
	1 | 0 結果1
	0 | 1 結果1
	0 | 0 結果0
按位異或:^
	1 ^ 1 結果0
	1 ^ 0 結果1
	0 ^ 1 結果1
	0 ^ 0 結果0
按位取反:~(一元運算符)
	~1爲0
	~0爲1

*/
class Test15_Bit{
    public static void main(String[] args){
		/*
		4的二進制:0000 0100
		4<<3:0 0100000
		*/
        System.out.println(4 << -3);//-2147483648 ???
        System.out.println(4 << -32);//4
        System.out.println(4 << 32);//4
        System.out.println(4 << 35);//32
        System.out.println(4 << 3);//等價於4乘以2的3次方,4*8=32

		/*
		32的二進制:0010 0000
		32>>4:0000 0010
		*/
        System.out.println(32 >>4);//等價於32除以2的4次方,32/16 =2

		/*
		-32的二進制:
			原碼:1010 0000
			反碼:1101 1111
			補碼:1110 0000
		-32>>4:1111 1110
			補碼:1111 1110
			反碼:1111 1101
			原碼:1000 0010
			負的  右移 補1 少多少補多少
		*/
        System.out.println(-32 >>4);// -2

        System.out.println(32 >>> 4);//和>>一樣,左邊補0   2
		/*
		-32的二進制:
			原碼:1000 0000 0000 0000 0000 0000 0010 0000
			反碼:1111 1111 1111 1111 1111 1111 1101 1111
			補碼:1111 1111 1111 1111 1111 1111 1110 0000
		-32>>>4:0000 1111 1111 1111 1111 1111 1111 1110
			最高位是0,是正數
		*/
        System.out.println(-32 >>> 4);//268435454

		/*
		32:0000 0000 0000 0000 0000 0000 0010 0000
		25:0000 0000 0000 0000 0000 0000 0001 1001
		32 & 25:0000 0000 0000 0000 0000 0000 0000 0000
		*/
        System.out.println(32 & 25);//0

		/*
		32:0000 0000 0000 0000 0000 0000 0010 0000
		25:0000 0000 0000 0000 0000 0000 0001 1001
		32 | 25:0000 0000 0000 0000 0000 0000 0011 1001
		*/
        System.out.println(32 | 25);//57

		/*
		32:0000 0000 0000 0000 0000 0000 0010 0000
		25:0000 0000 0000 0000 0000 0000 0001 1001
		32 | 25:0000 0000 0000 0000 0000 0000 0011 1001
		*/
        System.out.println(32 ^ 25);//57

		/*
		3:0000 0000 0000 0000 0000 0000 0000 0011
		~3:1111 1111 1111 1111 1111 1111 1111 1100
		補碼:1111 1111 1111 1111 1111 1111 1111 1100
		反碼:1111 1111 1111 1111 1111 1111 1111 1011
		原碼:1000 0000 0000 0000 0000 0000 0000 0100 -4
		*/
        System.out.println(~3);//-4
    }
}

運算符優先級

/*
運算符優先級:
(1)賦值類運算符是最低的,即賦值最後算
(2)條件運算符
(3)||-> &&-> |-> ^-> &  短路 邏輯
(4)比較運算符
(5)左移右移的位運算符  <<   >>   >>> 無符號右移:>>>
(6)算術運算符
	乘、除、模高於加和減
(7)自增,自減,以及按位取反,非   !  ~
(8).(面向對象用)和()

我們如果要準確的記憶每一種運算符的優先級是困難的。
我們遵循一個原則:
(1)表達式不要寫太複雜,可以分爲多行
(2)如果非要混合運算,那麼先算的用()括起來


關於&,|,^,看左右兩邊的操作數是boolean值,還是整數,來決定是邏輯運算符還是位運算符。
整數是位運算符  ^ 異或 運算符
*/
class Test16_Priority{
}

練習交換兩個變量的值、判斷是否閏年、求最大值

交換兩個變量的值

/*
交換兩個變量的值
藉助於第三個同樣類型的變量
a b c
c = a;
a = b;
b = a;
*/
class Test17_Swap{
    public static void main(String[] args){
        int x = 1;
        int y = 2;

		/*
		通用的方案:適用於任意的數據類型
				藉助於第三個通樣類型的臨時變量
		*/
        int temp = x;//x變量中值就賦值給了temp  temp = 1
        x = y;//再把y中的值放到x中,x = 2
        y = temp;//再把temp中的值賦值給y  y=1
        System.out.println("x = " + x);
        System.out.println("y = " + y);
        temp = x;
        x = y;
        y = temp;
//        x = 1;
//        y = 2;

		/*
		方案二:只適用於int等整數類型  byte short int long
		*/
        x = x ^ y;
        y = x ^ y;//(新的x) ^ 原來的y = (原來的x ^ 原來的y) ^ 原來的y = 原來的x  (求不同)
        x = x ^ y;//(新的x) ^ 新的y = (原來的x ^ 原來的y) ^ 原來的x = 原來的y
        System.out.println("x = " + x);
        System.out.println("y = " + y);
        // y = x ^ y ^ y; y = x; x = x ^ y ^ x;
        x = 1;
        y = 2;
		/*
		方案三:只適用於int等整數類型
			有風險,可能會溢出
		*/
        x = x + y;//有風險,可能會溢出  大了 超了
        y = x - y;//(新的x) - 原來的y = (原來的x + 原來的y)- 原來的y  = 原來的x
        x = x - y;//(新的x) - 新的y = (原來的x + 原來的y) - 原來的x = 原來的y
        System.out.println("x = " + x);
        System.out.println("y = " + y);

		/*
		以下不推薦
		*/
        x = 1;
        y = 2;
        x = x * y;//風險更大
        y = x / y;
        x = x / y;
    }
}

判斷是否閏年

/*
1、定義一個int類型變量,保存年份,判斷這個年份是否是閏年
注:判斷一年是否是閏年的標準:
       1)可以被4整除,但不可被100整除
       2)可以被400整除
	   */
class Test18_Exer{
    public static void main(String[] args){
        int year = 2000;

        boolean result = year%4==0 && year%100!=0 || year%400==0;
        System.out.println(year + (result?"是閏年":"不是閏年"));

        if ( year%4==0 && year%100!=0 || year%400==0){
            System.out.println(year + "是閏年");
        }
    }
}

求最大值

//2、定義三個int類型的變量,x,y,z,隨意賦值整數值,求最大值
class Test19_Exer{
    public static void main(String[] args){
        int x = 23;
        int y = 34;
        int z = 49;

        //int max = x>=y ? x : y;//運行完這句max中存的是x與y中的最大值
        //max = max >=z ? max : z;//用新的max與z比較

        int max = (x>=y ? x : y) >= z ? (x>=y ? x : y) : z;
        System.out.println("max = " + max);

        //還不如兩行的
//        int min = (x<=y ? x:y) <= z ? (x<=y ? x:y) : z;
//        System.out.println("min:" + min);
        int min = x<=y ? x:y;//行完這句min中存的是x與y中的最小值
        min = min<=z ? min :z;////用新的min與z比較
        System.out.println("min:" + min);
    }
}

code:https://github.com/liuawen/Learning-Java

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章