天天看點

2. Java的基本程式設計結構一、一個簡單的Java應用程式二、注釋三、資料類型四、變量五、運算符六、字元串七、輸入輸出八、控制流程九、大數值十、數組

以《Java核心技術 卷1》第10版為主,結合自身實踐進行截圖及細節描述。

Java的基本程式設計結構

  • 一、一個簡單的Java應用程式
  • 二、注釋
  • 三、資料類型
    • 1. Java整型
    • 2. 浮點類型
    • 3.char類型
    • 4. boolean類型
  • 四、變量
    • 1. 聲明變量
    • 2. 變量初始化
    • 3. 常量
  • 五、運算符
    • 1. 算術運算符
    • 2. 數學函數與常量
    • 3. 數值類型之間的轉換
    • 4. 結合指派運算符
    • 5. 自增與自減運算符
    • 6. 關系和boolean運算符
    • 7. 位運算符
    • 8. 括号與運算符級别
    • 9. 枚舉類型
  • 六、字元串
    • 1. 子串與拼接
    • 2. 不可變字元串
    • 3. 檢測字元串是否相等
    • 4. 空串和Null串
    • 5. 碼點與代碼單元
    • 6. 建構字元串
  • 七、輸入輸出
    • 1. 讀取輸入
    • 2. 格式化輸出
    • 3. 檔案輸入輸出
  • 八、控制流程
    • 1. 塊作用域
    • 2. 條件語句
    • 3. 循環語句
    • 4. 中斷控制流程語句
  • 九、大數值
  • 十、數組
    • 1. 數組簡介及聲明
    • 2. 數組初始化及匿名數組
    • 3. 數組拷貝
    • 5. Arrays類常用API
    • 6. 多元數組
    • 7. 不規則數組

一、一個簡單的Java應用程式

import java.util.Arrays; //導入數組類,友善數組輸出
public class Welcome {
	public static void main(String[] args){
		//System.out.println("We Will not use 'Hello,World!'");
		System.out.println(Arrays.toString(args));
	}
}
           

說明:

  • Java語言區分大小寫
  • 關鍵字import 導入其他包中的類。【public,class,import目前先不看,後續章節會詳細介紹】
  • 關鍵字public稱為通路修飾符(access modifier)
  • 關鍵字class表明Java程式中的全部内容都必須包含在類中
  • Java中定義類名規則:必須字母開頭,後面可以跟字母和數字的任意組合,長度上沒有限制,但不可使用Java保留字(保留字不許要刻意去記)。标準命名規範:類名是以大寫字母開頭的名詞,後每個單詞的第一個字母大寫(駱駝命名法,如:FirstSample)
  • 源代碼的檔案名必須與公共類(即public class修飾的類名)的名字相同,并用.java作為擴充名。即檔案名稱為:FirstSample.java
  • 在運作已編譯的程式時,Java虛拟機将從指定類中的main方法開始執行,是以,在類的源檔案中必須包含一個main方法。
  • main方法必須聲明為public
  • 用大括号{ } 劃分程式的各個部分(通常稱為塊)
  • Java使用的通用文法是:object.method(parameters)
  • String[] args:是用來接受指令行參數的,程式中import(導入)Arrays類,都是為了這步的展示,平常并不需要。具體使用如下:(可先看看十、數組知識)
    2. Java的基本程式設計結構一、一個簡單的Java應用程式二、注釋三、資料類型四、變量五、運算符六、字元串七、輸入輸出八、控制流程九、大數值十、數組

二、注釋

  注釋不會出現在可執行程式中,是以可在源程式中添加任意多的注釋,而不必擔心可執行代碼膨脹。

-- // 單行注釋:注釋内容從開始到本行結尾

-- /*  */多行注釋:以/* 開始 以 */ 結尾

-- /**
    * 文檔注釋,可用來自動地生成文檔。在其他章節會詳細介紹文檔注釋的使用
    */
           

三、資料類型

1. Java整型

類型 存儲需求 取值範圍
byte 1位元組 -128~127
short 2位元組 -32768~32767
int 4位元組 -2147483648~ 2147483647(約±2.1*109)
long 8位元組 -9223327036854755808~9223327036854755807(約±9.2*1018)
  • Java中資料類型的取值範圍與運作Java代碼的機器無關(Java的移植性)
  • Java中整數預設類型為int
  • 長整型(long型)數值需有一字尾L或l進行标注(例:40000000L)
  • 字首0x或0X:表示十六進制,字首0表示八進制,字首0b或0B表示二進制,還可為數字字面量加下劃線(如1_000_000),Java編譯器會去除這些下劃線。【從java7開始才有這些特性】
  • Java中沒有無符号(unsigned)形式的int、short、long或byte類型,C++中有

2. 浮點類型

