1.一個簡單的java應用程序

1 public class FirstSample { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 System.out.println("hello world"); 6 } 7 8 }
雖然這是一個簡單的java程序,但是所有的java應用程序都具有這種結構
需要注意的是:
首先java是區別大小寫的,如果出現大小寫問題那么程序將無法運行
java應用程序中的所有內容必須都放置在類中
java中定義類名的規則很寬松:名字必須以字母開頭,后面可以跟字母和數字的任意組合,長度沒有限制,但是不能用java保留字作為類名
標准的命名方法(駝峰命名法):就是首字母大寫,如果多個字母組成,那么每個單詞的首字母都應該大寫,像駝峰一樣。
源代碼的名字必須和公共類的名字相同,並且以.java作為擴展名。
JVM運行.class文件時,首先從main方法開始
在java中,用大括號划分程序的各個部分(通常叫做塊),java中任何方法的代碼都用“{”開始用“}”結束
在java中,每個句子必須要用分號結束,特別需要說明,回車不是語句的結束標志,因此,如果需要,可以把一條語句寫在多行
在這樣System.out.println("hello world");使用了System.out對象並且調用了它的方法println,注意點好(.)用於調用方法
,java使用的通用語法是object.method(參數)。
2.注釋
最常用的注釋是//:其注釋內容用//開始到本行結尾
當需要長篇的注釋時,可以用多行//,也可以用/*------*/把它括起來
第三種注釋:用來自動生成文檔,/**--------*/
3.數據類型
java是一種強類型語言,這就意味者要為每一個變量聲明一種類型
java中一共有8種基本類型,其中有4種整型,2種浮點型,1種用於表示Unicode編碼的字符單元的字符類型char和一種表示真值的boolean類型
3.1 整型
整型:用於表示沒有小數部分的數值,它允許是負數
4種整型分別是byte(1字節),short(2字節),int(4字節),long(8字節),一個字節8位二進制。
長整型后面有一個后綴L或者l(10L),十六進制前面會有一個前綴0x后者0X(0xCAFE),八進制有一個前綴0,從java7開始,加上前綴0b或者0B就可以表示二進制數。
3.2 浮點型
浮點類型表示有小數部分的數值。有float(4字節)和double(8字節)
double表示這種類型的數值進度是float的兩倍(有人叫它雙精度),絕大數情況下使用double,在很多情況下,float類型很難滿足精度要求
float類型的數值后面會有一個F或者f(3.14F)。沒有f或者F的浮點值默認為double類型。當然也可以在后面加上后綴D或者d
3.3 char類型
char類型的字面量要用單引號(‘’)括起來,只能放單字符
char類型是可以運算的,因為char在ASCII等字符編碼表中有對應的數值,在java中進行char類型的運算的時候,直接當作ASCII碼表中對應的整數來運算。
我們強烈建議不要在程序種使用char類型,除非要處理UTF-16代碼單元,最好將字符串作為抽象數據類型處理
3.4 boolean類型
布爾類型:就兩個值true和false用來判斷邏輯判斷
3.5 變量
變量名必須是一個以字母開頭並由字母或數字組成的序列,可以在一行聲明多個變量,但是不提倡,逐一聲明每個變量可以提高程序的可讀性。
聲明變量后就要初始化,千萬不能使用未初始化的變量
3.6 常量
在java中,利用關鍵字final指示常量,關鍵字final表示這個變量只能被賦值一次,一但被賦值,就不能修改了習慣上,常量名使用全大寫。
在java中經常希望某個常量在一個類的多個方法中使用,通常將這些常量稱為類常量,可以用final static設置一個類常量
3.7 運算符
在java中+,-,*,/表示加,減,乘,除。當參加/運算的兩個數都是整數時,就叫整數除法,否則就是浮點數除法。
整數求余操作用%表示,有時叫做取模運算,需要注意:整數除0會出現異常,而浮點數除0會出現無窮大或者NAN結果
3.8 數學函數和常量
在Math中包含着各種各樣的數學函數,我們編寫函數時,可能要用到。在api說明文檔中我們可以知道,Math類在java.lang
中所以不要導包就可以用,使用方式就是Math.method();
求平方根可以用sqrt()

