Java核心技術總結一:Java的基本程式設計結構
一、註釋
// 單行註釋
/* */ 多行註釋
/** */ 自動生成文件
二、資料型別
型別 儲存需求 取值範圍
byte 1位元組 -128 ~ 127
short 2位元組 -32768 ~ 32767
int 4位元組 -2147483648 ~ 2147483647
long 8位元組 -9223372036854775808 ~ 9223372036854775807
補充:
長整型整數有字尾L或l,十六進位制有字首0x或0X,八進位制有字首0
jdk1.7以後,加上字首0b或者0B就可以寫成二進位制數,如0B1001即為9
jdk1.7以後,可以為數字加上下劃線,使其更易讀,如1_000_000即為100萬
Java沒有任何無符號形式的byte、short、int、long型別
型別 儲存需求 取值範圍
float 4位元組 大約±3.402 823 47E+38F(有效位數為6~7位)
double 8位元組 大約為±1.797 693 134 862 315 70E+308(有效位數為15位)
補充:
float型別有字尾F或f,沒有字尾F的浮點數值(如3.14)預設為double型別
浮點數不適用於無法接受舍入誤差的金融計算,如2.0-1.1=0.8999999...
不是期望的0.9,如果在計算中不允許有誤差,就應該使用BigDecimal類
Java中的char型別佔2位元組,16位,其採用Unicode字元(ASCll碼也包含在類)
常用的ASCll碼:
0-9:48-57
A-Z:65-90
a-z: 97-122
有兩個值:true和false,用來判斷邏輯條件。
補充:
整型值和布林值不能進行相互轉換
如if(x=0),在C++中可以編譯執行,其結果總為false,而java中不能通過編譯,因為整數表示式x=0不能轉換為布林值
三、變數與常量
變數比較簡單,這裡說下注意點:
1.變數宣告後必須使用賦值語句對變數進行顯式初始化,不能使用未初始化的變數
如 int a;System.out.println(a);//錯誤,a未初始化
2.變數的宣告儘可能靠近變數第一次使用的地方
3.jdk10以後,如果可以從變數的初始值推斷出它的型別,
就不需要宣告型別,只需要使用關鍵字var而無需知道型別
如 var number=12;//number為int型別;
var name=“zhangsan”;//name為String型別
1.java中,利用關鍵字final指示常量,final表示該變數一旦被賦值無法更改
2.習慣上,常量名使用全大寫
3.如果希望某個常量可以在一個類的多個方法中使用,可以將其設定為類常量,
使用關鍵字static final進行設定(類常量定義於main方法的外部)
針對某個變數的取值只在一個有限的集合裡,可以自定義列舉型別
如
enum Size{SMALL,MEDIUM,LARGE};
Size s=Size.LARGE;
四、運算子
+、-、*、/,%
/運算需要注意,當參與/操作的兩個運算元都是整數時,表示整數除法;否則,表示浮點除法,如15/2=7,15.0/2=7.5
注意:整數被0除將產生1個異常;浮點數被0除將得到無窮大或NaN結果
1.Math.sqrt(x),計算x的平方根
2.Math.pow(x,a),計算x的a次方,返回值為double型別
3.最接近π的常量:Math.PI;最接近e的常量:Math.E
說明:
1.只要在原始檔頂部加上import static java.lang.Math.*;則使用Math類置的函式與常量不需要加Math
例如:
import static java.lang.Math.*;
public class test {
public static void main(String[] args) {
System.out.println(sqrt(PI));
}
}
2.java中數學運算如果計算溢位,數學運算子只是返回一個錯誤結果而不做任何提示,
如:1000000000*3=-1294967295,因為int最大值才剛超過20億,
此時可以採用Math.multiplyExact(1000000000,3)進行計算,它就會產生一個異常
1.合法轉換:
byte->short->int->long(double);char->int->long(double);float->double
int-->float;long-->float;long-->double
->轉換表示無資訊丟失,-->表示可能有精度的丟失
如int n=123456789;float f=n;//f =1.2345679E8 ;這是因為123456789包含的位數比float型別所能夠表示的位數多.
2.當用一個二元運算子連線兩個值時(例如n+f),先要將兩個運算元轉換為同一運算元,再進行計算。
規則如下:
兩個運算元有一個為double型別,則另外一個轉為double型
否則有一個為float型別,則另外一個轉為float型
否則有一個為long型別,則另外一個轉為long型
否則,兩個運算元都將被轉為int型
上一節可以看到,在必要時int會自動轉成double,但當需要將double轉成int時,需要使用強制型別轉換。
語法格式為:在圓括號中給想要轉換的目標型別,後面緊跟待轉換的變數名。
例如:double x=9.96;int y=(int)x;/y=9;
注意:
如果試圖將一個數值從一種型別強制轉換為另一種型別,而又超出了目標型別的表示範圍,結果就會截斷成一個完全不同的值,例如,(byte)300的實際值為44
1.結合賦值和運算子 (+=,-=;*=;/=,%=...)
如x+=4;等價於x=x+4;
注意:如果x為一個int型,則x+=3.5,即x=(int)(x+3.5),發生強制型別轉換
2.自增減運算子(n++,++n,n--,--n)
在表示式中,字首會先進行±1操作,而字尾會先使用變數原來的值
如 int m=4;int n=3*m++;//n=12;m=5
int m=4;int n=3*++m;//n=15;m=5
3.關係和boolean運算子
- 檢測相等性,使用==,如3==7的值為false
檢測不相等,使用!=,如3!=7的值為true
還有常用的<,>,<=,>=
2.expression1&& expression2:
邏輯與:當兩個表示式都為true結果為true,否則為false
expression1|| expression2
邏輯或:當兩個表示式只要有一個為true結果為true,否則為false
注意:邏輯與和或都按照短路方法求值,即如果expression1可以確定結果,expression2不進行計算。
3.condition?expression:expression2
當condition為true,結果就為expression1,否則為expression2
1.&(and),|(or),^(xor),~(not)
如3&7=7,(011&111=3)
注意&,|也可用在布林值上,此時其與&&,||相似,只不過不採用短路方法計算。
2.左移<<,右移>>
如1<<3結果為8
注意右移時如果不夠移,則結果為0,如1>>2結果為0;
注意:移位操作符的右運算元要完成模32的運算(如果左運算元為long型,則為模64),
例如1<<35等價於1<<3
優先順序 運算子 結合性
1 ()、[]、{} 從左向右
2 !、+、-、~、++、-- 從右向左
3 *、/、% 從左向右
4 +、- 從左向右
5 «、»、>>> 從左向右
6 <、<=、>、>=、instanceof 從左向右
7 ==、!= 從左向右
8 & 從左向右
9 ^ 從左向右
10 | 從左向右
11 && 從左向右
12 || 從左向右
13 ?: 從右向左
14 =、+=、-=、*=、/=、&=、|=、^= 從右向左
、~=、«=、»=、>>>=
五、字串
String的substring方法可以從一個較大的字串提取出一個子串。例如:
Stirng father="hello";
String son=father.substring(0,3); //son即為"he"
substring第二個引數是不想複製的第一個位置,本例從0到2複製
substring的工作方式有一個優點;容易計運算元串的長度。s.substring(a,b)的長度為b-a
1.java允許使用+連線(拼接)兩個字串
當將一個字串與一個非字串的值進行拼接時,後者會轉換成字串。
如 int num=2020;String year=“this year is”+num;//year為字串"this year is 2020".
2.jdk11中,提供了repeat方法
Stirng repeated="Java".repeat(3);//repeated為字串"JavaJavaJava"
由於不能修改java字串中的單個字元,所以在java文件中將String類物件稱為是
不可變的,如 String a="hello",“hello”這個值不可以修改,但是可以修改字
符串變數a,使得其引用另外一個字串,如 a=“hi”。
不可變字串有一個優點:編譯器可以讓字串共享:可以想象將各種字串存放在公
共的儲存池中。字串變數指向儲存池中相應的位置。如果複製一個字串變數,原
始字串與複製的字串共享相同的字元。
1.可以使用equals方法檢測連個字串是否相等
s.equals(t):如果字串s和字串t相等,返回true,否則返回false。
一定不要用==運算子檢測兩個字串是否相等(該運算子只能確定兩個字串是否存
放在同一個位置,但完全有可能將內容相同的多個字串副本放置在不同的位置)
1.空串""是長度為0的字串(可以使用sr.length()==0或者str.equals(“”))
檢查字串是否為空
2.String可以存放一個特殊的值->nul,要檢查一個字串是否為null,要使用
str==null進行判斷。
有時需要檢查一個字串既不是null也不是空串,可以使用以下條件進行判斷:
str!=null&&ste.length()!=0
注意:兩者順序不能顛倒,如果在一個null值上呼叫方法,會出現錯誤
所有上文的equals方法,如果字串a不為null,則應該使用a.equals(b)來判斷
a和b是否相等,因為b可能存在為null的情況。
每次拼接字串時,都會構建一個新的Sring物件,既耗時有浪費空間,使用
StringBuilder類可以避免這個問題的發生。
例如;
StringBuilder sb=new StringBuilder();
sb.append("hello");
sb.append("world");
String s= sb.toString();
//通過這種方式建立了字串s,其值為"helloworld”。
擴充套件: StringBuilder在jdk1.5引入,其前身是 StringBuffer,效率
比 StringBuilder低,但是它允許採用多執行緒方式新增或刪除字元。而
StringBuilder不能,如果所有字串編輯操作都在單執行緒中執行,則
應該使用 StringBuilder。
六、輸入與輸出
想要通過控制檯進行輸入,需要構造一個與“標準輸入流”System.in關聯的
Scanner物件。下面例子展示如何從控制檯輸入並獲取值。
Scanner sc=new Scanner(System.in);
System.out.println("please input your name");
String name=sc.nextLine();//獲取控制檯輸入
Scanner不只有nextLine方法,還有nextInt,next等多種方法,詳見jdkAPI
jdk1.5沿用了C語言函式庫的printf方法
例如
double x=1.12345678;
System.out.printf("%8.2f",x);
//輸出為 1.12
//這包括8個字元,其中精度為小數點後2個字元,所以會列印前導空格和4個字元。
讀取檔案:
Scanner in = new Scanner(Path.of("myfile.txt"), StandardCharsets.UTF_8);
寫入檔案:
PrintWriter out = new PrintWriter("myfile.txt", StandardCharsets.UTF_8);
注意:如果一個不存在的檔案構造一個Scanner或者一個無法建立的檔名構造一個PrintWriter,就會產生一個異常。
七、控制流程
塊(即複合語句)是指有若干條java語句組成的語句,並用一對大括號括起來。塊定義
了變數的作用域。一個塊可以巢狀在另一個塊中。
如:
public static void main(String[] args) {
int n;
//...
{
int k;
//...
}
}
但不能在巢狀的兩個塊中宣告相同的變數。
如:
//無法通過編譯
public static void main(String[] args) {
int n;
//...
{
int n;
int k;
//...
}
}
int a= 1 ;
int b= 2 ;
if ( a> b) {
System. out. println ( "a" ) ;
}
if ( a> b) {
System. out. println ( "a" ) ;
} else {
System. out. println ( "b" ) ;
}
if ( a> b) {
System. out. println ( "a" ) ;
} else if ( a== b) {
System. out. println ( "==" ) ;
} else {
System. out. println ( "b" ) ;
}
int num= 1 ;
int sum= 0 ;
while ( num<= 5 ) {
sum+= num;
num++ ;
}
System. out. println ( sum) ;
do {
sum+= num;
num++ ;
} while ( num<= 5 ) ;
System. out. println ( sum) ;
int sum= 0 ;
for ( int j = 0 ; j <= 5 ; j++ ) {
sum+= j;
}
System. out. println ( sum) ;
int choice= ( int ) ( Math. random ( ) * 4 ) ;
switch ( choice) {
case 0 :
System. out. println ( "0" ) ;
break ;
case 1 :
System. out. println ( "1" ) ;
break ;
case 2 :
System. out. println ( "2" ) ;
break ;
default :
System. out. println ( "3" ) ;
}
int sum= 0 ;
for ( int i = 0 ; i <= 5 ; i++ ) {
if ( i== 1 ) {
continue ;
}
sum+= i;
}
System. out. println ( sum) ;
sum= 0 ;
for ( int i = 0 ; i <= 5 ; i++ ) {
if ( i== 1 ) {
break ;
}
sum+= i;
}
System. out. println ( sum) ;
八、大數
如果基本的整數和浮點數精度不能夠滿足需求,
可以使用java.math包中兩個很有用的類,BigInteger和BigDecimal,
BigInteger類實現任意精度的整數計算
BigDecimal類實現任意精度的浮點數計算
1.使用靜態的valueof方法可以將普通數值轉換為大數
BigInteger a=BigInteger.valueOf(100);
2.對於更大的數,可以使用一個帶字串引數的構造器:
BigInteger bigInteger = new BigInteger("4632879378293728937298378983793728937812937812");
3.不能使用熟悉的算術運算子處理大數(如+和*),而是使用大數的add和multipy方法
BigInteger c=a.add(b);//c=a+b
BigInteger d=c.multiply(b);//d=c*b
九、陣列
int [ ] a;
a= new int [ 100 ] ;
int [ ] b= { 2 , 3 , 4 , 5 } ;
int [ ] c= new int [ 0 ] ;
int len= a. length;
for ( int i = 0 ; i < a. length ; i++ ) {
a[ i] = i;
}
for ( int element: a) {
System. out. println ( element) ;
}
int [ ] aa= a;
aa[ 5 ] = 12 ;
int [ ] copyA= Arrays. copyOf ( a, a. length) ;
copyA[ 6 ] = 16 ;
int [ ] sort= { 4 , 1 , 3 , 2 } ;
Arrays. sort ( sort) ;
int [ ] [ ] m;
m= new int [ 10 ] [ 10 ] ;
for ( int i = 0 ; i < m. length ; i++ ) {
for ( int j = 0 ; j < m[ i] . length ; j++ ) {
m[ i] [ j] = i* 10 + j;
}
}
for ( int i = 0 ; i < m. length ; i++ ) {
for ( int j = 0 ; j < m[ i] . length ; j++ ) {
System. out. println ( m[ i] [ j] ) ;
}
}
for ( int [ ] row: m) {
for ( int value: row) {
System. out. println ( value) ;
}
}