類型 存儲需求 取值範圍
float 4位元組 約 ± 3.40282347E+38F(有效位數為6~7位)
double 8位元組 約 ± 1.79769313486231570E+308(有效位數為15位)
  • Java中浮點數預設類型為double,float類型需在數值後加字尾F或f
  • 可以用十六進制表示浮點數值,例如0.125 = 2-3 可以表示成0x1.0p-3(p表示指數。注意,尾數采用十六進制,指數采用十進制。指數的基數是2,而不是10)
  • 所有浮點數值計算都遵循IEEE 754規範。(簡單來說就是用科學技術法來表示一個浮點數,然後統一規定浮點數在單精度,雙精度中符号位的位置,尾數,指數所占位數及其位置)
  • 表示溢出和出錯情況的三個特殊的浮點數值:正無窮大,負無窮大,NaN(不是一個數字)。Double/Float.POSITIVE_INFINITY、NEGATIVE_INFINITY、NaN 分别表示這三個數值,實際中很少用到。
  • 所有“非數值”的值都認為是不相同的,是以不可用x == Double.NaN來檢測一個特定值是否等于Double.NaN。但可以Double.isNaN(x) ,來檢測x是否是非數值。
  • 在金融計算中,就不可使用浮點數值了,其存在誤差。得用BigDecimal類表示。(請檢視九、大數值)

3.char類型

  char類型原本用于表示單個字元,如今,有些Unicode字元用一個char值描述,有些Unicode字元用兩個char表示。(Unicode字元表所描述的字元數量遠大于占2個位元組的char類型取值範圍)

  char類型的字面量值要用單引号括起來。char類型的值可以表示為十六進制值,其範圍\u0000到\uffff。除\u外,還有其他轉義字元

轉義字元

轉義序列 名稱 Unicode值
\b 倒退 \u0008
\t 制表 \u0009
\n 換行 \u000a
\r 回車 \u000d
" 雙引号 \u0022
單引号 \u0027
\ 反斜杠 \u005c

  特别地:注釋中遇到 \u 也會進行解析,如:// \u00A0 is a newline 會産生一個文法錯誤,因為\u00A0 表示換行。又如:// Look inside c:\users,也會産生一個文法錯誤,因為\u 後并不是4個數字。

Unicode 與 char類型

  設計Unicode編碼是為了解決各國編碼方案不一緻的問題。剛開始Java采用16位的Unicode字元集,但很快Unicode字元超過了65536個,其主要原因是增加了大量的漢語、日語和韓語的表意文字。

  為解決Unicode與char之間的問題,引入了碼點(code point)。碼點是指一個編碼表中某個字元對應的代碼值。在Unicode标準中,碼點采用十六進制書寫,并加上字首U+。

  Unicode的碼點分成17個代碼級别(code plane)。第一個代碼級别稱為基本的多語言級别(常用),碼點從U+0000到U+FFFF;其餘的16個級别代碼從U+10000到U+10FFFF,其中包括一些輔助字元。

  UTF-16編碼采用不同長度的編碼表示所有Unicode碼點。在基本的多語言級别中,每個字元用16位表示,被稱為代碼單元。此時就産生一個問題,要擴充位元組來容納其他級别字元嗎?不行,人們常用的字元大多是基本多語言級别中的字元,為了不常用的字元,去打破之前的相關設計不值得。那怎麼辦呢?其他級别字元(也常稱作輔助字元)采用一對連續的代碼單元進行編碼。輔助字元區間是U+10000~U+10FFFF(其個數總共是1024*1024個,二進制位需占用20位)。是以規定如下:其他級别字元用兩個代碼單元表示(二進制位共32位),即每個代碼單元,有10位表示具體數字的,剩餘6位做标記,所作标記要保證不管機器怎麼讀,不會存在歧義的情況。那規定前六位為1101 10(十進制54)的表示第一個代碼單元(1101 10xx xxxx xxxx);前六位為1101 11(十進制55)表示第二個代碼單元(1101 11xx xxxx xxxx)。即U+D800 ~ U+DBFF為輔助字元第一部分,U+DC00 ~ U+DFFF為輔助字元第一部分。為了UTF-16編碼方法的正确,Unicode将U+D800~U+DFFF作為保留區,不在這塊配置設定字元。(懂進制轉換的話,這塊比較容易了解)

  在Java中,char類型描述了UTF-16編碼中的一個代碼單元,是以強烈建議不要在程式中使用char類型。(推薦使用字元串,字元串中對碼點和代碼單元也有相關介紹,見 六,5 碼點與代碼單元)

 常見編碼:

  • 數字:[0x30,0x39](或十進制[48, 57])
  • 大寫字母:[0x41,0x5a](或十進制[65, 90])
  • 小寫字母:[0x61,0x7a](或十進制[97, 122])

 也可前往位址Unicode字元集,檢視所有的Unicode字元。

4. boolean類型

   boolean(布爾)類型有兩個值:false和true,用來判定邏輯條件。整型值和布爾值之間不能進行互相轉換。(C++中0表示false)

四、變量