double a = 4; double b = Math.sqrt(a); System.out.println(b);
因為在java中沒有冪函數所以我們可以用pow()方法
double c = Math.pow(2, 2); System.out.println(c);
pow()方法有2個double類型的參數,返回值也是double
floorMod方法的目的則是解決一個長期存在的有關整數取余的問題
書上說的難懂,只能知道怎么取值
int m = Math.floorMod(15, 13); System.out.println(m);//2 int n = Math.floorMod(-15, 13); System.out.println(n);//11 int j = Math.floorMod(15, -13); System.out.println(j);//-11 int k = Math.floorMod(-15, -13); System.out.println(k);//-2
為什么會出現這樣的情況呢https://blog.51cto.com/11604910/2372141可以參考這4張圖
3.8 數值之間的合法轉化
這種情況大多出現在 不同類型數值之間經行運算的時候
總結一下:就是從小數值類型轉化為大的是合法的,不會有信息丟失,其中int-》float,long-》float,long-》double,可能會有精度損失,但是也是合法的
總結以下就是:如果2個數中有一個是double,另外一個就會轉化為double
否則,其中一個是float,另外一個就會轉化為float
否則,其中一個是long,另外一個就會轉化為long
否則,兩個都會被轉化為int類型
3.9 數值之間的強制轉化
也就是上面相反的轉化,從大到小,但是有可能會丟失信息,但是java允許這種轉化,但是要在前面加上要轉化的數據類型,並且用括號()括起來
1 double x = 3.14; 2 int y = (int)x; 3 System.out.println(y);//3
正如上面說的會丟失信息。
如果想對一個浮點數進行四舍五入,以便獲得最接近的整數,那就需要用到Math.round()方法
1 double m = 3.45; 2 double n = 3.55; 3 long a = Math.round(m); 4 long b = Math.round(n); 5 System.out.println(a);//3 6 System.out.println(b);//4
4.0 結合賦值和運算符
a+=b等價於a = a + b
其他的運算符也有這樣的表示
4.1 自增和自減運算符
++和--
n++表示n+1
n--表示n-1
其實還有一種表達方式就是++n,也是表示n+1,但是在表達式中就不是這樣了
在表達式中n++;先將n帶進去運算后n+1
++n而是先將n+1,把n+1帶進去運算,所以建議捕要在表達式中使用++,會使人產生困惑
下面是例子

int a = 20; int c = 10; int e = 10; int b; int d; b = a * c++;//c=11 d = a * ++e;//e=11 System.out.println(b);//200 System.out.println(d);//220
4.2 關系和boolean運算符
java有豐富的關系運算符,要檢查是否相等可以用==,檢查不相等可以用!=
還經常用<,>,>=,<=;
java還沿用了c++的邏輯與&&,邏輯或||,邏輯非!。
&&和||是通過短路的方法來求值的,那么何為短路方法呢,我們先用&&來說明 message1&&message2,如果message1是false,那么不管message2為true還是false,結果都是false,所以我們沒必要判斷message2,也就是不必計算message1這個表達式。||也是這個意思。這就是所謂的短路。
4.3 三元操作符
codition?a:b意思很簡單就是如果codition為true則執行a,為false則執行b。
4.4 位運算符
位運算符有與(&),或(|),非(~),異或(^)
表明看起來位運算符和&&和||好像差不多,但是操作對象不一樣,位運算符是對兩個二進制數進行操作,而boolean運算符是對兩個關系運算符進行操作
與(&);如果都為1,則為1,其他情況都為0
或(|);如果有一個為1,則為1,其他情況都為0
非(~);如果位為1,結果為0,位為0,結果為1
異或(^);如果兩位相同則為0,不同則為1
左移運算符(<<);低位補0
有符號右移(>>);為負則前面全部補1,為正則后面全部補0
無符號右移(>>>);無論是正還是負,高位都補0
4.5 括號與運算符級別
如果有圓括號則先計算圓括號里面的,沒有的話,就根據給出的運算符優先級次序進行計算,同一級別按從左到右計算(除了一些右結合運算符外)這些運算符優先級次序網上都有,這里就不一一給出
4.6 字符串
從概念上講,Java字符串就是Unicode字符序列。java沒有內置的字符串類型,而是在標准java類庫中提供了一個預定義類,很自然的叫做String,每個用“”括起來的字符串都是String類的實例
4.61 子串
String類的substring方法可以從一個較大的字符串中提取出一個子串,下面是例子
String s = "yangfan"; String b = s.substring(0,4); System.out.println(b);//yang
這方法需要注意的是后面的位取不到,以上面的例子來說就是4位取不到,只取到0-3的字符串
這個方法有個優點就是:很容易知道子串的長度,substring(a,b),length=b-a;
4.62 拼接
與絕多數的程序設計語言一樣,java允許用+來拼接兩個字符串
當一個字符串和一個非字符串拼接時,后者會被轉化成字符串(后面我們可以知道,任何一個java對象都可以轉化成字符串)
如果我們需要把多個字符串放在一起,而且用一個定界符分隔,可以使用靜態join方法,以下就是例子
String all = String.join("?", "a","b","c"); System.out.println(all);//a?b?c
4.63 不可變字符串
java字符串中的字符是不能修改的,舉個例子String s = “hello”,字符串“hello”里面的任何一個字符都不能被修改,當然字符串變量s可以變,可以指向別的字符串
不可變字符串在修改字符串上可能效率低,但是不可變字符串有個優點:編譯器可以讓字符串共享。
總而言之,java設計者認為共享帶來的高效率遠遠勝於提取和拼接字符串帶來的低效率。
4.64 檢測字符串是否相等
這里需要說一下==與equals()方法
==:比較的是引用是否相等,也就是說兩個變量是否指向同一地址
而equals()方法:api中也是比較引用是否指向同一地址,但是String類重寫了這個類,使得equals()比較的是字符串的值是否相等,也就是內容是否相同!下面為例子

