Java架构师成长之道之Java数据计算
Java架構(gòu)師成長之道之Java數(shù)據(jù)計算
Java架構(gòu)師成長之道3.1 Java數(shù)據(jù)計算概述
計算機最主要的任務就是完成生產(chǎn)生活中的各種數(shù)據(jù)的運算,在Java中提供了諸多的運算符來完成相關(guān)數(shù)據(jù)的運算,在日常程序開發(fā)中最常用的有算術(shù)運算符、自增運算符、關(guān)系運算符、邏輯運算符以及三目運算符,在JDK源碼中會使用到基于二進制的位運算符。
在了解具體運算符的使用之前,先了解關(guān)于數(shù)據(jù)計算的幾個概念
package net.ittimeline.java.core.operator; import static java.lang.System.out; /*** 數(shù)據(jù)計算的相關(guān)概念* 運算符:數(shù)據(jù)執(zhí)行的運算類型,例如算術(shù)、邏輯、關(guān)系、位運算* 操作數(shù):參與運算的數(shù)據(jù),例如2,(3+2)都是操作數(shù)* 表達式:由操作數(shù)和運算符組成,通常是完成某種業(yè)務數(shù)據(jù)計算而設計的,例如計算圓的面積* 優(yōu)先級:在各種運算符參與運算時,有不同的執(zhí)行順序,由它們的優(yōu)先級決定,可以使用()改變優(yōu)先級* 結(jié)合性:執(zhí)行運算的方向,例如從左到右或者從右到左* @author liuguanglei 18601767221@163.com* @create 2019-07-30 11:51* @website www.ittimeline.net* @since JDK11.03*/ public class OperatorConceptTest {public static void main(String[] args) {// 3+5就是表達式,3,5就是操作數(shù)int result=3+5;System.out.println("result ="+result);/*** 算術(shù)運算的優(yōu)先級是先乘除后加減* 可以使用()改變優(yōu)先級*/int precedence=(45+5)/5*10;out.println("precedence = "+precedence);} }-
運算符:指定數(shù)據(jù)執(zhí)行的運算類型,例如算術(shù),邏輯,關(guān)系,比較,位運算等等
-
操作數(shù):就是參與運算的數(shù)據(jù),例如2,(3+2)都是一個操作數(shù)
-
表達式:由操作數(shù)和運算符組成,通常都是完成某種業(yè)務數(shù)據(jù)計算而設計的,例如計算圓的面積等等。
-
優(yōu)先級:在各種運算符參與運算時,有不同的執(zhí)行順序,由它們的優(yōu)先級決定,可以使用()來改變執(zhí)行的順序
-
結(jié)合性:執(zhí)行計算的方向,一般是從左到右,但是賦值運算是從右到左。
3.2 算術(shù)運算符
算術(shù)運算就是數(shù)學意義上的加減乘除以及取模運算,Java中支持的算術(shù)運算符包含加法(+)、減法(-)、乘法(*)、除法(/)、和取模(/)
- 算術(shù)運算符的優(yōu)先級是先乘除,后加減。
- 算術(shù)運算符的結(jié)合性是從左到右
- 算術(shù)運算計算結(jié)果的類型是參與運算的最大數(shù)據(jù)類型,例如整數(shù)和浮點數(shù)運算的結(jié)果是浮點型
- 賦值(=)時會進行自動類型轉(zhuǎn)換
算術(shù)運算案例
package net.ittimeline.java.core.operator.arithmetic;/*** 算術(shù)運算符* Java中的算術(shù)運算符支持數(shù)學意義的+ - * /以及取模(%)運算(求余數(shù))** @author liuguanglei 18601767221@163.com* @create 2019-07-28 09:40* @website www.ittimeline.net* @since JDK11.03*/ public class ArithmeticDivideTest {/*** 除法運算* @param args*/public static void main(String[] args) {//算術(shù)計算的結(jié)果的數(shù)據(jù)類型是參與運算的最大數(shù)據(jù)類型int source=12;int target=5;//int和int運算的結(jié)果是intint result=source/target;System.out.println("result = "+result);//算術(shù)運算符結(jié)合性是從左向右運算result=source/target*target;//result=10System.out.println("result = "+result);//賦值時會執(zhí)行自動類型轉(zhuǎn)換double dblResult=source/target;//運算結(jié)果是2.0System.out.println("dblResult ="+dblResult);//double和int運算結(jié)果是double//通過強制類型轉(zhuǎn)換將int轉(zhuǎn)換為doubledblResult=(double) source/target;//獲取精確的運行結(jié)果System.out.println("dblResult ="+dblResult);} }取模運算是求余數(shù),開發(fā)中通常用于判斷數(shù)據(jù)是否能夠整除。取模也會作為數(shù)據(jù)庫中間件MyCAT,ShardingJDBC實現(xiàn)取模算法。
- 取模運算結(jié)果的符號類型(正負)和被模數(shù)一致
- 整數(shù)和浮點數(shù)可以進行取模運算
取模運算應用案例:將五位整數(shù)反轉(zhuǎn)
package net.ittimeline.java.core.operator.arithmetic;/*** 取模運算案例* 將一個五位整數(shù)反轉(zhuǎn)* 例如12345變成54321* @author liuguanglei 18601767221@163.com* @create 2019-08-03 09:39* @website www.ittimeline.net* @since JDK11.03*/ public class ArithmeticRemainderApp {public static void main(String[] args) {int number=12345;System.out.println("反轉(zhuǎn)之前的五位整數(shù)是"+number);//首先使用取模運算獲取各個位的數(shù)字//個位int theUnit=number/10000;//十位int decade=number/1000%10;//百位int hundreds=number/100%10;//千位int kilobit=number%100/10;//萬位int myriabit=number%100%10;int invert=myriabit*10000+kilobit*1000+hundreds*100+decade*10+theUnit;System.out.println("反轉(zhuǎn)之后的五位整數(shù)是"+invert);} }使用基本數(shù)據(jù)類型的包裝類、字符串數(shù)組以及算術(shù)運算根據(jù)距離和時間計算速度
package net.ittimeline.java.core.operator.arithmetic;/*** @author liuguanglei 18601767221@163.com* @create 2019-07-30 15:44* @website www.ittimeline.net* @since JDK11.03*/ public class Velocity {public static void main(String[] args) {//實例化數(shù)組args=new String[]{"1200","300"};//數(shù)組中需要兩個元素if(args.length<2){System.err.println("需要倆參數(shù)");//系統(tǒng)異常退出System.exit(1);}//使用包裝類將字符串轉(zhuǎn)換為floatfloat distance=Float.parseFloat(args[0]);//args[0]表示訪問數(shù)組的第一個元素//args[1]表示訪問數(shù)組的第二個元素float time=Float.parseFloat(args[1]);//float和float運算的類型是floatSystem.out.print("Velocity = ");System.out.print(distance/time);} }3.3 自增(自減)運算符
自增運算符主要用于變量自增1,用于變量自增1的運算符是++,但是++可以放在變量前面,也可以放在變量后面,放在前面時,變量先自增1,然后再參與運算,++放在變量的后面,變量先運算,再自增1。
自減運算符使用--表示,用于變量自減1,也可以放在變量的前面和后面,分別表示先減1,再參與運算和先參與運算,再減1。
- 自增(自減)運算符不會改變變量本身的數(shù)據(jù)類型,因此在運算時需要考慮當前數(shù)據(jù)類型的極限值
- 自增(自減)運算符如果是一條單獨的語句,前置++(--)和后置++(--)的效果是一樣的
自增運算符案例
package net.ittimeline.java.core.operator.autoincrement;/*** 前置++,后置++* 作用是針對整型變量加1* 自增運算不會改變變量本身的數(shù)據(jù)類型* @author liuguanglei 18601767221@163.com* @create 2019-07-28 10:32* @website www.ittimeline.net* @since JDK11.03*/ public class AutoincrementAddTest {public static void main(String[] args) {//自增運算符是單獨的語句,前置++和后置++的結(jié)果是一樣的int tmp=10;tmp++;System.out.println("tmp = "+tmp);int val=10;++val;System.out.println("val = "+val);int num=10;//后置++,先運算,后自增1int result=num++;//result=10System.out.println("result = "+result);//num=11System.out.println("num ="+num);int source=10;//前置++ 先自增1,后運算result=++source;//result=11System.out.println("result ="+result);//source=11System.out.println("source ="+source);short shortVal=10;//shortVal的類型還是shortSystem.out.println(shortVal++);byte byteVal=10;//byteVal的數(shù)據(jù)類型還是byteSystem.out.println(byteVal++);} }自減運算符應用案例
package net.ittimeline.java.core.operator.autoincrement;/*** 自減運算符* @author liuguanglei 18601767221@163.com* @create 2019-07-28 10:42* @website www.ittimeline.net* @since JDK11.03*/ public class AutoincrementSubTest {/*** 自減運算符* @param args*/public static void main(String[] args) {int num=10;//先運算,后減1int result=num--;System.out.println("result = "+result);System.out.println("numb = "+num);int source=10;//先減1再運算int target= --source;System.out.println("target = "+target);System.out.println("source = "+source);} }自增(自減)運算符的常用應用場景就是在for循環(huán)中改變循環(huán)條件的值。
package net.ittimeline.java.core.operator.autoincrement;/*** 自增和自減運算符的應用場景** @author liuguanglei 18601767221@163.com* @create 2019-08-03 09:23* @website www.ittimeline.net* @since JDK11.03*/ public class AutoincrementApp {public static void main(String[] args) {System.out.println("自增運算符的應用場景");//自增運算符的應用場景//定義一個字符串String content="Java架構(gòu)師成長之道";//將字符串轉(zhuǎn)換為字符數(shù)組char[] contents=content.toCharArray();//循環(huán)遍歷字符數(shù)組 這里的c++表示將循環(huán)的初始條件自增1for (char c =0;c<content.length();c++){System.out.print(contents[c]+" ");}//自減運算的應用場景System.out.println("自減運算的應用場景");String car="法拉利拉法";char[] carDesc=car.toCharArray();for(int i=carDesc.length-1;i>=0;i--){System.out.print(carDesc[i]+"");}} }自增自減運算符復雜案例
package net.ittimeline.java.core.operator.autoincrement;/*** 自增運算符復雜案例** @author liuguanglei 18601767221@163.com* @create 2019-08-03 09:40* @website www.ittimeline.net* @since JDK11.03*/ public class AutoIncrementComplexTest {public static void main(String[] args) {int i = 10;int j = 20;// i++ 等價于i+=1 等價于i=int k = i++;//k=10System.out.println("k = " + k);//i =11System.out.println("i = " + i);k = ++i;//k = 12System.out.println("k = " + k);//i =12System.out.println("i = " + i);k = j--;//k=20System.out.println("k =" + k);//j=19System.out.println("j = " + j);k=--j;//k=18System.out.println("k = " + k);//j=18System.out.println("j = " + j);}}自增運算符的本質(zhì):讓變量自增的三種方式
package net.ittimeline.java.core.operator.autoincrement;/*** 自增運算的本質(zhì)** @author liuguanglei 18601767221@163.com* @create 2019-08-03 10:33* @website www.ittimeline.net* @since JDK11.03*/ public class AutoincrementEssence {public static void main(String[] args) {int number = 12;number++;System.out.println("number = " + number);//等價于number = 12;number += 1;System.out.println("number = " + number);//等價于number=12;number=number+1;System.out.println("number = " + number);} }3.4 賦值運算符
賦值通常是給變量賦值,Java中使用"="來表示賦值,而"=="表示相等,賦值是將=右邊的值或者表達式賦值給左邊的變量。
- 當賦值號(=)兩邊的數(shù)據(jù)類型不一致時,可以使用自動類型轉(zhuǎn)換或者強制類型轉(zhuǎn)換進行處理
- 支持連續(xù)賦值,即同時聲明并賦值多個變量
- 賦值運算不會改變變量本身的數(shù)據(jù)類型
JDK提供了java.util.Random類用于生成隨機數(shù),詳細的使用說明可以查閱JDK API文檔,后續(xù)在編寫應用案例時,可以使用它來生成測試數(shù)據(jù)。
package net.ittimeline.java.core.operator.assignment;import java.util.Random;/***產(chǎn)生0-99之間的隨機數(shù)* @author liuguanglei 18601767221@163.com* @create 2019-07-28 10:59* @website www.ittimeline.net* @since JDK11.03*/ public class RandomTest {public static void main(String[] args) {/*** 創(chuàng)建一個隨機數(shù)* 88表示初始種子,種子相同,每次產(chǎn)生的序列相同,種子不同,每次產(chǎn)生的序列不同* */Random random=new Random(88);//生成0-99之間的整數(shù)int left=random.nextInt(100);int right=random.nextInt(100);System.out.println("left = "+left+" right ="+right);}}賦值運算符還可以可算術(shù)運算符結(jié)合使用,例如+= ,-=,*=,/=,%=。
package net.ittimeline.java.core.operator.assignment; import static java.lang.System.out;import java.util.Random;/*** 算術(shù)運算與賦值運算結(jié)合運算** @author liuguanglei 18601767221@163.com* @create 2019-07-29 14:02* @website www.ittimeline.net* @since JDK11.03*/ public class MathOps {public static void main(String[] args) {//創(chuàng)建一個隨機數(shù)對象Random random=new Random(88);int i,j,k;//隨機產(chǎn)生一個1-100之間的整數(shù)j=random.nextInt(100)+1;k=random.nextInt(100)+1;out.println("j = "+j);out.println("k = "+k);i=j+k;out.println("j + k = "+i);i=j-k;out.println("j - k = "+i);i=j*k;out.println("j * k = "+i);i=j/k;out.println("j / k = "+i);i=j%k;out.println("j % k = "+i);j%=k;out.println("j %= k "+j);float u,v,w;v=random.nextFloat();w=random.nextFloat();out.println("v = "+v);out.println("w = "+w);u=v+w;out.println("v + w = "+u);u=v-w;out.println("v - w = "+u);u=v*w;out.println("v * w = "+u);u=v/w;out.println("v / w = "+u);u+=v;out.println("u+v = "+u);u-=v;out.println("u-v = "+u);u*=v;out.println("u*v = "+u);u/=v;out.println("u/v = "+u);} }復雜的賦值運算符
package net.ittimeline.java.core.operator.assignment;/*** 賦值運算符的復雜案例* 開發(fā)中盡量將表達式寫的簡單明了,有利于程序的維護* @author liuguanglei 18601767221@163.com* @create 2019-08-03 11:24* @website www.ittimeline.net* @since JDK11.03*/ public class AssignmentComplex {public static void main(String[] args) {int m=2;int n=3;/*** 拆解表達式* n*=m++* n=n*m++* n=3*2* n=6* m=3*/n*=m++;System.out.println("n = "+n);System.out.println("m = "+m);n=4;/*** 拆解表達式* n+=(n++)+(++n);* n=n+(n++)+(++n)* n=4+4+6* n=14*/n+=(n++)+(++n);System.out.println("n = "+n);} }3.5 JDK1.5新特性-靜態(tài)導入
- 靜態(tài)導入是使用import static關(guān)鍵字加上類名[.變量名][.方法名],其中[.變量名]和[.方法名]是可選的,如果沒有,默認就是導入類的所有變量和方法到當前類中,這樣就可以直接在當前類中使用。
使用靜態(tài)導入和SimpleDateFormat實現(xiàn)輸出當前日期
package net.ittimeline.java.core.operator; import java.text.SimpleDateFormat; import java.util.Date;import static java.lang.System.out; /*** 靜態(tài)導入** @author liuguanglei 18601767221@163.com* @create 2019-07-29 13:48* @website www.ittimeline.net* @since JDK11.03*/ public class HelloDate {/*** 聲明日期格式*/public static final String PATTERN="yyyy-MM-dd HH:mm:ss";public static void main(String[] args) {//創(chuàng)建日期格式化對象SimpleDateFormat simpleDateFormat=new SimpleDateFormat(PATTERN);String now =simpleDateFormat.format(new Date());//顯示輸出當前日期out.print(now);} }3.6 關(guān)系運算符
關(guān)系運算符用于判斷數(shù)據(jù)的關(guān)系,Java中常用的關(guān)系運算符有大于(>),小于(<),等于(==),不等于(!=),大于等于(>=),小于等于(<-=)。
- 關(guān)系運算符的運算結(jié)果是boolean類型,也就是true或者false
- 相等性用==表示,而不是=
- >=表示大于或者等于,>=表示小于或則等于
- >,>=,<,<=只能用在基本數(shù)據(jù)類型的數(shù)值類型之間進行比較
- ==可以使用在基本數(shù)據(jù)類型和引用類型之間相等性判斷
==和=的差別
package net.ittimeline.java.core.operator.relation;/*** ==和=的差別* @author liuguanglei 18601767221@163.com* @create 2019-08-03 11:36* @website www.ittimeline.net* @since JDK11.03*/ public class Equals {public static void main(String[] args) {int i=10;int j=20;//== 判斷相等性,運算結(jié)果是falseSystem.out.println("i == j = "+(i==j));//=表示將右邊的值或者表達式賦值給左邊的變量System.out.println("i = j = "+(i=j));} }在使用關(guān)系運算符之前先對之前的輸出語句System.out.println()結(jié)合JDK5.0新特性之靜態(tài)導入
做一個更加"簡短"的輸出。
然后借助JDK的Random類生成兩個1-100以內(nèi)的隨機整數(shù),用關(guān)系運算符運算,并輸出運算結(jié)果
package net.ittimeline.java.core.operator.relation;import java.util.Random;import static java.lang.System.out;/*** 關(guān)系運算符** @author liuguanglei 18601767221@163.com* @create 2019-07-29 13:19* @website www.ittimeline.net* @since JDK11.03*/ public class Bool {public static void main(String[] args) {Random random = new Random(88);//產(chǎn)生兩個1-100之內(nèi)的隨機整數(shù)int i = random.nextInt(100)+1;int j = random.nextInt(100)+1;//輸出 i和 j的值out.println("i = " + i);out.println("j = " + j);//使用關(guān)系運算符比較i和j的值out.println("i > j is " + (i > j));out.println("i < j is " + (i < j));out.println("i >= j is " + (i >= j));out.println("i <= j is " + (i <= j));out.println("i == j is " + (i == j));out.println("i != j is " + (i != j));}}3.7 ==和equals()的區(qū)別
- ==和equals都是比較的值是否相等,通常基本數(shù)據(jù)類型使用判斷,引用數(shù)據(jù)類型使用equals判斷,而如果使用判斷引用數(shù)據(jù)類型,比較的是對象的引用地址。
Java中所有的類(無論是JDK自帶的還是開發(fā)人員自己定義的)的直接或者間接父類都是java.lang.Object,該類有個成員方法equals,用于比較對象的相等性。
從Object的equals方法看的出來,默認比較的是對象的引用地址
public boolean equals(Object obj) {return (this == obj);}那么問題來了
EqualsMethod2類中,明明Value的成員變量i的值是100,理論上來說應該是相等的。
但是使用equals判斷的時候是不相等,因為只要使用關(guān)鍵字new創(chuàng)建對象時,會開辟新的堆內(nèi)存空間存儲對象。
因為Object類的equals方法比較的是對象的地址是否相等,但是在實際開發(fā)中,經(jīng)常比較的是對象的成員變量是否相等,因此絕大多數(shù)類都重寫了equals方法。
這里以Integer類為例子,分別使用==和equals來判斷Integer對象的相等性。
當創(chuàng)建Integer對象的值在-128-127之間時,無論是equals還是==都是相等的。
因為Integer類中有個內(nèi)部類IntegerCache,用于緩存Integer的值在-128-127之間的對象
而如果Integer的值超過了緩存的范圍,那么使用判斷對象相等時就不會相等了。
在開發(fā)過程中盡量使用equals方法來判斷,而不是使用來判斷。
3.8 邏輯運算符
邏輯運算符用于布爾類型變量或者布爾表達式的邏輯運算,Java支持的邏輯運算符有如下幾種:
- 邏輯與(&):&兩邊同時為true,結(jié)果為true
- 短路與(&&):當&&兩邊為true,結(jié)果為true,如果&&的一邊為false,將不再執(zhí)行剩余的表達式,也就是短路特性。
- 邏輯或(|):當|兩邊只要有一個為true,結(jié)果為true,否則結(jié)果為false
- 短路或(||):當||兩邊只要有一個為true,結(jié)果為true,否則結(jié)果為false,并且不再執(zhí)行剩余表達式,也就是短路特性。
- 邏輯非(!):當一個變量或者表達式的結(jié)果為true,!的結(jié)果為false,否則結(jié)果為true,邏輯非就是相反的結(jié)果
- 邏輯亦或():當兩邊結(jié)果同時為true或者false,結(jié)果為false,否則為true。
一般開發(fā)中使用短路與、短路或,不會使用邏輯與和邏輯或。
package net.ittimeline.java.core.operator.logic;import java.util.Random;/*** 邏輯運算* @author liuguanglei 18601767221@163.com* @create 2019-08-03 13:02* @website www.ittimeline.net* @since JDK11.03*/ public class LogicTest {public static void main(String[] args) {Random random=new Random(88);//創(chuàng)建兩個隨1-100之內(nèi)的隨機數(shù)int left=random.nextInt(100)+1;int right=random.nextInt(100+1);System.out.println("left ="+left);System.out.println("right ="+right);//判斷兩個數(shù)都是大于100boolean result=left>100&&right>100;System.out.println("left>100&&right>100 = "+result);//判斷左邊的數(shù)加上100大于100或者右邊的數(shù)大于100result=left+100>100||right>100;System.out.println("left+100>100||right>100 = "+result);//邏輯非result=!result;System.out.println("!result = "+result);//邏輯亦或//^左右兩邊都為true或者false,結(jié)果為falseresult =left>10^right>10;System.out.println("left>10^right>10 = "+result);result=left>50^right>50;//^左右兩邊結(jié)果不同結(jié)果為trueSystem.out.println("left>50^right>50 = "+result);} }邏輯與和短路與的區(qū)別
package net.ittimeline.java.core.operator.logic;/*** 邏輯與與短路與* 邏輯與&左右兩邊都是true,結(jié)果為true,不具備短路特性* 短路與&&左右兩邊都是true,結(jié)果為true,具備短路特性:明確整體的計算結(jié)果,不在計算剩余的表達式* @author liuguanglei 18601767221@163.com* @create 2019-08-03 13:02* @website www.ittimeline.net* @since JDK11.03*/ public class LogicAndShowCircuitTest {public static void main(String[] args) {boolean flag=false;int num=10;//邏輯與不具備短路特性,雖然&左邊已經(jīng)是falseboolean logicAnd=flag&num++>0;//但是從輸出結(jié)果看出num依然自增1System.out.println("num = "+num);//而 短路與&&具備短路特性num=10;// &&左邊已經(jīng)為false,右邊的num沒有自增1boolean logicAndCircuit=flag&&num++>0;//輸出結(jié)果依然為10System.out.println("num = "+num);} }邏輯與的短路特性
package net.ittimeline.java.core.operator.logic;import static java.lang.System.out; /*** 邏輯運算的短路現(xiàn)象** @author liuguanglei 18601767221@163.com* @create 2019-07-29 19:41* @website www.ittimeline.net* @since JDK11.03*/ public class ShowCircuit {static boolean test1(int val){out.println("test1("+val+")");out.println("result: "+(val<1));return val<1;}static boolean test2(int val){out.println("test1("+val+")");out.println("result: "+(val<2));return val<2;}static boolean test3(int val){out.println("test1("+val+")");out.println("result: "+(val<3));return val<3;}public static void main(String[] args) {/*** 邏輯與的短路特性* 當執(zhí)行到test1方法時,2<2的結(jié)果為false,整體表達式的結(jié)果為false,因此不會再執(zhí)行test3方法*/boolean flag=test1(0)&&test1(2)&&test3(2);out.println("expression is "+flag);} }邏輯或的短路特性
package net.ittimeline.java.core.operator.logic;import static java.lang.System.out; /*** 邏輯運算的短路現(xiàn)象** @author liuguanglei 18601767221@163.com* @create 2019-07-29 19:41* @website www.ittimeline.net* @since JDK11.03*/ public class LogicOrCircuit {static boolean test1(int val){out.println("test1("+val+")");out.println("result: "+(val<1));return val<1;}static boolean test2(int val){out.println("test1("+val+")");out.println("result: "+(val<2));return val<2;}static boolean test3(int val){out.println("test1("+val+")");out.println("result: "+(val<3));return val<3;}public static void main(String[] args) {/*** 邏輯或的短路特性* 當執(zhí)行到test1方法時,0<2的結(jié)果為true,整體表達式的結(jié)果為false,因此不會再執(zhí)行tes2和test3方法*/boolean flag=test1(0)||test2(2)||test3(2);out.println("expression is "+flag);} }邏輯與、短路與和邏輯或、短路或的應用案例
package net.ittimeline.java.core.operator.logic;/*** 邏輯運算符的復雜案例* 結(jié)合自增運算、if(true){}* @author liuguanglei 18601767221@163.com* @create 2019-08-03 15:55* @website www.ittimeline.net* @since JDK11.03*/ public class LogicComplex {public static void main(String[] args) {int x = 1;int y = 1;//x++=1 y++=1 if (x++ == 2 & y++ == 2) {x = 7;}//x=2 y=2System.out.println("x = " + x + " y = " + y);x = 1;y = 1;// ++x=2 ++y =2 if trueif (++x == 2 && ++y == 2) {x = 7;}//x=7 y=2System.out.println("x = " + x + " y = " + y);x = 1;y = 1;//x++ =1 ++y=2 if trueif (x++ == 1 | ++y == 1) {x = 7;}//x=7 y=2System.out.println("x = " + x + " y = " + y);x = 1;y = 1;// x++=1 // x=7 y=1if (x++ == 1 || ++y == 1) {x = 7;}//x=7 y=1System.out.println("x = " + x + " y = " + y);}}3.9 三元運算符
三元運算符用于布爾變量或者布爾表達式判斷,需要三個操作數(shù),等價于if/else,其表現(xiàn)形式為
bool-exp?value0:value1,如果布爾表達式的結(jié)果為true,三目運算的結(jié)果為value0,否則為value1。
使用三目運算符模擬扔硬幣
package net.ittimeline.java.core.operator.ternary;import java.util.Random;/*** 使用三元運算符模擬扔硬幣* @author liuguanglei 18601767221@163.com* @create 2019-07-30 16:07* @website www.ittimeline.net* @since JDK11.03*/ public class CoinFlipping {public static void main(String[] args) {Random random=new Random(88);boolean flip=random.nextBoolean();System.out.print("OUTCOME :");System.out.println(flip?"人頭":"字");} }三目運算符和if/else
package net.ittimeline.java.core.operator.ternary; import static java.lang.System.out; /*** 三目運算符和if/else** @author liuguanglei 18601767221@163.com* @create 2019-07-30 10:21* @website www.ittimeline.net* @since JDK11.03*/ public class TernaryIfElese {/*** 三目運算符* @param i* @return*/static int ternary(int i){return i<10?i*100:i*10;}/*** 標準的if/else* @param i* @return*/static int standardIfElse(int i){if(i<10){return i*100;}else{return i*10;}}public static void main(String[] args) {out.println(ternary(9));out.println(ternary(11));out.println(standardIfElse(9));out.println(standardIfElse(11));} }使用嵌套if和三目運算符求三個整數(shù)的最大值
package net.ittimeline.java.core.operator.ternary;/*** 求三個數(shù)中的最大值* 分別使用if/else if和三元運算符* @author liuguanglei 18601767221@163.com* @create 2019-08-04 16:58* @website www.ittimeline.net* @since JDK11.03*/ public class GetMaxNumber {public static void main(String[] args) {int i=277;int j=20;int k=-99;int max=0;if(i>j){if(i>k){max=i;}else{max=k;}}System.out.println("使用if/else if實現(xiàn)求三個整數(shù)的最大值 max = "+max);max= i>j&&i>k?i:k;System.out.println("三個數(shù)中的最大值是"+max);} }使用三元運算符判斷用戶輸入的整數(shù)是基數(shù)還是偶數(shù)
如果想要用戶輸入數(shù)據(jù),需要使用Java提供的Scanner類實現(xiàn)
3.10 位運算符
位運算符是直接對整數(shù)的二進制進行運算,在JDK的原碼中大量使用了位運算,
以下是截取Integer類的numberofLeadingZeros方法
位運算符操作的都是整數(shù)類型,因為是基于二進制運算,其運行效率高。
在日常開發(fā)中幾乎不會使用到位運算,但是后期會閱讀大量JDK源碼,了解底層實現(xiàn)機制,因此必須掌握位運算符的基本使用。
Java中支持的位運算符有如下幾種:
-
左移(<<): 左移N位相當于乘以2的n次方,空位補0,被移除的高位丟棄,空缺位補0
-
右移(>>):右移N位相當于除以2的n次方,被移位的二進制最高位是0,右移后,空缺位補0,最高位是1,最高位補1
-
無符號右移(>>>):不管最高位的符號位,右移N位相當于除以2的N次方,被移位的二進制最高位無論是0還是1,空缺位都補0
-
按位與(&):只有&兩邊都是1,結(jié)果是1,否則就是0
-
按位或(|):只要|兩邊都是0,結(jié)果是0,否則就是1
-
按位亦或(^):相同的二進制位進行亦或運算,結(jié)果是0,不相同的二進制位運算結(jié)果是1
-
取反運算(~):無論正負數(shù)取反運算,各二進制位按照補碼取反
-
&,|,在操作布爾類型的時候表示為邏輯與、邏輯或、邏輯亦或,&、|、在操作整數(shù)的時候表示為按位與與按位或、按位亦或。
左移運算
package net.ittimeline.java.core.operator.bit;/*** 左移運算** @author liuguanglei 18601767221@163.com* @create 2019-08-03 16:26* @website www.ittimeline.net* @since JDK11.03*/ public class BitLeftMoveTest {public static void main(String[] args) {//8的二進制表示為// 0000 0000 0000 0000 0000 0000 0000 1000int number=8;//因為8是正數(shù),左移動2位,右邊補上0,相當于乘以2的兩次方 也就是乘以4// 0000 0000 0000 0000 0000 0000 0010 0000number=number<<2;System.out.println("8<<2 ="+number);/*** 在進行移位運算時需要考慮數(shù)據(jù)越界的問題*/int value=21;// 0000 0000 0000 0000 0000 0000 0101 0100//左邊移動26位//101 0100 0000 0000 0000 0000 0000 0000 0//最高位1 表示結(jié)果為負數(shù)System.out.println("21<<26 = "+(value<<26));} }使用左移計算2*16的結(jié)果
package net.ittimeline.java.core.operator.bit;/*** 使用左移計算2*16** @author liuguanglei 18601767221@163.com* @create 2019-08-04 17:36* @website www.ittimeline.net* @since JDK11.03*/ public class BitLeftMoveArithmetic {public static void main(String[] args) {int number=2;//2 * 16 用左移就是2左移4位int result=number<<4;System.out.println("2*16="+result);} }右移運算
package net.ittimeline.java.core.operator.bit;/*** 右移運算** @author liuguanglei 18601767221@163.com* @create 2019-08-03 16:45* @website www.ittimeline.net* @since JDK11.03*/ public class BitRightMoveTest {public static void main(String[] args) {//0000 0000 0000 0000 0000 0000 0001 0000int number=16;//右移N位,相當于除以2的N次方 16/4 結(jié)果是4//00 0000 0000 0000 0000 0000 0000 0001 00number=number>>2;System.out.println("16 >> 2 = "+(number));number=-16;// -16/4 結(jié)果是-4number=number>>2;System.out.println("-16 >> 2 ="+(number));} }按位與、按位或、按位亦或、按位非運算
package net.ittimeline.java.core.operator.bit;/*** 按位運算符* & 兩邊都是1,結(jié)果為1* |* ^* @author liuguanglei 18601767221@163.com* @create 2019-08-03 17:22* @website www.ittimeline.net* @since JDK11.03*/ public class BitAndOrXor {public static void main(String[] args) {/*** 5的二進制表示方式為 0000 0000 0000 0000 0000 0000 0000 0101* 9的二進制方式表示為 0000 0000 0000 0000 0000 0000 0000 1001** 0101&1001 =0001 因此 5&9的結(jié)果是1* 0101|1001 = 1101 因此 5|9的結(jié)果是13* 0101^1001 = 1100 因此 5^9的結(jié)果是12* 9 ->0000 0000 0000 0000 0000 0000 0000 1001* ~9 1111 1111 1111 1111 1111 1111 1111 0110 原碼* 1000 0000 0000 0000 0000 0000 0000 1001 反碼* 1000 0000 0000 0000 0000 0000 0000 1010 補碼* ~9 最終的結(jié)果是-10***/System.out.println("5&9 = "+(5&9));System.out.println("5|9 = "+(5|9));System.out.println("5^9 = "+(5^9));System.out.println("~9 = "+(~9));System.out.println(Integer.toBinaryString(-10));} }有符號左移
package net.ittimeline.java.core.operator.bit;import static java.lang.System.out;/*** 有符號右移** @author liuguanglei 18601767221@163.com* @create 2019-07-30 16:23* @website www.ittimeline.net* @since JDK11.03*/ public class SignedRightShift {public static void main(String[] args) {int i = 0x80000000;out.println(Integer.toBinaryString(i));//等價于i=i>>1i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));i >>= 1;out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));} }無符號右移
package net.ittimeline.java.core.operator.bit;import static java.lang.System.out;/*** 無符號右移** @author liuguanglei 18601767221@163.com* @create 2019-07-30 16:33* @website www.ittimeline.net* @since JDK11.03*/ public class UnsignedRightShift {public static void main(String[] args) {int i = -1 << 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;out.println(Integer.toBinaryString(i));i >>>= 1;i >>>= 1;i >>>= 1;i >>>= 1;i >>>= 1;i >>>= 1;i >>>= 1;i >>>= 1;i >>>= 1;out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));out.println(Integer.toBinaryString(i));} }使用亦或運算實現(xiàn)變量的交換
package net.ittimeline.java.core.operator.bit;/** 使用亦或因運算實現(xiàn)變量交換* @author liuguanglei 18601767221@163.com* @create 2019-08-04 17:11* @website www.ittimeline.net* @since JDK11.03*/ public class BitXorVariableSwap {public static void main(String[] args) {int left=10;int right=20;System.out.println("變量交換之前 left = "+left+" right = "+right);left=left^right;right=left^right;left=left^right;System.out.println("變量交換之后 left = "+left+" right = "+right);} }轉(zhuǎn)載于:https://www.cnblogs.com/ittimeline/p/11295963.html
總結(jié)
以上是生活随笔為你收集整理的Java架构师成长之道之Java数据计算的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Mysql的一些问题
- 下一篇: Eclipse创建JavaWeb工程