1. 聲明變量

  格式:[類型] [變量名] [;]

  • 類型可以是資料類型和類,接口等對象
  • 變量名必須是一個以字母開頭并由字母和數字構成的序列。Java中字母或數字是在所有語言中表示字母或數字的Unicode字元,比如德國‘ä’,希臘‘π’。并不僅僅是A ~ Z,a ~ z,0~9。聲明的變量名應是有意義的,且大小寫敏感,長度上無限制。【推薦:變量名命名規範:首字母小寫,後面單詞首字母大寫(小駝峰)】
  • 每個聲明以分号結束
  • 盡管$屬于一個合法的Java字元,但不要使用,它隻用在Java編譯器或其他工具生成的名字中(編譯内部類時,編譯器是用$來作為中間符号定義内部類名的)。不能使用Java保留字作為變量名。
  • 可以在一行中聲明多個變量,但不提倡。逐一聲明變量,可讀性加強。

2. 變量初始化

  聲明一個變量之後,必須用指派語句對變量進行顯式初始化。

// 對一個已經聲明過的變量進行指派
int vacationDays;
vacationDays =12;
// 将變量的聲明和初始化放在同一行
int vacationDays = 12;
           

   變量的聲明盡可能地靠近第一次使用的地方,這是一種良好的程式編寫風格。

3. 常量

  關鍵字final 訓示常量

// 常量
final double CM_PER_INCH =2.54;
// 類常量
static final double CM_PER_INCH =2.54;
           
  • 關鍵詞final 表示這個變量隻能被指派一次,一旦被指派之後,就不能再修改了
  • 習慣上,常量名使用全大寫方式
  • 類常量:可在一個類中多個方法中使用,定義在main方法外部

五、運算符

1. 算術運算符

   + - * / % (加,減,乘,除,求餘)

  • 當參與 / (除)運算的兩個操作數是整數時,表示整法除法,即結果隻保留整數;否則浮點除法。舉例:15/2 結果是7;15.0/2=7.5
  • 整數被0除會産生一個異常,浮點數被0除會得到無窮大或NaN結果
  • 可移植性是Java語言的設計目标之一,無論在那個虛拟機上運作,同一運算應得到同一的結果。但對于浮點數的運算,這是很困難的。舉例說明:double類型使用64位存儲一個值,而有些處理器使用80位寄存器,得到的結果會比64位寄存器更加精确。此時Java虛拟機初期規定:所有的中間計算結果都必須進行截斷。但這種方法遭到反對,因截斷操作需消耗時間。後Java給予改進,預設情況下,Java虛拟機允許對中間計算結果采用擴充的精度,但是strictfp标記的方法或類内部必須使用嚴格的浮點計算。(嚴格在哪?嚴格在不同的機器上的浮點計算結果一緻)。

2. 數學函數與常量

  在Math類中,包含了各種各樣的數學函數

常見函數

傳回類型 方法和參數
static double sqrt(double a):傳回正平方根
static double pow(double a,double b):傳回a^b結果
static int floorMod(int x,int y):傳回x%y的值。最初在設計%求餘操作時,忽略了一個準則:餘數總是>=0 。而 -3 % 2 = -1,這顯然不符合數學規範。是以引入了這個方法,保證餘數始終>=0
static long round(double a):傳回a四舍五入後的long值
Math中還有一些三角函數,指數函數,對數函數,具體檢視jdk-api-1.8幫助文檔中文版(我有上傳資源)
常量 Math中有兩個常量:Math.PI(π) Math.E (自然對數的基數)
  • 關于函數調用,因為Math類中的方法都是靜态方法(static标注),是以直接[ 類名. 方法(參數) ] 調用即可。也可靜态導入:import static java.lang.Math.*; 那麼調用時就可把類名去掉:[ 方法(參數) ] 調用。
  • 在Math類中,為了達到最快的性能,所有的方法都使用計算機浮點單元中的例程。如果想得到嚴格的計算結果【即在所有平台上得到相同的結果】應使用StrictMath類。

3. 數值類型之間的轉換

①自動類型轉換

2. Java的基本程式設計結構一、一個簡單的Java應用程式二、注釋三、資料類型四、變量五、運算符六、字元串七、輸入輸出八、控制流程九、大數值十、數組
  • 實線表示無資訊丢失的轉換,虛線表示有精度損失的轉換(說明:檢視上面3.1 和3.2 整形和浮點型可表示數值的範圍,發現float表示的數值範圍要大于long型,是以int/long可以自動轉化為float型,更别說double型了。int型可實線轉換為double型,是因為double的精度約15位,而int型共10位【正負20億左右】是以可無損轉換。)
  • 當兩種不同類型的數值進行計算時

②強制類型轉換

  不符合自動轉換圖形的,都是強制類型轉換。

  文法格式:(要轉換的類型) 變量

double x =9.97;
int nx = (int)x;
           
  • 預設的強制類型轉換是通過截斷方式進行的。如浮點型轉整形,截斷小數部分。但如果在強制類型轉換過程中,超出了目标類型的表示範圍(比如:300轉byte)會截斷成一個完全不同的數值。
  • 若想要進行舍入運算,則需要Math.round 方法。其API見上表

4. 結合指派運算符

  • 同類别的還有 /= -= *= %=等
  • x +=3.5; 若得到值與 x 類型不同,就會發生強制類型轉換(自動行為)

5. 自增與自減運算符

  n++ / n--:将變量n的目前值加一或減一 (字尾)

  ++n / --n:将變量n的目前值加一或減一 (字首)

  • 字尾和字首兩種形式單獨存在沒有差別,但放到表達式中就有差別了,運算符在前面,先自增/自減,再算表達式,否則,反之。