1 String a = new String("YF"); 2 String b = new String("YF"); 3 System.out.println(a == b);//false 4 System.out.println(a.equals(b));//true 5 String c = "YF"; 6 String d = "YF"; 7 System.out.println(c == d);//true 8 System.out.println(c.equals(d));//true
如果需要比較兩個字符串忽視大小寫是否相等就可以用,equalsIgnoreCase()
如果虛擬機始終將相同的字符串共享,就可以用==運算符檢查是否相同,但是注意!!!只有字符串常量是共享的,而+和substring等操作的結果並不是共享的,因此千萬不要用==來比較兩個字符串內容是否相等!
下面例子
String a = new String("YF"); String b = new String("YF"); String c = "YF"; String d = "YF"; String e = "YFYF"; String x = a + b; String y = c + d; System.out.println(e==x);//false System.out.println(e==y);//false System.out.println(x==y);//false
總之我們記住一個結論就是:只有字符串常量是共享的,其他都是形成新的字符串,而不是共享
4.65 空串和Null
空串是“”字符串長度為0的字符串,可以用下面兩種方法來檢查一個字符串是否為空字符串
String s = ""; System.out.println(s.equals(""));//true System.out.println(s.length()==0);//true
空串是一個java對象,有自己的長度(0)和內容(空),String變量還可以存放一個特殊的值,名為null,這表示這個變量目前和任何對象都沒有關聯。可以用以下方法檢測一個字符串是否是null
String s = null; System.out.println(s == null);//true
如果需要檢查一個字符串既不是null也不是空串,需要使用下面的條件
if(str != null && str != "")
首先要檢查str不為null
4.46 碼點與代碼單元
這個部分講到了編碼原理,比較深入,不適合目前的java學習,故暫不學習
4.47 構建字符串
有時候需要由較短的字符串構建字符串,而使用字符串拼接的方法達到此目的效率比較低,每次連接字符串,都會構建一個新的字符串,即耗時,又浪費空間。使用StringBuilder類就可以避免這個問題。
使用方法如下:

1 StringBuilder sb = new StringBuilder(); 2 sb.append("hello "); 3 sb.append("world!"); 4 String s = sb.toString(); 5 System.out.println(s);
5 輸入輸出
前面我們知道打印輸出“標准輸出流”是一件十分簡單的事,只要調用System.out.println();即可,然而讀取“標准輸入流”就沒有這么簡單了,要想通過控制台進行輸入,首先要構建一個Scanner對象,並與“標准輸入流”System.in關聯
Scanner in = new Scanner(System.in);
我們用一個例子來說明,要注意的是,因為Scanner類定義在java.util包中,當使用的類不是定義在java.lang包中時,需要進行導包操作,下面是例子

