Java工程師培訓課(三)
夜光序言:
如果你真很喜歡一個人,
實在放不下的話,
那就繼續喜歡吧
或許你會感動ta
或許你會累到放手
可是
至少你沒有遺憾
正文:
上次的夜光練習:
- 使用程式判斷一個整數是偶數還是奇數
- 使用程式判斷假設今天是星期4,那麼問10天后的今天是星期幾?
- 將數值表示式使用java程式翻譯,並通過程式求出運算結果
其中int x=1;int y=2,int a=3,int b=4,int c=5;
案例一:
public static // 判斷一個整數一奇數還是偶數 int x = -100; // 奇數是,1,3,5...偶數是2,4,6...顯然整數除2能整除,也就%(取模)結果為0就是偶數。 int result = x % 2; System.out.println(result); // 使用判斷語句進行判斷。 if (result == 0) { System.out.println(x + "是偶數"); } else { System.out.println(x + "是奇數"); } } |
方案二 使用判斷該數結果是否是奇數。
(但是該演算法有問題,如果被判斷的整數為負數是否有效?)
public static void main(String[] args) { // 判斷一個整數一奇數還是偶數 int x = 1; // 奇數是,1,3,5...偶數是2,4,6...顯然奇數%的結果為1. int result = x % 2; System.out.println(result); // 使用判斷語句進行判斷。 if (result == 1) { System.out.println(x + "是奇數"); } else { System.out.println(x + "是偶數"); } } |
改進
public static void main(String[] args) { // 判斷一個整數一奇數還是偶數 int x = -1; // 奇數是,1,3,5...偶數是2,4,6...顯然奇數%的結果為1. int result = x % 2; System.out.println(result); // 使用判斷語句進行判斷。 if (result != 0) { System.out.println(x + "是奇數"); } else { System.out.println(x + "是偶數"); } } |
案例三:判斷星期
public static void main(String[] args) { // 設定今天是星期1,用int 1表示星期一,0表示星期天 int today = 1; // 十天後是星期幾?,一個星期是7天,7天之後又是星期1,可以用? int future = (today+10) % 7; if (future == 0) { System.out.println("10天后是星期天"); } else { System.out.println("10天后是星期:" + future); }
} |
案例4:
int x = 1; int y = 2; int a = 3; int b = 4; int c = 5; int result = (3 + 4 * x) / 5 - 10 * (y - 5) * (a + b + c) / x + 9* (4 / x + (9 + x) / y); System.out.println(result); // 442 |
賦值運算子
= , +=, -=, *=, /=, %=
運算子 |
運算 |
範例 |
結果 |
= |
賦值 |
a=3,b=2 |
a=3,b=2 |
+= |
加等於 |
a=3,b=3;a+=b; |
a=5,b=2; |
-= |
減等於 |
a=3,b=2,a-=b; |
a=1,b=2; |
*= |
乘等於 |
a=3,b=2,a*=b; |
a=6,b=2 |
/= |
除等於 |
a=3,b=2,a/=b; |
a=1,b=2; |
%= |
模等於 |
a=3,b=2,a%=b; |
a=1,b=2 |
a+=b 可以想象成 a=a+b;
變數宣告完了之後,可以使用賦值語句(assignment statement)給變數賦一個值,Java中使用等號(=)作為基本的賦值運算子(assignment operator),
格式如下:
variable = expression; 變數 = 表示式;
|
變數我們已經知道如何宣告,表示式具體如何定義?
表示式的定義:
表示式涉及到值(常量),變數和通過運算子計算出的值,以及他們組合在一起計算出的新值。
x =y+1;
例如:
public static void main(String[] args) { int x = 1; // 宣告int變數x, 賦值1給變數x int y = 0; // 宣告int變數y, 賦值0給變數y double area; // 宣告double變數area double radius = 1.0; // 宣告double變數radius,並賦值1.0給變數radius x = 5 * (3 / 2) + 3 * 2; // 將=右半部分表示式的計算結果賦值給變數x x = y + 1; // 將變數y和1的求和的值賦值給變數x area = radius * radius * 3.14159; // 將計算面積的值賦值給變數area } |
賦值運算子小問題
問題1: int x; Syst2intln(x = 1); 如何理解? 答:等價於 x=1; System.out.println(x); 注意:不能 1=x,變數名必須在賦值運算子的左邊。
|
問題二: int x; int y; int z; x = y = z = 100; 如何理解? 答:等價於 int x; int y; int z; z = 100; y = z; x = y;
|
問題三:short s1 = 1; s1= s1+1; s1+=1; 問:s1= s1+1; s1+=1; 與有什麼不同? 對於short s1 = 1; s1 = s1 + 1; 由於s1+1運算時會自動提升表示式的型別,所以結果是int型,再賦值給short型別s1時,編譯器將報告需要強制轉換型別的錯誤。 對於short s1 = 1; s1 += 1;由於 += 是java語言規定的運算子,java編譯器會對它進行特殊處理,因此可以正確編譯。
|
比較運算子
如何比較兩個值?使用比較運算子 3和5誰大,在java中如何比較?
比較運算子比較的兩邊運算元,結果都是boolean的,只有true和false兩種結果。
運算子 |
運算 |
例子 |
結果 |
== |
相等於 |
4= =3 |
false |
!= |
不等於 |
4!= 3 |
true |
< |
小於 |
4 < 3 |
flase |
> |
大於 |
4>3 |
true |
<= |
小於等於 |
4<=3 |
false |
>= |
大於等於 |
4>=3 |
true |
Instanceof |
檢查是否是類的物件 |
"hello"instanceof String |
true |
注意的細節:
1.使用比較運算子的時候,要求兩種資料型別必須一致。
byte、short、char 會自動提升至int。
邏輯運算子
什麼是邏輯運算子?連線比較運算子的符號稱之為邏輯運算子。那麼為什麼要連線比較運算子? 舉例:當你去公司應聘,招聘要求,男性(判斷為真),並且開發經驗1年(判斷為假)那麼,我們還適合去面試嗎,不能,因為只滿足了一項,總體是不滿足的(總體結果為假)。
邏輯運算子用於對boolean型結果的表示式進行運算,運算的結果都是boolean型。我們的比較運算子只能進行一次判斷,對於對此判斷無能為力,那麼邏輯運算子就可以經將較運算子連線起來。
邏輯運算子用於連線布林型表示式,在Java中不可以寫成3<x<6,應該寫成x>3 & x<6 。
“&”和“&&”的區別:單與時,左邊無論真假,右邊都進行運算;雙與時,如果左邊為真,右邊參與運算,如果左邊為假,那麼右邊不參與運算。
“|”和“||”的區別同理,雙或時,左邊為真右邊不參與運算。
“ ^ ”異或與“|”或的不同之處是:當左右都為true時,結果為false。
& 與 | 或 ^ 異或 ! 非
1、& 與
true & true = true ; false & true= false; true & false = false; false & false= false;
|
總結 & 符號特點
& : 只要兩邊的boolean 表示式結果,有一個false.那麼結果就是false
只有兩邊都為true ,將結果為true.
2、| 或
true | true =true; ture | false =true; false | true =true; false | false =flase; |
總結 | : 兩邊只要有一個為真結果就為真,當兩邊同為假時結果才為假.
3、^ 異或
true ^ true =false; ture ^ false =true; false ^ true= true; false ^ false=flase; |
^ : 兩邊相同結果是false
兩邊不同結果是true;
4、! 非
!true = false !false= true
|
5、&& 短路
研究發現,&運算只有兩邊全為真的時候,結果才為真,那麼當左邊為假的時候就沒有必要在進行判斷,&&就產生了。
int a =4;
a >3 && a< 6;
a >3 & a< 6 ;
在這種情況下世沒有區別的
如果:
a =2
a >3 & a< 6 2大於 3 為假, 接著運算 2 小於6 為真,總的結果為假
a >3 && a< 6; 此時a 不大於3 結果為false 右邊不運算了.即短路.所以&& 比& 效率稍微高了一點.
public static void main(String[] args) { int x = 0; int y = 1; if (x == 0 && y == 1) { System.out.println(x + y); } } |
位運算子
按位操作符用來操作整數基本資料型別中的單個位元(bit),就是二進位制,按位操作符會對兩個引數中對應的位(bit)執行布林運算,最終生成一個結果。按位操作符來源於C語言面向底層的操作,Java設計的初衷是嵌入式電視機機頂盒,所以面向底層的操作也保留了下來。
任何資訊在計算機中都是以二進位制的形式儲存的,”&”、“|”、“^”除了可以作為邏輯運算子也可以作為位運算子。位運算是直接對二進位制進行運算。他們對兩個運算元中的每一個二進位制位都進行運算。例如int是由32個二進位制陣列成,因此使用位運算子可以對整數值的二進位制數進行運算。
位(bit)運算子:
位運算子
|
運算子含義
|
& |
與(AND) |
| |
或(OR) |
^ |
異或 |
~ |
取反 |
規則:
可以把1當做true 0當做false
只有參與運算的兩位都為1,&運算的結果才為1,否則就為0。
只有參加運算的兩位都是0,| 運算的結果才是0,否則都是1。
只有參加運算的兩位不同,^ 運算的結果才為1,否則就為0。
1、& 與運算
& 參見運算的兩位數都為1,&運算子結果才為1,否則就為0。
6&3
00000000 |
00000000 |
00000000 |
00000110 |
6 |
00000000 |
00000000 |
00000000 |
00000011 |
3 |
00000000 |
00000000 |
00000000 |
00000010 |
& =2 |
2、| 或運算
| 參與運算的兩位都為0,|運算的結果才為0,否則就為1。
00000000 |
00000000 |
00000000 |
00000110 |
6 |
00000000 |
00000000 |
00000000 |
00000011 |
3 |
00000000 |
00000000 |
00000000 |
00000111 |
| =7 |
|
|
|
|
|
3、^ 異或運算
^只有參加運算的兩位不同,^運算的結果才為1,否則就為0。
00000000 |
00000000 |
00000000 |
00000110 |
6 |
00000000 |
00000000 |
00000000 |
00000011 |
3 |
00000000 |
00000000 |
00000000 |
00000101 |
^ =5 |
- ~ 反碼
就是取反,二進位制只有1和0,取反就是如果為1,取反就是0,如果是0,取反就是1。
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
6 |
1111-1111 |
1111-1111 |
1111-1111 |
1111-1001 |
取反 -7 |
System.out.println(~6);//-7
結論:當參與取反的數值是正數時,把對應的值加上負號,再-1;
當參與取反的數值是負數時,把對應的值加上負號,再-1;
負數的表現形式就是對應的正數取反,再加1。負數的最高位肯定是1。
4、負數表示
負數對應的正數的二進位制-1,然後取反。
-6
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
6 |
1111-1111 |
1111-1111 |
1111-1111 |
1111-1001 |
取反 |
1111-1111 |
1111-1111 |
1111-1111 |
1111-1010 |
加1 |
5、異或特點
一個數異或同一個數兩次,結果還是那個數. 用處一個簡單的加密思想.
6^3^3
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
6 |
0000-0000 |
0000-0000 |
0000-0000 |
0000-0011 |
^3 |
0000-0000 |
0000-0000 |
0000-0000 |
0000-0101 |
|
0000-0000 |
0000-0000 |
0000-0000 |
0000-0011 |
^3 |
0000-0000 |
0000-0000 |
0000-0000 |
0000-0110 |
結果是6 |
除了這些位運算操作,還可以對資料按二進位制位進行移位操作,Java的移位運算子有三種。
練習:取出一個二進位制的某一段。
使用異或(^)資料對資料加密
對兩個變數的值進行互換。
方式1:
對兩個變數進行值交換(不能使用第三個變數)
方式2:
兩個數相加的時候,值有可能超出int表示範圍,不推薦。
方式3:
該方式雖然效率高,而且避免了超出int值,但是可讀性較差。
三種方式都可以對兩個變數的值進行交換,但是推薦使用第一種。(面試除外)
移位操作符
<< 左移
>> 右移
>>> 無符號右移
位運算子 |
||
運算子 |
運算 |
範例 |
<< |
左移 |
3 << 2 = 12 --> 3*2*2=12 |
>> |
右移 |
3 >> 1 = 1 --> 3/2=1 |
>>> |
無符號右移 |
3 >>> 1 = 1 --> 3/2=1 |
& |
與運算 |
6 & 3 = 2 |
| |
或運算 |
6 | 3 = 7 |
^ |
異或運算 |
6 ^ 3 = 5 |
~ |
反碼 |
~6 = -7 |
位運算子的細節 |
|
<< |
空位補0,被移除的高位丟棄,空缺位補0。 |
>> |
被移位的二進位制最高位是0,右移後,空缺位補0; 最高位是1,空缺位補1。 |
>>> |
被移位二進位制最高位無論是0或者是1,空缺位都用0補。 |
& |
二進位制位進行&運算,只有1&1時結果是1,否則是0; |
| |
二進位制位進行 | 運算,只有0 | 0時結果是0,否則是1; |
^ |
任何相同二進位制位進行 ^ 運算,結果是0;1^1=0 , 0^0=0
不相同二進位制位 ^ 運算結果是1。1^0=1 , 0^1=1 |
技巧:可以理解為二進位制1就是true,0就是false。
案例:
1、左移 (算術移位)
3<< 2 是如何在計算機裡是實現的?
首先將3轉換為2進位制,
00000000 |
00000000 |
00000000 |
00000011 |
3 的二進位制 |
||
00000000 |
00000000 |
00000000 |
000011 |
左移2位,砍掉高位 |
||
0000 0000 |
0000 0000 |
0000 0000 |
0000 1100 |
低位補0 |
結果是12,所以3<<2 =12;
結論:左移就相當於乘以2的位移個數次冪.
2、右移
6>>2
00000000 |
00000000 |
00000000 |
00000110 |
6的二進位制 |
||
000000 |
00000000 |
00000000 |
00000001 |
右移10被砍掉 |
||
00000000 |
00000000 |
00000000 |
00000001 |
高位補0 |
結果是1,所以6>>2 =1;
結論一個數往左移越移越大,往右邊移越來越小.
推論
3<<2=12; 3<<1=6 ; 3<<3=24;
3*4=12 ; 3*2=6; 3*8=24;
3*22=12; 3*21=6 3*23 =24;
結論往左移幾位就是乘以2的幾次冪。
右移規律
6>>2=1 ;6>>1=3 ;
6/4=1 ; 6/2=3 ;
右移兩位就是除以 2的2次方,右移一位就是除以 2的一次方。
總結 :>> 是除以2的移動位數次冪
<< 是乘以2的移動位數次冪
用處:最快的運算是位運算。
練習:最有效率的方式算出2乘以8等於幾?
3、無符號右移 (邏輯移位)
通過演示發現右移時高位就空了出來, >> 右移時高位補什麼要按照原有 資料的最高位來決定。
1111-1111 1111-1111 1111-1111 1111-1010 -6>>2
1111-1111 1111-1111 1111-1111 1111-0010
最高位補什麼要看原有最高位是什麼
那麼使用>> 後原來是最高位1 的那麼空出來的最高位還是1 的,是0的還是0。
如果使用>>> 無論最高位是0還是1 空餘最高位都拿0 補,這就是無符號右移。
1111-1111 1111-1111 1111-1111 1111-1010 -6>>>2
001111-1111 1111-1111 1111-1111 1111-10
結果是;1073741822
三元運算子
格式
(條件表示式)?表示式1:表示式2;
如果條件為true,運算後的結果是表示式1;
如果條件為false,運算後的結果是表示式2;
示例:
1獲取兩個數中大數。
int x=3,y=4,z;
z = (x>y)?x:y;//z變數儲存的就是兩個數的大數。
int x = 1; int y = 2; int z; z = x > y ? x : y; System.out.println(z); //2 |
2判斷一個數是奇數還是偶數。
int x=5; System.out.println((x%2==0?"偶數":"奇數")); |
- 運算子的優先順序與結合性
夜光:作業
- 按照標準步驟完成hello world列印。
- 如果定義一個變數,如何使用變數。
- 基本資料型別有哪些?
- 'a'+1,結果是什麼?為什麼?都做了什麼事情呢?
- ++在前,在後的區別?
- short s = 3; s = s+2; s+=2,有什麼區別,為什麼?
- &和&&的區別?