int m =7;
int n =7;
int a =2* ++m; //a是16,m是8
int b =2* n++; //b是14,n是8
           

6. 關系和boolean運算符

運算符 類别
關系運算符 ==,!=,<,>,<=,>=
邏輯運算符 &&(短路與),|| (短路或),!(非),&(與),|(非)
三元運算符 ?: 用法:條件判斷?true執行片段:false執行片段
  • 短路與(&&)說明:條件判斷A && 條件判斷B ,若A錯誤,B就不執行了,因為結果已經注定了。短路或也是一樣的道理。隻要通過A就能确定整個表達式結果,B就不執行了。

7. 位運算符

   &(與),|(或),^(異或),~(非),>>(右移),<<(左移),>>>(無符号右移):是按二進制位來計算的。也不經常用,畢竟不直覺。

8. 括号與運算符級别

  括号級别最高,注意:! && || 優先級逐降低

運算符優先級(從高到低)

運算符 結合性
[ ] . ( ) 【方法調用】 從左到右
! ~ ++ -- +【一進制運算符】 -【一進制運算符】()【強制類型轉換】 new 從右到左
* / % 從左到右
+ - 從左到右
<< >> >>> 從左到右
< <= > >= instanceof 從左到右
== != 從左到右
& 從左到右
^ 從左到右
| 從左到右
&& 從左到右
|| 從左到右
?: 從右到左
= += -= *= /= %= &= |= ^= <<= >>= >>>= 從右到左
  • +/- 一進制運算符用于數值的符号(正/負),當用于非數值時,會解析為數字。
  • 優先級順序不需要特别去記,當存在多個運算符時,加括号是個不錯的程式設計習慣

9. 枚舉類型

  有時,變量的取值隻在一個有限的集合内,例如披薩大小。當然可以分别編号,但是存在隐患,有可能存儲一個錯誤的數值。是以引入了枚舉類型。

enum Size {SMALL,MEDIUM,LARGE,EXTRA_LARGE}; //自定義枚舉類型
Size s= Size.MEDIUM; //聲明
           

  Size類型的變量隻能存儲這個類型聲明中給定的某個枚舉值或null值。

六、字元串

1. 子串與拼接

  Java字元串就是Unicode字元序列,Java中沒有内置的字元串類型,而是在标準Java類庫中提供了一個預定義類。每個用雙括号括起來的字元串都是String類的一個執行個體。

常用方法

傳回類型 方法名和參數 說明
String subString(int beginIndex) subString(int beginIndex,int endIndex) (子串)傳回一個從beginIndex到串尾的所有代碼單元
String subString(int beginIndex,int endIndex) (子串)傳回一個從beginIndex到endIndex-1的所有代碼單元
static String join(CharSequence delimiter, CharSequence… elements) (拼接) 傳回一個新的字元串,用給定的定界符連接配接所有元素
  • 舉例說明:String.join("/",“S”,“M”,“L”,“XL”); //結果是S/M/L/XL
  • CharSequence是String繼承的一個接口
  • Java允許使用+号拼接兩個字元串;當一個字元串與另一個非字元串的值進行拼接時,後者會轉換為字元串

2. 不可變字元串

  String類沒有提供用于修改字元串的方法,是以将String類對象稱為不可變字元串。我們修改字元串,并不是修改字元串本身,而是建立一個字元串,将原來的字元串變量引用該建立的字元串。

  進一步了解:編譯器讓字元串共享。即 将各種字元串存放在公共的存儲池中,字元串變量指向存儲池中相應的位置。但這同樣存在一個問題:共享存儲池中使用後不再使用的字元串會越來越多,會導緻記憶體洩漏。但幸運的是有垃圾回收機制,如果一塊記憶體不再使用,系統會将其回收。

  Java的設計者認為共享帶來的高效率遠遠勝過提取、拼接字元串所帶來的低效率。

3. 檢測字元串是否相等

傳回類型 方法名和參數 說明
boolean equals(Object anObject) 将此字元串與指定對象進行比較。相等傳回true,否則false
boolean equalsIgnoreCase(String anotherString) 不區分大小寫比較是否相等
  • 不要使用“==”運算符檢測兩個字元串是否相等!這個運算符隻能确定兩個字元串是否在同一個位置上。
  • 不對呀!不是字元串共享嗎,同一個字元串應該在同一個位置上啊!但其實是字元串常量是共享的,而+或subString等操作産生的結果并不是共享的。

4. 空串和Null串

  空串是長度為0的字元串,是一個Java對象,有自己的串長度(0)和内容(空)。

  String變量可以存儲一個特殊值:null,表示目前沒有任何對象與該變量關聯。

// 檢查一個字元串是否為空
if (str.length()==0)  或者  if (str.equals(""))
// 檢查一個字元串是否為null
if (str == null)
// 檢查一個字元串既不是null也不為空串
if (str != null && str.length() !=0)
// 必須首先檢查str不為null,才可再檢查是否為空串。因為null是不可以調用的
           