1 Scanner in = new Scanner(System.in); 2 System.out.println("你的名字是?"); 3 String name = in.nextLine(); 4 System.out.println("你今年多大?"); 5 int age = in.nextInt(); 6 System.out.println("你的名字是:"+name+",你今年"+age+"歲"); 7 in.close();
需要了解的是nextLine()讀取的是下一行的內容,nextInt()方法則是讀取下一個數字
5.1.1 格式化輸出
從javaSE5.0開始沿用了c語言的printf方法
每個以%字符開始的格式說明符都用相應的參數替換,格式說明符尾部的轉化符將指示被格式化的數值類型,f代表浮點數,s代表字符串,d代表十進制。完整的轉換符網上都有,不一一列出。另外還有可以控制格式化輸出的各種標志,這里也不一一列出。
還可以使用靜態方法String.format()方法創建一個格式化的字符串,而不打印。

1 String name = "java"; 2 String s = String.format("hello,%s!", name); 3 System.out.println(s);
書上還介紹了關於printf方法中日期與時間的格式化選項,格式包括2個字符,以t開始后面加上合適的另外一個字母,下面是例子

1 //星期三 四月 10 10:58:30 CST 2019 2 System.out.printf("%tc", new Date()); 3 System.out.println();
但是,我們從表中可以看到,很多格式只給出指定日期的部分信息。代碼如下

System.out.printf("%tB", new Date()); //四月 System.out.println(); System.out.printf("%te", new Date()); //10 System.out.println(); //2019 System.out.printf("%tY", new Date());
這樣會導致需要多次對日期操作才能實現對每一部分進行格式化。這樣就會很麻煩。為此我們采用一個格式化的字符串指出要被格式化的參數索引,索引必須緊跟在%后面並且以$結尾,也可以用<標志,它指示前面的格式說明中的參數被再次使用
用例子來說明

1 //星期三 四月 10 10:58:30 CST 2019 2 System.out.printf("%s %tB %te %tY","Due date",new Date(),new Date(),new Date()); 3 System.out.println(); 4 System.out.printf("%1$s,%2$tB,%2$te,%2$tY","Due date",new Date()); 5 System.out.println(); 6 System.out.printf("%s,%tB,%<te,%<tY","Due date",new Date());
輸出的效果是一模一樣的
5.2 文件的輸入與輸出
如果想要對文件進行讀取,並且在控制台顯示它們,就需要用File對象構造一個Scanner對象,如下面例子

//hello World! Scanner in = new Scanner(Paths.get("D://project//yf.txt"),"UTF-8"); String s = in.nextLine(); System.out.println(s); in.close();
現在就可以用前面介紹的任何Scanner方法來對文件進行讀取
如果想要寫入文件,就需要構造一個PrintWirite對象,並在構造器中,提供文件名!如果文件不存在則會創建該文件
然后像System.out一樣使用println等方法寫入,例子如下

PrintWriter out = new PrintWriter("D://project//yf2.txt","UTF-8"); out.println("hello world!"); out.close();
6.1 控制流程
首先介紹塊的概念:塊(即復合語句)是指由一對大括號括起來的若干簡單的java語句。塊決定了變量的作用域。
一個塊可以嵌套在另一個塊中。但是不能在嵌套的兩個塊中聲明同名變量
6.2 條件語句
分if 和 if else 簡單不做說明
6.3 循環
分while();循環 true則一直運行下去
do{}while();它至少做一次
for();是支持迭代的一種通用結構,每次迭代后更新計數器或類似的變量來控制迭代次數。與c++一樣。盡管java允許在for循環的各個部分放置任何表達式,但是有一條不成文的規則:for語句的3個部分應該對同一個計數器變量進行初始化,檢測,更新。若不守規則,編寫的循環常常難以理解。for循環只不過是while循環的一種簡化形式
關於for循環還有注意的是:如果在for語句中定義一個變量,那么在循環體外這個變量就不能使用,如果希望在for循環外使用循環計數器的最終值,那么應該確保這個變量在循環語句外聲明。
6.4 switch語句
1 switch(choice){ 2 case 1: 3 . . . 4 break; 5 case 2: 6 . . . 7 break; 8 9 case 3: 10 . . . 11 break; 12 13 case 4: 14 . . . 15 break; 16 default: 17 . . . 18 break; 19 }
switch語句將從與選項值相匹配的case標簽開始執行,直到遇到break語句,或者執行到switch語句的結束處為止。
如果沒有相匹配的case標簽,而又default子句,那么執行這個子句。
case標簽可以是,char,byte,short,int的常量表達式,枚舉常量,從SE7開始可以是字符串字面量。
6.5 中斷控制流程語句
break,continue,還有帶標簽的break和continue。
break就是跳出循環,continue則是跳出這次循環。很好理解
而帶有標簽的break的意思就是,跳出帶有標簽的這個循環,我們用一個例子說明

