Java核心技術總結一:Java的基本程式設計結構

夏涼冬暖發表於2020-12-23


一、註釋

//      單行註釋
/* */   多行註釋
/** */  自動生成文件

二、資料型別

  • 整型
    型別    儲存需求    取值範圍
    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類
 
  • char型別
Java中的char型別佔2位元組,16位,其採用Unicode字元(ASCll碼也包含在類)
常用的ASCll碼:
0-9:48-57
A-Z:65-90
a-z: 97-122
  • boolean型別
有兩個值: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。
一定不要用==運算子檢測兩個字串是否相等(該運算子只能確定兩個字串是否存
放在同一個位置,但完全有可能將內容相同的多個字串副本放置在不同的位置)
  • 空串與Null串
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");
            }//輸出b

             if(a>b){
            System.out.println("a");
             }else if(a==b){
            System.out.println("==");
             }else{
            System.out.println("b");
            }//輸出b
  • 迴圈
     /*
            1.while迴圈
            while(condition){
            statement
            }
            當condition為true,執行statement,為false,退出迴圈
           該迴圈至少執行0次
           2.do-while迴圈
            do{
            statement
            }while(condition)
            該迴圈先執行statement,再檢測迴圈條件,為true繼續執行,否則退出迴圈
            該迴圈至少執行一次
         */
               int num=1;
               int sum=0;
               while(num<=5){
                   sum+=num;
                   num++;
               }
                System.out.println(sum);//輸出15
                //此時num=6;
               do {
                   sum+=num;
                   num++;
               } while(num<=5);
                System.out.println(sum);//輸出21
  • 確定迴圈
 /*
          for迴圈:
          第一部分通常是對計數器初始化,如本例的int j=0;
          第二部分給出每新一輪迴圈執行前要檢查的條件,如果為false,退出,否則繼續,如本例的j<=5
          第三部分指定如何更新計算器,如本例的j++
          注意:檢測兩個浮點數是否相等需要格外小心,下面的for迴圈可能永遠不會結束
          for(double x=0;x!-10;x+=0.1)...
          這是因為舍入的誤差,可能永遠達不到精確的最終值
         */
        int sum=0;
        for (int j = 0; j <=5 ; j++) {
            sum+=j;
        }
        System.out.println(sum);//輸出15 ,0+1+2+3+4+5
  • 多重選擇:switch語句
   /*
         switch語句語法如下:
         switch(expression){
         case value :
         //語句
         break; //可選
         case value :
         //語句
         break; //可選
         //你可以有任意數量的case語句
         default : //可選
         //語句
         }
         1.當expression的值與 case 語句的值相等時,那麼 case 語句之後的語句開始執行,直到 break 語句出現才會跳出 switch 語句。
         2.當遇到 break 語句時,switch 語句終止。程式跳轉到 switch 語句後面的語句執行。case 語句不必須要包含 break 語句。
         如果沒有 break 語句出現,程式會繼續執行下一條 case 語句,直到出現 break 語句。
         3.switch 語句可以包含一個 default 分支,該分支一般是 switch 語句的最後一個分支
         default 在沒有 case 語句的值和變數值相等的時候執行。default 分支不需要 break 語句。
         */
      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");
       }//輸出choice的值

  • 中斷控制流程的語句
        /*
           1.continue 語句語句用來結束當前迴圈,並進入下一次迴圈,即僅僅這一次迴圈結束了,
           不是所有迴圈結束了,後邊的迴圈依舊進行
           2. break 語句語句用來結束迴圈,所有迴圈結束
           下面用for迴圈舉例,while,do-while迴圈同理
         */
        int sum=0;
        for (int i = 0; i <=5 ; i++) {
            if(i==1){
                continue;
            }
            sum+=i;
        }
        System.out.println(sum);//輸出14,因為只有i=1時沒有執行sum+=i;
        sum=0;
        for (int i = 0; i <=5 ; i++) {
            if(i==1){
                break;
            }
            sum+=i;
        }
        System.out.println(sum);//輸出0,因為i=1時退出迴圈

八、大數

如果基本的整數和浮點數精度不能夠滿足需求,
可以使用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;//也可以寫成int a[]
        // 將陣列a初始化
        a=new int[100]; //兩步可以連起來,寫成int []a=new int[100],此時陣列a裡所有元素值均為0
        int []b={2,3,4,5};//建立陣列物件並提供初始值的簡寫形式,該陣列長度為4
        int []c=new int[0];//在java中。陣列長度可以為0,但其不等同與null
        int len=a.length;//len為100,即獲取a陣列的長度
        //訪問陣列元素,如a陣列的下標從0-99,a[100],會引發"array index out of bounds"異常
        for (int i = 0; i <a.length ; i++) {
            a[i]=i;//給a[i]賦值,
        }
  • for each 迴圈
        /*
        增強for迴圈
        for(variable:collection){
            steatment
        }
        variable為儲存在collection裡的元素(按順序排列),collection必須是一個陣列或者實現Iterable介面的物件
        for each迴圈遍歷的是陣列中的每個元素,而不是下標值
         */
         //列印陣列中所有元素值
        for (int element: a){
            System.out.println(element);//依次輸出0-99
        }
        //更簡單的方法為Arrays.toStirng(a);
  • 陣列拷貝
   //在java中,允許將一個陣列變數拷貝到另一個陣列變數。這時兩個變數將引用同一個陣列
         int []aa=a;
         aa[5]=12;//此時a[5]=12;
        //如果希望將一個陣列的所有值拷貝到一個新的陣列中,就使用Arrays類的copyOf方法
        //第二個引數時新陣列的長度,可以大於或小於拷貝的陣列長度,如果大於陣列長度,則多出的初始值為0
        //(boolean陣列初始值為false),小於陣列長度,則只拷貝前面的值
        int []copyA= Arrays.copyOf(a,a.length);
        copyA[6]=16;//此時a[6]=6,不發生變化
  • 陣列排序
  //想要對數值型陣列進行排序,可以使用Arrays類中的sort方法,這個方法使用了優化的快速排序演算法,效率較高
        int []sort={4,1,3,2};
        Arrays.sort(sort);//現在sort陣列的順序為{1,2,3,4}
 //如果對字串陣列使用Arrays,sort方法排序,則回按照字典順序進行排序
  • 二維陣列
        //二維陣列
        //宣告二維陣列
        int [][]m;
        //將陣列m進行初始化
        m=new int[10][10];
        //遍歷二維陣列並賦值
        for (int i = 0; i <m.length ; i++) {//m.length,陣列行的個數
            for (int j = 0; j <m[i].length ; j++) {//m[i]length,陣列第i行元素個數
                m[i][j]=i*10+j;//對陣列進行賦值
            }
        }
        //輸出二維陣列的元素值
        //方法1
        for (int i = 0; i <m.length ; i++) {//m.length,陣列行的個數
            for (int j = 0; j <m[i].length ; j++) {//m[i]length,陣列第i行元素個數
                System.out.println(m[i][j]);
            }
        }
        //方法2
        for (int []row:m){
            for (int value:row){
                System.out.println(value);
            }
        }
        

相關文章