5. 碼點與代碼單元

  碼點 = 1或2 個代碼單元。具體緣由,請檢視 三,3 char類型中的描述。String字元串中索引從0開始

傳回類型 方法名和參數 說明
int length() 傳回字元串代碼單元的數量
int codePointCount(int beginIndex, int endIndex) 傳回beginIndex到endIndex-1的碼點數量,參數是代碼單元的位置值。
char charAt(int index) 傳回位置為index的代碼單元
int offsetByCodePoints(int index,int codePointOffset) 傳回從index代碼點開始,位移codePointOffse個碼點後的代碼單元索引
int codePointAt(int index) 傳回從給定位置開始的碼點
IntStream codePoints() 從CharSequence接口繼承的方法,傳回一個int值流,每個int值對應一個碼點,可以将其轉化為一個數組。
// 得到第i的碼點;因為預設索引是按照代碼單元編号的,是以要先得到對應的代碼單元索引,再擷取值。
int index = str.offsetByCodePoints(0,i); //index >= i
int cp = str.codePointAt(index);
           

為了了解得更清晰,看下面代碼

public class Welcome {
	public static void main (String[] args){
		//𝕆 占兩個代碼單元,String索引從0開始
		String str = "Welcome𝕆java";
		System.out.println("代碼單元數量:"+str.length()); //13
		System.out.println("碼點數量:"+str.codePointCount(0,str.length()));//12 
		System.out.println("占一半碼點數量:"+str.codePointCount(0,8)); //8
		System.out.println("測試上一句:"+str.codePointCount(0,9)); //8
		int index = str.offsetByCodePoints(0,8);
		System.out.println("第8個碼點的代碼單元值:"+index); //9
		System.out.println("代碼單元索引為9的碼點值"+str.codePointAt(index)); //j ox6A 106
	}
}
           
2. Java的基本程式設計結構一、一個簡單的Java應用程式二、注釋三、資料類型四、變量五、運算符六、字元串七、輸入輸出八、控制流程九、大數值十、數組

6. 建構字元串

   有時需要将許多較短的字元串建構成一個字元串,例如按鍵或來自檔案中的單詞。采用字元串連接配接的方式效率低。是以使用StringBuilder類。

具體操作:

  1. 建構一個空的字元串建構器:StringBuilder builder = new StringBuilder();
  2. 當需要添加字元或字元串時,調用append方法
  3. 調用toString方法,可傳回String對象

補充:

  • JDK5.0中引入了StringBuilder類,這個類的前身是StringBuffer,StringBuffer效率低,但允許采用多線程的方式執行添加或删除字元的操作。如果所有字元串在一個單線程中編輯,則應該用StringBuilder替代它。這兩類的API是相同的。

StringBuilder常見方法

傳回類型 方法名和參數 說明
int length() 傳回代碼單元數量
StringBuilder append(String str) 追加一個字元串并傳回this
StringBuilder append(char c) 追加一個代碼單元并傳回this
StringBuilder appendCodePoint(int codePoint) 追加一個代碼點并傳回this
void setCharAt(int index,char ch) 将第i個代碼單元設定為c
StringBuilder insert(int offset, String str) 在offset位置插入一個字元串并傳回this
StringBuilder delete(int start, int end) 删除從start到end-1的代碼單元并傳回this
String toString() 傳回字元串

七、輸入輸出

   本部分主要講輸入輸出到控制台,現代的程式都使用GUI收集使用者的輸入。

1. 讀取輸入

  1. 構造Scanner對象:Scanner in =new Scanner(String.in)
  2. 讀取一行:String name = in.nextLine(); //輸入行中可能包含空格

    讀取一個單詞:String name = in.next(); //以空格進行分割

    讀取一個整數:String age = in.nextInt(); // 還有其他方法,讀取浮點型等

需要注意:

  • Scanner類定義在java.util包中,當使用的類不是定義在基本java.lang包中時,一定要使用import訓示字元将相應的包加載進來。比如Scanner 應在在檔案開頭:import java.util.Scanner;
  • 因為輸入是可見的,是以Scanner類并不适用從控制台讀取密碼。JavaSE6特别引入了Console實作這個目的。但該類隻能在控制台(cmd)中執行,不能在eclipse中運作。而且現在都是通過GUI(界面)進行輸入的,是以Console類也不需要了解。

2. 格式化輸出

   System.out.print(x); 輸出x,但是會将x對應的資料類型所允許的最大非0數字位數列印輸出。舉例:10000.0/3.0 會輸出 3333.3333333333335。

  慶幸的是,Java5.0 沿用了C語言函數中的printf方法。調用語句是System.out.printf("%8.2f",x); %8.2f 就是格式說明符,當然不會這麼簡單,完整格式如下:

格式說明符

2. Java的基本程式設計結構一、一個簡單的Java應用程式二、注釋三、資料類型四、變量五、運算符六、字元串七、輸入輸出八、控制流程九、大數值十、數組

用于printf的标志