1 for(){ 2 me: 3 for(){ 4 for(){ 5 ... 6 for(){ 7 break me; 8 } 9 } 10 } 11 }
這個例子中的意思就是,跳出帶有me標簽的這個循環。continue帶標簽也是這個用法。
6.6 對大數值的處理
如果基本的整數和浮點數精度不能滿足需求的話,可以使用java.math包中的兩個很有用的類:BigInteger和BigDecimal。
這兩個類可以處理包含任意長度數字序列的數值。BigInteger類實現了任意精度的整數運算,BigDecimal類實現了任意精度的浮點數運算。可以使用靜態的valueOf()將普通數值轉化為大數值。
BigInteger a = BigInteger.valueOf(100);
遺憾的是,不能使用熟悉的+,*,來處理大數值,而是用方法add()和multiply()
BigInteger a = BigInteger.valueOf(100); BigInteger b = a.add(a); BigInteger c = a.multiply(a); System.out.println(b);//200 System.out.println(c);//10000
7 數組
首先需要明確的是:數組是一種數據結構,用來儲存同一類型值得集合,可以通過一個整型下標來訪問數組中每一個值。
創建一個數字數組時,所有元素都初始化為0,boolean數組得元素會初始化為false,對象類型會初始化為null。還要注意一點,一旦創建了數組,它們得大小就確定了,不能修改它的大小(盡管可以修改每一個元素)。如果經常需要在運行過程中擴展數組的大小,就應該用另外一種數據結構-數組列表(array list)。
7.1 for each循環
java有一種功能很強大的循環結構,可以用來依次處理數組中的每個元素(其他類型的元素集合亦可)而不必為指定下標而分心。
for(variable : collection) statement
7.2 數組初始化以及匿名數組
java中,提供了一種創建數組對象並同時賦予初始化值的簡化書寫形式。
int[] a = {1,2,3,4,5};
甚至可以初始化一個匿名的數組
new int[] {1,2,3,4,5};
使用這種語法形式可以在不創建新變量的情況下重新初始化一個數組。
7.3 數組拷貝
在Java中允許將一個數組變量拷貝給另一個數組變量,這時,兩個變量將引用同一個數組。
如果希望一個數組的所有值都拷貝到另一個新的數組中去,就要用到Array類中的copyof方法,例子如下

int[] a = {1,2,3,4,5}; int[] b = Arrays.copyOf(a,a.length); for(int i : b){ System.out.println(i); }
如果后面的參數大於原數組的長度,如果數組元素時數值型,就補0,boolean就補false,相反如果小於原數組的長度,那么就賦值前面的元素。
7.4 數組排序
要想對數組型數組進行排序,可以用Arrays類中的sort方法,這個方法使用了優化的快速排序算法。快速排序算法對於大多數數據集合來說都是效率比較高的。例子
int[] a = {1,20,3,0,0,10}; Arrays.sort(a); for(int i : a){ System.out.print(i+" "); }
輸出為:0 0 1 3 10 20
7.5 多維數組
二數組:其實就是一維數組里面的元素都是一維數組。
int[][] a = new int[][];
int[][] a = {
{},
{},
};
java實際上沒有多維數組,只有一維數組。多維數組被解釋為“數組的數組”。
還有一個不規則數組的概念,就是數組的數組,但是它們的長度不一樣。
8 命令行參數
我們這里來講講main(String[] args)中的args,這表示main方法將接受一個字符串數組,也就是命令行參數
1 public class Hello { 2 3 public static void main(String[] args) { 4 // TODO Auto-generated method stub 5 for(String s : args){ 6 System.out.println(s); 7 } 8 } 9 10 }
結果是這樣的。這就可以說明args字符串變量存儲的就是
命令行參數。