标志 目的 舉例
+ 列印正數和負數的符号 +3333.33
空格 在正數之前添加空格 | 3333.33|
數字前面補0 003333.33
- 左對齊 |3333.33 |
( 将負數括在括号内 原值:-3333.33 現:(3333.33)
, 添加分組分隔符 3,333.33
#(對于f格式) 包含小數點 3,333.
#(對于x或0格式) 添加字首0x或0 0xcafe
$ 給定被格式化的參數索引 %1$d 以十進制格式列印第一個參數
< 格式化前面說明的數值 %d%<x 以十進制,十六進制列印同一數值

用于printf的轉換符

轉換符 類型 舉例
d 十進制整數 159
x 十六進制整數 9f
o 八進制整數 237
f 定點浮點數 15.9
e 指數浮點數 1.59e+01
g 通用浮點數
a 十六進制浮點數 0x1.fccdp3
s 字元串 Hello
c 字元 H
b 布爾 True
h 散列碼 42628b2
tx或Tx 日期時間 已淘汰,應使用java.time包
% 百分号 %
n 與平台有關的行分隔符

舉了一些例子,說明值被格式化的位置問題

public class Welcome {
	public static void main (String[] args){
		//預設情況下,值的位置與格式說明符的位置一一對應
		System.out.printf("測試:%08.2f,%(e \n",3333.33,-4444.44); 
		//也可通過$,< 進行位置指定
		System.out.printf("測試:%2$08.2f,%1$(e , %<8.2f  \n",3333.33,-4444.44); 
	}
}
           
2. Java的基本程式設計結構一、一個簡單的Java應用程式二、注釋三、資料類型四、變量五、運算符六、字元串七、輸入輸出八、控制流程九、大數值十、數組
  • 标志是為了讓輸出項更加美觀
  • 可以使用s轉換符格式化任意的對象,該對象若實作了Formattable接口,則調用formatTo方法,否則調用toString方法
  • 關于時間/日期的轉換符,以t/T開頭,以相應其他字元結尾,比如%tD,會顯示美國格式的日期。這裡并沒有列出,是因為很多,且推薦使用java.time包中類與方法。
  • 參數索引值從1開始

3. 檔案輸入輸出

  檔案輸入: Scanner in =new Scanner(Path.get(“myfile.txt”),“UTF-8”);

  • 如果檔案名中包含反斜杠符号,就要在每個反斜杠之前再加一個額外的反斜杠:“c:\\mydirectory\\myfile.txt”
  • 這裡指定了UTF-8字元編碼,常見但不普遍。是以在讀取一個檔案時,要知道它的字元編碼。如果沒有指定,則會使用運作這個Java程式的機器的“預設編碼”,這不合适,因為部署其他機器上時可能會出現亂碼。
  • 可使用前面介紹的任何一個Scanner方法對檔案進行讀取
  • Scanner構造器中有一個Scanner(String source)的方法,其會将字元串解釋為資料,而不是檔案名。

  輸出檔案: PrintWriter out = new PrintWriter(“myfile.txt”,“UTF-8”);

  • 該方式輸出檔案,若檔案不存在,會建立該檔案,而且可使用print、println、printf 指令
  • 當指定一個相對檔案名時,檔案位于Java虛拟機啟動路徑的相對位置;如果在指令行啟動程式,啟動路徑是指令解釋器的目前路徑;如果使用內建開發環境,啟動路徑有IDE控制。是以推薦使用絕對路徑

  上面是Scanner類與PrintWriter類的簡單用法,其他用法請檢視jdk1.8API(我有上傳資源)

八、控制流程

1. 塊作用域

  塊(即複合句)是指由一對大括号括起來的若幹條簡單的Java語句,塊決定了變量的作用域。

  • 塊可以嵌套:一個塊可以嵌套在另一塊中
  • 不能在嵌套的兩個塊中聲明同名的變量
  • 在控制流程中(條件語句或循環語句)若statement(語句)隻有一句,可以不加塊(一對大括号),但加上最好,提高閱讀體驗。
public static void main (String[] args){
	int n;
	{   			//塊可以嵌套
		int k;
		int n;		//不可聲明同名變量,因為變量的作用域在其所屬塊及其嵌套塊中。
	}	
}
           

2. 條件語句

-- if 條件語句 --
1. if (condition) statement;   //condition為TRUE,執行statement
2. if (condition) {statements;} //condition為TRUE,執行多條statement
3. if (condition) {Astatements;} else{Bstatements;} //condition為TRUE,執行Astatements,為FALSE,執行Bstatements。else部分可選
4. if (conditionA) {Astatements;} else if (conditionB){Bstatements} else{Cstatements} //conditionA 為TRUE,執行Astatements,為FALSE,再判斷conditionB,為TRUE,執行Bstatements,為FAlSE,執行Cstatements
5. 以上else部分皆可選

   --  switch 多重選擇 --
//在處理多個單值選項時,if/else結構顯得有些笨拙。例如:結果是A怎麼樣,是B怎麼樣,是C怎麼樣...
switch(choice){
	case label1: ... break;
	case label2: ... break;
	case label3: ... break;
	....
	default: ... break;
}
           
  • switch語句将從與選項值相比對的case标簽處開始執行直到遇到break語句,或者執行到switch語句的結束處為止。如果沒有相比對的case标簽,而有default子句,就執行這個子句。
  • 如果case分支語句的末尾沒有break語句,那麼就會接着執行下一個case分支語句。
  • choice值的類型可以是char、byte、short或int的常量表達式;可以是枚舉變量;可以是字元串字面量(java7開始)

3. 循環語句

-- while循環 --
1. while(condition) statement; //condition為TRUE,執行一條statement,也可選擇{statements;}
2. do{statements;} while(condition); //與1的差别是:1循環體statement可能一次都不執行,而2先執行一次循環體,再判斷條件。注意:結尾分号不可少

   -- for 循環 --
for (int i=0;i<10;i++) {System.out.println(i);..循環體..} //第一部分int i=0,對計數器進行初始化;第二部分i<10,再每次新一輪循環執行前要檢測的條件;第三部分i++ 訓示如何更新計數器。三個部分都可省略,相當于while(true){...},會一直循環下去。

   -- for each循環 --
for(variable: collection) statement;
例:for(int element: a) System.out.println(element); //a為一個int數組
           
  • for循環第一部分聲明一個變量後,這個變量的作用域為for循環的整個循環體。
  • for循環中聲明變量時,不要用double類型,一般為int,因為浮點型在更新計數器時可能存在數值誤差。
  • 如果想在for循環體之外使用計數器的值,就要将計數器i定義在循環體之外
  • 可以在各自獨立(不嵌套)不同的for循環中可定義同名的變量。
  • for循環語句隻不過是While循環的一種簡化形式。是以兩者在一定條件下是可以互相轉換的
  • for循環的三個部分,定義部分(i=0),判斷部分(i<10)是先執行的,更新計數器部分(i++)是在循環體執行之後才執行的。
  • for each循環用來依次處理集合中每一個元素,而不必為下标值分心。
  • for each循環variable用于暫存集合中每一個元素,并執行相應的語句或語句塊。collection必須是一個數組或實作了Iterable接口的類對象。
  • for each循環中不會改變集合元素,因為variable隻是集合中元素的一個副本

4. 中斷控制流程語句

  不帶标簽的break語句

  與用于退出switch語句的break語句一樣,在你想退出控制流程時,直接break就好。隻能退出一層循環。

  帶标簽的break語句

  主要用于退出多重嵌套的循環語句。具體用法如下:

label_declaration:	//标簽聲明,标簽必須放在希望跳出的最外層循環之前
while(...){
	for(...){
		if(...)
			break label_declaration; //跳出兩層循環,到标簽前
	}
}
           
  • 可以将标簽應用到任何語句中,甚至可以應用到if語句或塊語句中。
  • 隻能跳出語句塊,不能跳入語句塊。

  continue語句

  與break語句一樣,将中斷正常的流程控制。具體效果:跳過剩餘的循環體部分,從新一輪循環開始執行。特别地,針對for循環,continue之後,先執行一次更新計數器的操作,再從新一輪循環開始。當然也有帶标簽的continue。

九、大數值

  如果基本的整數和浮點數精度不能滿足需求,那麼可以使用java.math包中的兩個類:BigInteger和BigDecimal。這兩個類可以處理包含任意長度數字序列的數值。BigInterger類實作了任意精度的整數運算,BigDecimal實作了任意精度的浮點數運算。下面給出了一些方法供參考:

BigInteger

傳回值 方法名及參數名 解釋
BigInteger add(BigInteger other) 傳回該大整數和另一個大整數other的和
BigInteger subtract(BigInteger other) 傳回該大整數和另一個大整數other的差
BigInteger multiply(BigInteger other) 傳回該大整數和另一個大整數other的積
BigInteger divide(BigInteger other) 傳回該大整數和另一個大整數other的商
BigInteger mod(BigInteger other) 傳回該大整數和另一個大整數other的餘數
int compareTo(BigInteger other) 比較兩個大整數,相等傳回0,<other傳回負數,>other傳回正數
static BigInteger valueOf(long x) 傳回 值等于x的大整數

BigDecimal

傳回值 方法名及參數名 解釋
BigDecimal add(BigDecimal other) 傳回該大實數與另一個大實數的和
BigDecimal subtract(BigDecimal other) 傳回該大實數與另一個大實數的差
BigDecimal multiply(BigDecimal other) 傳回該大實數與另一個大實數的積
BigDecimal divide(BigDecimal other, RoundingMode roundingMode) 傳回該大實數與另一個大實數的商,RoundingMode 用來規定商的舍入方式
int compare(BigDecimal other) 比較兩個大實數,相等傳回0,<other傳回負數,>other傳回正數
static BigDecimal valueOf(long x) 傳回 值等于x的大實數
static BigDecimal valueOf(long x, int scale) 傳回 值等于x * 10scale 的大實數

十、數組

1. 數組簡介及聲明

  數組是一種資料結構,是用來存儲同一類型值的集合,通過一個整型下标可以通路數組中的每一個值。

int[] a; //聲明數組a
int[] a = new int[100]; //聲明并建立數組(也被稱作初始化,因為數組會被預設指派)
           
  • 可以使用兩種方式int[] a; int a[]; 聲明數組,但推薦使用int[] a; 需要注意的是:僅聲明數組是不能使用該數組的,必須建立new或者初始化才能使用。
  • new int[100]:建立一個可以存儲100個整數的數組,數組長度100不要求是常量,還可以是變量。
  • 數組的下标從0開始。建立一個數字數組時所有元素初始化為0;boolean數組初始化為false;對象數組的元素初始化為特殊值null,這表示這些元素還未存放任何對象
  • 一旦建立了數組,就不能改變它的大小,若想更靈活的擴充數組,見ArrayList
  • Arrays類中的toString() 方法,可将數組列印成字元串。API見十,5

2. 數組初始化及匿名數組

① int[] smallPrimes = {2,3,4,5,6,7}; //建立數組對象并同時賦予初始值
② new int[] {5,6,7,8,9,10}; //初始化一個匿名數組
③ smallPrimes = new int[] {5,6,7,8,9,10}; //不建立新變量的情況下重新初始化一個數組
           
  • 在初始化中,數組的大小就是初始值的個數
  • 允許數組長度為0

3. 數組拷貝

  Java中允許将一個數組變量拷貝給另一個數組變量

int[] smallPrimes = new int[6];
int[] luckyNumbers = smallPrimes;
luckyNumbers[5] =12 //現在smallPrimes[5] 也是12了
其邏輯如下:兩個數組變量指向同一塊空間
           
2. Java的基本程式設計結構一、一個簡單的Java應用程式二、注釋三、資料類型四、變量五、運算符六、字元串七、輸入輸出八、控制流程九、大數值十、數組

但也可以通過Arrays的copyOf方法,拷貝整個數組,這個方法也常用來增加或減少數組的大小

//拷貝數組
int[] copiedLuckyNumbers = Arrays.copyOf(luckyNumbers,luckyNumbers.length);
//增加數組大小,多餘的元素預設初始化;也可減少數組大小,那就隻拷貝最前面的數組元素
luckyNumbers = Arrays.copyOf(luckyNumbers,2*luckyNumbers.length);
其邏輯如下:
           
2. Java的基本程式設計結構一、一個簡單的Java應用程式二、注釋三、資料類型四、變量五、運算符六、字元串七、輸入輸出八、控制流程九、大數值十、數組

5. Arrays類常用API

type借指8種資料類型:byte,short,int,long,boolean,char,float,double。下面的方法都是靜态(static 修飾)的,即通過類名直接調用

傳回值 方法名與參數 解釋
Static String toString(type[ ] a) 傳回a中資料元素的字元串,形如格式:[1,2,3,4],
static type copyOf(type[] a,int length ) 傳回與a類型相同的一個數組,長度為length,數組元素為a的值
static type copyOf(type[] a,int start,int end) 傳回與a類型相同的一個數組,長度為end-start,數組元素為a的值。包括start,不包括end
static void sort(type[] a) 采用優化的快速排序算法對數組進行排序
static int binarySearch(type[] a,type v) 采用二分搜尋算法查找值v,查找成功,傳回下标值,否則傳回一個負數
static int binarySearch(type[] a,int start,int endtype v) 采用二分搜尋算法在[start,end) 區間内查找值v,查找成功,傳回下标值,否則傳回一個負數
static void fill(type[] a,type v) 将數組中所有資料元素值設定為v
static boolean equals(type[] a,type[] b) 若兩個數組大小相同,且下标相同的元素都對應相等,傳回true,否則,傳回false
static String deepToString(Object[] a) 用于将多元數組轉換為字元串,其格式:[[…],[…],[…]]

6. 多元數組

  多元數組将使用多個下标通路資料元素,适用于表示表格或更加複雜的排列方式。

//聲明數組
double[][] balances;
//建立數組/初始化 (三行三列)
balances = new double[3][3];
//若知道數組元素,就可以不調用new/簡化的書寫形式進行初始化
int[][] magicSquare={{16,3,2},{5,10,11},{9,6,7}};
//一旦數組被初始化,可使用兩個括号通路數組元素
magicSquare[1][2] 值為:11  //數組索引從0開始計數
           
  • for each循環語句不能自動處理二維數組的每一個元素。若想使用,需要兩個嵌套的循環
  • 列印二維數組:使用Arrays的deepToString方法
①for(double[] row: magicSquare)
	for(double value:row)
		...do something with value...
② System.out.println(Arrays.deepToString(magicSquare));
           

7. 不規則數組

  Java中實際沒有多元數組,隻有一維數組,多元數組被解釋為“數組的數組”。是以可以建立不同行有不同列的情況

int[][] balances = new int[3][]; //也可new int[3][4];表示3行4列
balances[0] = new int[4];
balances[1] = new int[3];
balances[2] = new int[1];
其邏輯如下:
           
2. Java的基本程式設計結構一、一個簡單的Java應用程式二、注釋三、資料類型四、變量五、運算符六、字元串七、輸入輸出八、控制流程九、大數值十、數組
  • new int[3][];可以,但new int[][3];不可以,即在建立數組時,可隻規定行數,列數後續建立。但不可以隻規定列數,行數空缺。