Java 是由 Sun Microsystems 在 1995 年首先發布的編程語言和計算平台。有許多應用程序和 Web 站點只有在安裝 Java 後才能正常工作,而且這樣的應用程序和 Web 站點日益增多。Java 快速、安全、可靠。從筆記本電腦到數據中心,從游戲控制台到科學超級計算機,從手機到互聯網,Java 無處不在!
Java是一種計算機編程語言,擁有跨平台、面向對象、泛型編程的特性,廣泛應用於企業級Web應用開發和移動應用開發。
任職於太陽微系統的詹姆斯·高斯林等人於1990年代初開發Java語言的雛形,最初被命名為Oak,目標設置在家用電器等小型系統的程序語言,應用在電視機、電話、鬧鐘、烤面包機等家用電器的控制和通信。由於這些智能化家電的市場需求沒有預期的高,Sun公司放棄了該項計劃。隨著1990年代互聯網的發展,Sun公司看見Oak在互聯網上應用的前景,於是改造了Oak,於1995年5月以Java的名稱正式發布。Java伴隨著互聯網的迅猛發展而發展,逐漸成為重要的網絡編程語言。
Java編程語言的風格十分接近C++語言。繼承了C++語言面向對象技術的核心,Java捨棄了C++語言中容易引起錯誤的指針,改以引用替換,同時移除原C++與原來運算符重載,也移除多重繼承特性,改用接口替換,增加垃圾回收器功能。在Java SE 1.5版本中引入了泛型編程、類型安全的枚舉、不定長參數和自動裝/拆箱特性。太陽微系統對Java語言的解釋是:“Java編程語言是個簡單、面向對象、分布式、解釋性、健壯、安全與系統無關、可移植、高性能、多線程和動態的語言”
Java不同於一般的編譯語言或直譯語言。它首先將源代碼編譯成字節碼,然後依賴各種不同平台上的虛擬機來解釋執行字節碼,從而實現了“一次編寫,到處運行”的跨平台特性。在早期JVM中,這在一定程度上降低了Java程序的運行效率。但在J2SE1.4.2發布後,Java的運行速度有了大幅提升。
Java之所以被開發,是要達到以下五個目的:
Java技術主要分成幾個部分:Java語言、Java運行環境、類庫。一般情況下說Java時並不區分指的是哪個部分。
Java在1.5版本時,做了重大改變,太陽公司並1.5版本重命名為Java 5.0。
面向對象
Java的特點之一就是面向對象,是程序設計方法的一種。“面向對象程序設計語言”的核心之一就是開發者在設計軟件的時候可以使用自定義的類型和關聯操作。代碼和數據的實際集合體叫做“對象”。一個對象可以想象成綁定了很多“行為(代碼)”和“狀態(數據)”的物體。對於數據結構的改變需要和代碼進行通信然後操作,反之亦然。面向對象設計讓大型軟件工程的計劃和設計變得更容易管理,能增強工程的健康度,減少失敗工程的數量。
跨平台性
Java語言的第二個特性就是跨平台性,也就是說使用Java語言編寫的程序可以在編譯後不用經過任何更改,就能在任何硬件設備條件下運行。這個特性經常被稱為“一次編譯,到處運行”。
執行Java應用程序必須安裝Java Runtime Environment(JRE),JRE內部有一個Java虛擬機(Java Virtual Machine,JVM)以及一些標准的類庫(Class Library)。通過JVM才能在電腦系統執行Java應用程序(Java Application),這與.Net Framework的情況一樣,所以電腦上沒有安裝JVM,那麼這些程序將不能夠執行。
實現跨平台性的方法是大多數編譯器在進行Java語言程序的編碼時候會生成一個用字節碼寫成的“半成品”,這個“半成品”會在Java虛擬機(解釋層)的幫助下運行,虛擬機會把它轉換成當前所處硬件平台的原始代碼。之後,Java虛擬機會打開標准庫,進行數據(圖片、線程和網絡)的訪問工作。主要注意的是,盡管已經存在一個進行代碼翻譯的解釋層,有些時候Java的字節碼代碼還是會被JIT編譯器進行二次編譯。
有些編譯器,比如GCJ,可以自動生成原始代碼而不需要解釋層。但是這些編譯器所生成的代碼只能應用於特定平台。並且GCJ目前只支持部分的Java API。
甲骨文公司對於Java的許可是“全兼容的”,這也導致了微軟和升陽關於微軟的程序不支持RMI和JNI接口、並且增加特性為己所用的法律爭端。升陽最終贏得了官司,獲得了大約兩千萬美元的賠償,法院強制要求微軟執行升陽公司關於Java的許可要求。作為回應,微軟不再在Windows系統中捆綁Java,最新的Windows版本,Windows Vista和Internet Explorer 7.0版本也不再提供對於Java應用程序和控件的支持。但是升陽公司和其他使用Java運行時系統的公司在Windows操作系統下對用戶提供無償的第三方插件和程序支持。
Java語言使用解釋層最初是為了輕巧性。所以這些程序的運行效率比C語言和C++要低很多,用戶也對此頗有微詞。很多最近的調查顯示Java的程序運行速度比幾年前要高出許多,有些同樣功能的程序的效率甚至超過了C++和C語言編寫的程序。
Java語言在最開始應用的時候是沒有解釋層的,所有需要編譯的代碼都直接轉換成機器的原始代碼。這樣做的後果就是獲得了最佳的性能,但是程序臃腫異常。從JIT技術開始,Java的程序都經過一次轉換之後才變成機器碼。很多老牌的第三方虛擬機都使用一種叫做“動態編譯”的技術,也就是說虛擬機實時監測和分析程序的運行行為,同時選擇性地對程序所需要的部分進行編譯和優化。所有這些技術都改善了代碼的運行速度,但是又不會讓程序的體積變得失常。
程序的輕便性事實上是軟件編寫很難達到的一個目標,Java雖然成功地實現了“一次編譯,到處運行”,但是由於平台和平台之間的差異,所編寫的程序在轉換代碼的時候難免會出現微小的、不可察覺的錯誤和意外。有些程序員對此非常頭疼,他們嘲笑Java的程序不是“一次編譯,到處運行”,而是“一次編譯,到處調試”。以Java AWT為例,早期Java AWT內提供的按鈕、文字區等均是以電腦系統所默認的樣式而顯示。這令Java程序在有些沒有提供圖案的電腦系統產生錯誤(在Microsoft Windows設有窗口管理器,在一些Linux distribution則沒有)。後來SUN公司針對Java AWT一些問題而推出Java Swing。
平台無關性讓Java在服務器端軟件領域非常成功。很多服務器端軟件都使用Java或相關技術建立。
自動垃圾回收(Garbage Collection)
C++語言被用戶诟病的原因之一是大多數C++編譯器不支持垃圾收集機制。通常使用C++編程的時候,程序員於程序中初始化對象時,會在主機內存堆棧上分配一塊內存與地址,當不需要此對象時,進行析構或者刪除的時候再釋放分配的內存地址。如果對象是在堆棧上分配的,而程序員又忘記進行刪除,那麼就會造成內存洩漏(Memory Leak)。長此以往,程序運行的時候可能會生成很多不清除的垃圾,浪費了不必要的內存空間。而且如果同一內存地址被刪除兩次的話,程序會變得不穩定,甚至崩潰。因此有經驗的C++程序員都會在刪除之後將指針重置為NULL,然後在刪除之前先判斷指針是否為NULL。
C++中也可以使用“智能指針”(Smart Pointer)或者使用C++托管擴展編譯器的方法來實現自動化內存釋放,智能指針可以在標准類庫中找到,而C++托管擴展被微軟的Visual C++ 7.0及以上版本所支持。智能指針的優點是不需引入緩慢的垃圾收集機制,而且可以不考慮線程安全的問題,但是缺點是如果不善使用智能指針的話,性能有可能不如垃圾收集機制,而且不斷地分配和釋放內存可能造成內存碎片,需要手動對堆進行壓縮。除此之外,由於智能指針是一個基於模板的功能,所以沒有經驗的程序員在需要使用多態特性進行自動清理時也可能束手無策。
Java語言則不同,上述的情況被自動垃圾收集功能自動處理。對象的創建和放置都是在內存堆棧上面進行的。當一個對象沒有任何引用的時候,Java的自動垃圾收集機制就發揮作用,自動刪除這個對象所占用的空間,釋放內存以避免內存洩漏。
注意程序員不需要修改finalize
方法,自動垃圾收集也會發生作用。但是內存洩漏並不是就此避免了,當程序員疏忽大意地忘記解除一個對象不應該有的引用時,內存洩漏仍然不可避免。
不同廠商、不同版本的JVM中的內存垃圾回收機制並不完全一樣,通常越新版本的內存回收機制越快,IBM、BEA、SUN等等開發JVM的公司都曾宣稱過自己制造出了世界上最快的JVM,JVM性能的世界紀錄也在不斷的被打破並提高。
IBM有一篇有關Java內存回收機制比不激活垃圾收集機制的C++內存處理快數倍的技術文章,而著名的Java技術書籍《Java編程思想》(Thinking in Java)也有一段論述Java內存及性能達到甚至超過C++的章節。
Java的三種技術架構:
JAVAEE:Java Platform Enterprise Edition,開發企業環境下的應用程序,主要針對web程序開發;
JAVASE:Java Platform Standard Edition,完成桌面應用程序的開發,是其它兩者的基礎;
JAVAME:Java Platform Micro Edition,開發電子消費產品和嵌入式設備,如手機中的程序;
JDK下載地址:http://www.oracle.com/technetwork/cn/java/javase/downloads/jdk7-downloads-1880260.html
1,JDK:Java Development Kit,java的開發和運行環境,java的開發工具和jre。
2,JRE:Java Runtime Environment,java程序的運行環境,java運行的所需的類庫+JVM(java虛擬機)。
java運行分兩步:一個是編譯,一個是運行。
javac:負責的是編譯的部分,當執行javac時,會啟動java的編譯器程序。對指定擴展名的.java文件進行編譯。 生成了jvm可以識別的字節碼文件。也就是class文件,也就是java的運行程序。
java:負責運行的部分.會啟動jvm.加載運行時所需的類庫,並對class文件進行執行.
一個文件要被執行,必須要有一個執行的起始點,這個起始點就是main函數.
javac HelloWorld.java java HelloWorld.class
.class文件主要分為兩部分:
運行 java程序的運行過程有兩個階段:
public class HelloWorld { public static void main(String[] args) { System.out.println("Hello, World!"); } }
類型 占用存儲空間/字節 表數范圍 boolean 1/8 true & false char 2 存儲Unicode碼,單引號賦值 byte 1 -128 ~ 127 short 2 -2**15 ~ 2**15-1 int 4 -2**31 ~ 2**31-1 long 8 -2**63 ~ 2**63-1 float 4 -3.403E38 ~ 3.403E38 double 8 -1.798E308 ~ 1.798E3084類8種:
1> 邏輯型 -- boolean
2> 文本型 -- char
3> 整數型 -- byte, short, int, long
4> 浮點數型 -- float, double
float 與 double 的區別:
float表示單精度浮點數,32位二進制描述;
double表示雙精度浮點數,64位二進制表示;
double精度高,有效數字16位,float精度7位。但double消耗內存是float的兩倍,double的運算速度比float慢得多。
實數常量默認為 double;
整數常量默認為 int。
0x 和 10 內存中沒區別。
1> 十六進制整型常量:以十六進制表示時,需以0x或0X開頭,如0xff,0X9A。
2> 八進制整型常量:八進制必須以0開頭,如0123,034。
3> 長整型:長整型必須以L作結尾,如9L,342L。
4> 浮點數常量:由於小數常量的默認類型是double型,所以float類型的後面一定要加f(F)。同樣帶小數的變量默認為double類型。如:f=1.3f;
5> 字符常量:字符型常量需用兩個單引號括起來(注意字符串常量是用兩個雙引號括起來)。
Java中的字符占兩個字節。一些常用的轉義字符:
1> \r表示接受鍵盤輸入,相當於按下了回車鍵;
2> \n表示換行;
3> \t表示制表符,相當於Table鍵;
4> \b表示退格鍵,相當於Back Space鍵;
5> \'表示單引號;
6> \''表示雙引號;
7> \\表示一個斜槓\。
1> boolean 類型不可以轉換為其他的數據類型。
2> 容量小的類型自動轉換為容量大的數據類型(指表示值得范圍大小):
byte, short, char --> int --> long --> float --> double
byte, short, char 之間不會互相轉換,他們三者在計算時先會轉換為 int 類型
3> 容量大的數據類型轉換為容量小的數據類型時,要加上強制轉換符,可能會造成精度降低或溢出。
4> 有多種類型的數據混合運算時,系統首先自動的將所有數據類型轉換成容量最大的那一種數據類型,然後再進行計算。
c 語言之所以不能移植,是因為不同系統編譯後的類型長度不一致
byte b; b = 1; int i=b; // 1 long l=b; // 1 float f=b; // 1.0 double d=b; // 1.0 // 如果低級類型為char型,向高級類型(整型)轉換時,會轉換為對應ASCII碼值,例: char c='c'; int i=c; // 99 //對於byte,short,char三種類型而言,他們是平級的,因此不能相互自動轉換,可以使用下述的強制類型轉換。 short i=99; char c=(char)i; //c
// float 類型的兩種方式 // 在內存中的形式是不一樣的 float f1=0.1f; // 在內存中是float類型 float f2=(float)(0.1); // 在內存中是double類型,強制轉換為float類型
// long類型 long l1=123456; long l2=8888888888; // 錯誤!!! long l3=8888888888L; // 後面加L
// byte 類型 byte b1=1; byte b2=2; byte b3=129; // 錯誤!!!超過最大值
1> 算數運算符
+、 -、 *、 /、 %、 ++、 --
2> 賦值運算符
=、 +=、 -=、 *=、 /=、 %=
3> 關系運算符
>、 <、 >=、 <=、 ==、 !=
4> 邏輯運算符
!、 ^、 &、 &&、 |、 ||
除了 !(邏輯非) 都是用於連接兩個 boolean 類型表達式
&(邏輯與): 只有兩邊都為 true 結果是 true, 否則 false;
&&(短路與): 和 & 一樣,但如果左邊為 false,右邊就不參與運算;
|(邏輯或): 只有兩邊都為 flase 結果是 false, 否則是 true;
||(短路或): 和 | 一樣,但如果左邊為 true, 右邊就不參與運算;
^(邏輯異): 兩邊結果一樣為 false, 兩邊結果不一樣為 true;
5> 位運算符
&、 |、 ^、 ~、 >>、 <<、 >>>
// 自加自減練習 // ++、-- 在前面是先加減後賦值,在後面是先賦值在加減 int i1 = 10; int i2 = 20; int i = i2++; System.out.println("i:" + i); //20,是先賦值在自加! System.out.println("i2:" + i2); //21 i = ++i2; System.out.println("i:" + i); //22 System.out.println("i2:" + i2); //22 i = --i1; System.out.println("i:" + i); //9 System.out.println("i1:" + i1); //9 i = i1--; System.out.println("i:" + i); //9 System.out.println("i1:" + i1); //8 自加自減練習 // 邏輯運算符練習 boolean a, b, c; a = true; b=false; c = !a; System.out.println(c); //false c = a ^ b; System.out.println(c); //true c = a & b; System.out.println(c); //false c = a && b; System.out.println(c); //false c = a | b; System.out.println(c); //true c = a || b; System.out.println(c); //true 邏輯運算符練習
1> for 循環
for(初始化表達式;判斷表達式;遞增(遞減)表達式){
執行語句;
}
2> foreach 循環或者、加強型循環
for(類型 變量 : 數組){
執行語句;
}
JDK 1.5 引進了一種新的循環類型,被稱為 foreach 循環或者加強型循環,它能在不使用下標的情況下遍歷數組。
3> while 循環
while (條件){
操作;
}
4> do while 循環語句
do/while 語句與 while 語句不同的是,在判斷條件之前,先執行大括號內的循環體。
5> switch 語句
switch (key) {
case value:
...
break;
default:
...
break;
}
6> break & continue
跳出整個循環與跳出本次循環。
7> 三元運算
布爾表達式?值一:值二
布爾表達式為true結果為值一,表達式為false結果為值二
java三元表達式有字符強轉的功能,會把後面的強轉為和前面的類型一樣
public class OneHundredAnd{ public static void main(String[] args){ int result=0; for(int i=1;i<=100;i++){ result+=i; } System.out.println(result); } } for 循環, 計算1+2+3+4......+100的結果 public class TestArray { public static void main(String[] args) { double[] myList = {1.9, 2.9, 3.4, 3.5}; // 打印所有數組元素 for (double element: myList) { System.out.println(element); } } } foreach 循環 public class OneHundredAnd{ public static void main(String[] args){ int a=1,result=0; while(a<=100){ result+=a++; } System.out.println(result); } } while 循環, 計算1+2+3+4......+100的結果 public class OneHundredAnd{ public static void main(String[] args){ int a=1,result=0; do{ result+=a++; }while(a<=100); System.out.println(result); } } do while 循環, 計算1+2+3+4......+100的結果 public class PrimeNumbers{ public static void main(String[] args){ // 輸出100~200內的質數 // 只有1和它本身這兩個因數的自然數叫做質數.還可以說成質數只有1和它本身兩個約數. // 素數是這樣的整數,它除了能表示為它自己和1的乘積以外,不能表示為任 何其它兩個整數的乘積. // 例如: 12 =6×2=4×3,所以12不是素數. for (int i=101; i<200; i+=2){ for (int n=2; n<i; n++){ if (i % n != 0){ System.out.println(i); break; } } } } } 輸出100~200內的質數 public class DataConversion { public static void main(String[] args){ switch (18) { case 18: System.out.print("I'm eighteen years old, fighting."); break; case 19: case 20: case 21: case 22: System.out.print("I'm twenty years old, fighting."); break; default: System.out.print("Grow up to go away ^.^."); break; } } } case 語句 practice public class SimpleUnary{ public static void main(String[] args) { char a = 'a'; int b = 8; System.out.println(false?a:b); //打印b,b是8,所以打印出8 System.out.println(false?a:8); //打印8,但a是char型的,所以打印8的char字 //符,也就是backspace System.out.println(false?8:a); //打印int型,也就是a System.out.println(false?b:'a'); //打印a的ASCII碼 } } 三元運算 practice
所有的包裝類(Integer、Long、Byte、Double、Float、Short)都是抽象類 Number 的子類。
public class Numbers { public static String getType(Object o){ return o.getClass().toString(); } public static void main(String[] args){ // // xxxValue() 將number對象轉換為xxx數據類型的值並返回。 // Integer i1=1; // float f1 = i1.floatValue(); // System.out.println(f1 + " " + getType(f1)); //1.0 class java.lang.Float // int f2 = i1.intValue(); // System.out.println(f2 + " " + getType(f2)); //1 class java.lang.Integer // byte f3 = i1.byteValue(); // System.out.println(f3 + " " + getType(f3)); //1 class java.lang.Byte //// i1.compareTo(1); // // 比較這個Number對象的參數. 一樣返回0,否則-1. // Integer i1=1; // int i2 = i1.compareTo(1); // System.out.println(i2); // // 確定這個數字對象是否等於參數.一樣返回true,否則false. // Integer i1=1; // byte i2=1; // boolean i3 = i1.equals(i2); // System.out.println(i3); //false // //返回一個 Number 對象指定的內置數據類型 // //nteger.valueOf()方法基於減少對象創建次數和節省內存的考慮, // //緩存了[-128,127]之間的數字。此數字范圍內傳參則直接返回緩存中的對象。 // Integer i1=1; // Integer i2 = Integer.valueOf(i1); // System.out.println(i2); //1 // //以字符串形式返回值。 // Integer i1=1; // String i2 = i1.toString(); // System.out.println(i2); //1 // //將字符串解析為int類型。 // String i1="9"; // Integer i2 = Integer.parseInt(i1); // System.out.println(i2); //9 // //返回參數的絕對值。 // Integer i1=-1; // Integer i2 = Math.abs(i1); // System.out.println(i2); //1 // //對整形變量向左取整,返回類型為double型。 // int i1=1; // double i2 = Math.ceil(i1); // System.out.println(i2); //1.0 // //對整型變量向右取整。返回類型為double類型。 // int i1=1; // double i2 = Math.floor(i1); // System.out.println(i2); //1.0 // //返回與參數最接近的整數。返回類型為double。 // double i1=1.623; // double i2 = Math.rint(i1); // System.out.println(i2); //2.0 // //返回一個最接近的int、long型值。 // double i1=1.623; // long i2 = Math.round(i1); // System.out.println(i2); //2 // //返回兩個參數中的最小值。 // double i1=1.6; // double i2=1.8; // double i3 = Math.min(i1, i2); // System.out.println(i3); //1.6 // //返回兩個參數中的最大值。 // int i1=9; // int i2=5; // int i3 = Math.max(i1, i2); // System.out.println(i3); //9 // //返回兩個參數中的最大值。 // int i1=9; // int i2=5; // int i3 = Math.max(i1, i2); // System.out.println(i3); //9 // //返回自然數底數e的參數次方。 // double i1=9; // double i2 = Math.exp(i1); // System.out.println(i2); //8103.083927575384 // //返回參數的自然數底數的對數值。 // double i1=9; // double i2 = Math.log(i1); // System.out.println(i2); //2.1972245773362196 // //返回第一個參數的第二個參數次方。2的3次方. // double i1=2; // double i2=3; // double i3 = Math.pow(i1, i2); // System.out.println(i3); //8.0 // //求參數的算術平方根。 // double i1=9; // double i2 = Math.sqrt(i1); // System.out.println(i2); //3.0 // //求指定double類型參數的正弦值。 // double i1=3; // double i2 = Math.sin(i1); // System.out.println(i2); //3.0 // //求指定double類型參數的余弦值。 // double i1=3; // double i2 = Math.cos(i1); // System.out.println(i2); //-0.9899924966004454 // //求指定double類型參數的正切值。 // double i1=3; // double i2 = Math.tan(i1); // System.out.println(i2); //-0.1425465430742778 // //求指定double類型參數的反正弦值。NaN // double i1=1; // double i2 = Math.asin(i1); // System.out.println(i2); //1.5707963267948966 // //求指定double類型參數的反余弦值。NaN // double i1=2; // double i2 = Math.acos(i1); // System.out.println(i2); //0.0 // //求指定double類型參數的反正切值。 // double i1=3; // double i2 = Math.atan(i1); // System.out.println(i2); //1.2490457723982544 // //將笛卡爾坐標轉換為極坐標,並返回極坐標的角度值。 // double i1=3; // double i2=3; // double i3 = Math.atan2(i1, i2); // System.out.println(i3); //0.7853981633974483 // //將參數轉化為角度。 // double i1=3; // double i2 = Math.toDegrees(i1); // System.out.println(i2); //171.88733853924697 // //將角度轉換為弧度。 // double i1=3; // double i2 = Math.toRadians(i1); // System.out.println(i2); //0.05235987755982988 // //返回一個隨機數。 // double i1 = Math.random(); // System.out.println(i1); //0.9591935059236623 } } Number practice
Character 類用於對單個字符進行操作。
Character 類在對象中包裝一個基本類型 char 的值
public class Characters { public static void main(String[] args){ char c1 = 'm'; // //是否是一個字母 // boolean b1 = Character.isLetter(c1); // System.out.println(b1); //true // //是否是一個數字字符 // boolean b1 = Character.isDigit(c1); // System.out.println(b1); //false // //是否是一個空格 // boolean b1 = Character.isWhitespace(c1); // System.out.println(b1); //false // //是否是大寫字母 // boolean b1 = Character.isUpperCase(c1); // System.out.println(b1); //false // //是否是小寫字母 // boolean b1 = Character.isLowerCase(c1); // System.out.println(b1); //true // //指定字母的大寫形式,變大寫 // char b1 = Character.toUpperCase(c1); // System.out.println(b1); //M // //指定字母的小寫形式,變小寫 // char b1 = Character.toLowerCase(c1); // System.out.println(b1); //m // //返回字符的字符串形式,字符串的長度僅為1 // String b1 = Character.toString(c1); // System.out.println(b1); //m } } Character practice
使用關鍵字和構造方法來創建 String 對象。
String 類是不可改變的,所以你一旦創建了 String 對象,那它的值就無法改變了(如果需要對字符串做很多修改,那麼應該選擇使用 StringBuffer & StringBuilder 類)
String 類有 11 種構造方法,這些方法提供不同的參數來初始化字符串,比如提供一個字符數組參數:
public class StringDemo{ public static void main(String args[]){ char[] hello = { 's', 'u', 'o', 'n', 'i', 'n', 'g'}; String hellos = new String(hello); System.out.println( hellos ); } }String() 初始化一個新創建的 String 對象,它表示一個空字符序列。 String(byte[] bytes) 構造一個新的 String,方法是使用平台的默認字符集解碼字節的指定數組。 String(byte[] ascii, int hibyte) 已過時。 該方法無法將字節正確轉換為字符。從 JDK 1.1 起,完成該轉換的首選方法是通過 String 構造方法,該方法接受一個字符集名稱或使用平台的默認字符集。 String(byte[] bytes, int offset, int length) 構造一個新的 String,方法是使用指定的字符集解碼字節的指定子數組。 String(byte[] ascii, int hibyte, int offset, int count) 已過時。 該方法無法將字節正確轉換為字符。從 JDK 1.1 開始,完成該轉換的首選方法是通過 String 構造方法,它接受一個字符集名稱,或者使用平台默認的字符集。 String(byte[] bytes, int offset, int length, String charsetName) 構造一個新的 String,方法是使用指定的字符集解碼字節的指定子數組。 String(byte[] bytes, String charsetName) 構造一個新的 String,方法是使用指定的字符集解碼指定的字節數組。 String(char[] value) 分配一個新的 String,它表示當前字符數組參數中包含的字符序列。 String(char[] value, int offset, int count) 分配一個新的 String,它包含來自該字符數組參數的一個子數組的字符。 String(int[] codePoints, int offset, int count) 分配一個新的 String,它包含該 Unicode 代碼點數組參數的一個子數組的字符。 String(String original) 初始化一個新創建的 String 對象,表示一個與該參數相同的字符序列;換句話說,新創建的字符串是該參數字符串的一個副本。 String(StringBuffer buffer) 分配一個新的字符串,它包含當前包含在字符串緩沖區參數中的字符序列。 String 類 11 種構造方法
import java.nio.charset.Charset; import javax.print.DocFlavor.BYTE_ARRAY; public class Strings { public static void main(String[] args){ String s1 = "suoning"; String s2 = "nick"; // //返回指定索引處的 char 值。 // char c1 = s1.charAt(3); // System.out.println(c1); //n // //把這個字符串和另一個對象比較.等於返回0,此字符串小於字符串參數返回小於0,大於返回大於0. // int c1 = s1.compareTo(s2); // System.out.println(c1); //5 // //將指定字符串連接到此字符串的結尾。 // String c1 = s1.concat(s2); // System.out.println(c1); //suoningnick // //當且僅當字符串與指定的StringButter有相同順序的字符時候返回真。 // StringBuffer s3 = new StringBuffer("suoning"); // boolean c1 = s1.contentEquals(s3); // System.out.println(c1); //true // //返回指定數組中表示該字符序列的 String。 // char[] s3 = {'s', 'u', 'o', ' ', 'n', 'i', 'n', 'g'}; // String c1 = s1.copyValueOf(s3); // System.out.println(c1); //suo ning // String c2 = s1.copyValueOf(s3, 1, 6); // System.out.println(c2); //uo nin // //測試此字符串是否以指定的後綴結束。 // boolean c1 = s1.endsWith(s2); // System.out.println(c1); //false // //將此字符串與指定的對象比較。 // boolean c1 = s1.equals(s2); // System.out.println(c1); //false // //將此 String 與另一個 String 比較,不考慮大小寫。 // boolean c1 = s1.equalsIgnoreCase(s2); // System.out.println(c1); //false // //使用平台的默認字符集將此 String 編碼為 byte 序列,並將結果存儲到一個新的 byte 數組中。 // byte[] c1 = s1.getBytes(); // System.out.println(c1); //[B@11e78461 // //將字符從此字符串復制到目標字符數組。 // //srcBegin -- 字符串中要復制的第一個字符的索引。 rcEnd -- 字符串中要復制的最後一個字符之後的索引。 // //dst -- 目標數組。 dstBegin -- 目標數組中的起始偏移量。 // //沒有返回值,但會拋出 IndexOutOfBoundsException 異常。 // //char[] s3 = new char[5]; // s1.getChars(1,6,s3,0); // System.out.println(s3); //uonin // //返回此字符串的哈希碼。 // int s3 = s1.hashCode(); // System.out.println(s3); //-1855756159 // //返回指定字符在此字符串中第一次出現處的索引。 // int s3 = s1.indexOf('s'); // System.out.println(s3); //0 // //返回在此字符串中第一次出現指定字符處的索引,從指定的索引開始搜索。 // int s3 = s1.indexOf('n', 3); // System.out.println(s3); //3 // // 返回字符串對象的規范化表示形式。 // String s3 = s1.intern(); // System.out.println(s3); //suoning // // 返回指定字符在此字符串中最後一次出現處的索引。 // int s3 = s1.lastIndexOf('n'); // System.out.println(s3); //5 // // 返回指定字符在此字符串中最後一次出現處的索引,從指定的索引處開始進行反向搜索。 // int s3 = s1.lastIndexOf('n', 3); // System.out.println(s3); //3 // // 返回指定子字符串在此字符串中最右邊出現處的索引。 // String s4 = new String("ning"); // int s3 = s1.lastIndexOf(s4); // System.out.println(s3); //3 // //返回指定子字符串在此字符串中最後一次出現處的索引,從指定的索引開始反向搜索。 // String s4 = new String("ning"); // int s3 = s1.lastIndexOf(s4, 2); // System.out.println(s3); //-1 // //返回此字符串的長度。 // int s3 = s1.length(); // System.out.println(s3); //7 // //告知此字符串是否匹配給定的正則表達式。 // boolean s3 = s1.matches("suo(.*)"); // System.out.println(s3); //true //測試兩個字符串區域是否相等。 //ignoreCase -- 如果為 true,則比較字符時忽略大小寫。 //toffset -- 此字符串中子區域的起始偏移量。 //other -- 字符串參數。 //toffset -- 字符串參數中子區域的起始偏移量。 //len -- 要比較的字符數。 // boolean s3 = s1.regionMatches(3, s2, 6, 4); // System.out.println(s3); //false // boolean s3 = s1.regionMatches(true, 3, s2, 6, 4); // System.out.println(s3); //false // //返回一個新的字符串,它是通過用 newChar 替換此字符串中出現的所有 oldChar 得到的。 // String s3 = s1.replace(' ', 'm'); // System.out.println(s3); //suoning // //返回一個新的字符串,它是通過用 newChar 替換此字符串中出現的所有 oldChar 得到的。 // String s3 = s1.replace(' ', 'm'); // System.out.println(s3); //suoning // // 使用給定的 replacement 替換此字符串所有匹配給定的正則表達式的子字符串。 // String s3 = s1.replaceAll(".*", "m"); // System.out.println(s3); //mm // //使用給定的 replacement 替換此字符串匹配給定的正則表達式的第一個子字符串。 // String s3 = s1.replaceFirst("n", "m"); // System.out.println(s3); //suoming // //根據給定正則表達式的匹配拆分此字符串。 // String s5 = new String("suo ning"); // String[] s3 = s5.split(" ", 0); // for (String retval: s3){ // System.out.println(retval); //suo、ning // } // // 測試此字符串是否以指定的前綴開始。 // boolean b1 = s1.startsWith(s2); // System.out.println(b1); //false // //測試此字符串從指定索引開始的子字符串是否以指定前綴開始。 // boolean b1 = s1.startsWith(s2, 3); // System.out.println(b1); //false // //返回一個新的字符序列,它是此序列的一個子序列。 // String s3 = s1.substring(2, 6); // System.out.println(s3); //onin // //返回一個新的字符序列,它是此序列的一個子序列。 // CharSequence s3 = s1.subSequence(2, 6); // System.out.println(s3); //onin // //返回一個新的字符序列,它是此序列的一個子字符串。 // String s3 = s1.substring(2, 6); // System.out.println(s3); //onin // String s3 = s1.substring(2); // System.out.println(s3); //oning // //將此字符串轉換為一個新的字符數組。 // System.out.println(s1.toCharArray()); //suoning // //使用默認語言環境的規則將此 String 中的所有字符都轉換為小寫。 // String s3 = s1.toLowerCase(); // System.out.println(s3); //suoning // // 返回此對象本身(它已經是一個字符串! // String s3 = s1.toString(); // System.out.println(s3); //suoning // // 使用默認語言環境的規則將此 String 中的所有字符都轉換為大寫。 // String s3 = s1.toUpperCase(); // System.out.println(s3); //SUONING // // 返回字符串的副本,忽略前導空白和尾部空白。 // String s3 = s1.trim(); // System.out.println(s3); //suoning // // 返回給定data type類型x參數的字符串表示形式。 // String s3 = String.valueOf(s1); // System.out.println(s3); //suoning } } String practice
當對字符串進行修改的時候,需要使用 StringBuffer 和 StringBuilder 類。
和 String 類不同的是,StringBuffer 和 StringBuilder 類的對象能夠被多次的修改,並且不產生新的未使用對象。
StringBuilder 類在 Java 5 中被提出,它和 StringBuffer 之間的最大不同在於 StringBuilder 的方法不是線程安全的(不能同步訪問)。
由於 StringBuilder 相較於 StringBuffer 有速度優勢,所以多數情況下建議使用 StringBuilder 類。然而在應用程序要求線程安全的情況下,則必須使用 StringBuffer 類。
int
參數的字符串表示形式插入此序列中
5
replace(int start, int end, String str)String
中的字符替換此序列的子字符串中的字符
6
int capacity()char
值。
8
void ensureCapacity(int minimumCapacity)dst
。
10
int indexOf(String str)ch
。
16
void setLength(int newLength)String
,它包含此字符序列當前所包含的字符子序列。
19
String substring(int start, int end)String
,它包含此序列當前所包含的字符子序列。
20
String toString()public class StringBufferBuilders { public static void main(String[] args){ StringBuffer s1 = new StringBuffer("suoning"); // //將指定的字符串追加到此字符序列。 // String s2 = "nick"; // StringBuffer s3 = s1.append(s2); // System.out.println(s3); //suoningnick // //將此字符序列用其反轉形式取代。 // StringBuffer s3 = s1.reverse(); // System.out.println(s3); //gninous // //移除此序列的子字符串中的字符。 // StringBuffer s3 = s1.delete(0, 3); // System.out.println(s3); //ning // //將 int 參數的字符串表示形式插入此序列中。 // StringBuffer s3 = s1.insert(3, 99); // System.out.println(s3); //suo99ning // //使用給定 String 中的字符替換此序列的子字符串中的字符。 // StringBuffer s3 = s1.replace(0, 3, "nick"); // System.out.println(s3); //nickning // //返回當前容量。 // int s3 = s1.capacity(); // System.out.println(s3); //23 // //返回此序列中指定索引處的 char 值。 // char s3 = s1.charAt(3); // System.out.println(s3); //n // //確保容量至少等於指定的最小值。 // s1.ensureCapacity(1); // System.out.println(s1.capacity()); //23 // //將字符從此序列復制到目標字符數組 dst。 // char[] s2 = new char[4]; // s1.getChars(3,7,s2,0); // System.out.println(s2); //ning // //返回第一次出現的指定子字符串在該字符串中的索引。 // String s2 = "nick"; // int s3 = s1.indexOf(s2); // System.out.println(s3); //-1 // //從指定的索引處開始,返回第一次出現的指定子字符串在該字符串中的索引。 // String s2 = "nick"; // int s3 = s1.indexOf(s2, 2); // System.out.println(s3); //-1 // //返回最右邊出現的指定子字符串在此字符串中的索引。 // String s2 = "nick"; // int s3 = s1.lastIndexOf(s2); // System.out.println(s3); //-1 // //返回最後一次出現的指定子字符串在此字符串中的索引。 // String s2 = "nick"; // int s3 = s1.lastIndexOf(s2, 3); // System.out.println(s3); //-1 // // 返回長度(字符數)。 // int s3 = s1.length(); // System.out.println(s3); //7 // //將給定索引處的字符設置為 ch。 // s1.setCharAt(3, 'm'); // System.out.println(s1); //suoming // //設置字符序列的長度 // s1.setLength(9); // System.out.println(s1.length()); //9 // //返回一個新的字符序列,該字符序列是此序列的子序列。 // CharSequence s3 = s1.subSequence(3, 7); // System.out.println(s3); //ning // //返回一個新的 String,它包含此字符序列當前所包含的字符子序列。 // String s3 = s1.substring(3); // System.out.println(s3); //ning // //返回一個新的 String,它包含此序列當前所包含的字符子序列。 // String s3 = s1.substring(3,7); // System.out.println(s3); //ning // //返回此序列中數據的字符串表示形式 // String s3 = s1.toString(); // System.out.println(s3); //suoning } } StringBuffer & StringBuilder practice
Java 語言中提供的數組是用來存儲固定大小的同類型元素。
// 申明及創建數組 int a1[] = new int[6]; //不推薦寫法,來源於C/C++ int[] a2 = new int[6]; int[] a3 = {1, 2, 3, 4, 5, 6};
數組的元素是通過索引訪問的。數組索引從 0 開始,所以索引值從 0 到 a2.length-1。
//多維數組 String s[][] = new String[5][9]; s[0][0] = new String("nick"); s[0][1] = new String("good"); s[1][0] = new String("jenny"); s[1][1] = new String("yep"); s[1][2] = new String("!");public class TestArray { public static void main(String[] args) { double[] myList = {1.9, 2.9, 3.4, 3.5}; // 打印所有數組元素 for (int i = 0; i < myList.length; i++) { System.out.println(myList[i] + " "); } // 計算所有元素的總和 double total = 0; for (int i = 0; i < myList.length; i++) { total += myList[i]; } System.out.println("Total is " + total); // 查找最大元素 double max = myList[0]; for (int i = 1; i < myList.length; i++) { if (myList[i] > max) max = myList[i]; } System.out.println("Max is " + max); } } 數組 practice
java.util.Arrays 類能方便地操作數組,它提供的所有方法都是靜態的。
import java.util.Arrays; public class MyArrayOfs { public static void main(String[] args){ int a1[] = new int[6]; int[] a2 = new int[6]; int[] a3 = {1, 2, 3, 4, 5, 6}; int[] a5 = {1, 2, 3, 9, 8, 8}; int[] a6 = {1, 2, 3, 4, 5, 6}; // // public static boolean equals(long[] a, long[] a2) // //如果兩個指定的 long 型數組彼此相等,則返回 true。如果兩個數組包含相同數量的元素,並且兩個數組中的所有相應元素對都是相等的,則認為這兩個數組是相等的。換句話說,如果兩個數組以相同順序包含相同的元素,則兩個數組是相等的。同樣的方法適用於所有的其他基本數據類型(Byte,short,Int等)。 // boolean b1 = Arrays.equals(a3, a5); // System.out.println(b1); //false // boolean b2 = Arrays.equals(a3, a6); // System.out.println(b2); //true // //public static void fill(int[] a, int val) // //填充值 // //將指定的 int 值分配給指定 int 型數組指定范圍中的每個元素。同樣的方法適用於所有的其他基本數據類型(Byte,short,Int等)。 // Arrays.fill(a2, 9); // System.out.println(a2[5]); //9 // //public static void sort(Object[] a) // //對指定對象數組根據其元素的自然順序進行升序排列。同樣的方法適用於所有的其他基本數據類型(Byte,short,Int等)。 // Arrays.sort(a5); // for(int i: a5) { // System.out.println(i); //1、2、3、8、8、9 // } // //public static int binarySearch(Object[] a, Object key) // //用二分查找算法在給定數組中搜索給定值的對象(Byte,Int,double等)。數組在調用前必須排序好的。如果查找值包含在數組中,則返回搜索鍵的索引;否則返回 (-(插入點) - 1)。 // int index1 = Arrays.binarySearch(a5, 9); // System.out.println(index1); //-7 // Arrays.sort(a5); // int index2 = Arrays.binarySearch(a5, 8); // System.out.println(index2); //4 // int index3 = Arrays.binarySearch(a5, 9); // System.out.println(index3); //5 } } 數組 practice
java.util 包提供了 Date 類來封裝當前的日期和時間。
# 實例化 Date 對象 import java.util.Date; Date d1 = new Date(); long t1 = 1514736000000L; Date d2 = new Date(t1); System.out.println(d1); //Mon Dec 05 23:59:59 CST 2016 System.out.println(d2); //Mon Jan 01 00:00:00 CST 2018
Date 對象的方法:
import java.util.Date; public class DateTimes { public static void main(String[] args){ Date d1 = new Date(); long t1 = 1514736000000L; Date d2 = new Date(t1); System.out.println(d1); //Mon Dec 05 23:59:59 CST 2016 System.out.println(d2); //Mon Jan 01 00:00:00 CST 2018 // // boolean after(Date date) // //若當調用此方法的Date對象在指定日期之前\後返回true,否則返回false。 // boolean b1 = d2.after(d1); // System.out.println(b1); //true // // int compareTo(Date date) // //比較當調用此方法的Date對象和指定日期。兩者相等時候返回0。調用對象在指定日期之前則返回負數。調用對象在指定日期之後則返回正數 // int b1 = d2.compareTo(d1); // System.out.println(b1); //1 // // int compareTo(Object obj) // //若obj是Date類型則操作等同於compareTo(Date) 。否則它拋出ClassCastException。 // int b1 = d2.compareTo(d1); // System.out.println(b1); //1 // //boolean equals(Object date) // //當調用此方法的Date對象和指定日期相等時候返回true,否則返回false // boolean b1 = d2.equals(d1); // System.out.println(b1); //false // // long getTime( ) // //返回自 1970 年 1 月 1 日 00:00:00 GMT 以來此 Date 對象表示的毫秒數。 // long l1 = d2.getTime(); // System.out.println(l1); //1514736000000 // //int hashCode( ) // //返回此對象的哈希碼值。 // long l1 = d2.hashCode(); // System.out.println(l1); //-1387455136 // //void setTime(long time) // //用自1970年1月1日00:00:00 GMT以後time毫秒數設置時間和日期。 // d1.setTime(t1); // System.out.println(d1); //Mon Jan 01 00:00:00 CST 2018 // //String toString( ) // //轉換Date對象為String表示形式,並返回該字符串。 // d2.toString(); // System.out.println(d2); //Mon Jan 01 00:00:00 CST 2018 } } Date practice import java.util.Date; public class DateDemo { public static void main(String args[]) { // 初始化 Date 對象 Date date = new Date(); // 使用 toString() 函數顯示日期時間 System.out.println(date.toString()); } } 獲取當前日期時間
//使用兩個字母格式,它以t開頭並且以下面表格中的一個字母結尾。 import java.util.Date; public class DateTimes { public static void main(String args[]) { //初始化 Date 對象 Date date = new Date(); //使用toString()顯示日期和時間 String str = String.format("Current Date/Time : %tc", date ); System.out.println(str); //Current Date/Time : Sat Jan 1 00:00:00 MST 2018 System.out.printf("%1$s %2$tB %2$td, %2$tY", "Due date:", date); //Jan date: January 01, 2018 System.out.printf("%s %tB %<te, %<tY", "Due date:", date); //Jan date: January 01, 2018 } }//解析字符串為時間 import java.util.*; import java.text.*; public class DateTimes { public static void main(String args[]) { SimpleDateFormat ft = new SimpleDateFormat ("yyyy-MM-dd"); String input = args.length == 0 ? "2018-01-01" : args[0]; System.out.print(input + " Parses as "); Date t; try { t = ft.parse(input); System.out.println(t); } catch (ParseException e) { System.out.println("Unparseable using " + ft); //2018-01-01 Parses as Mon Jan 01 00:00:00 CST 2018 } } } 解析字符串為時間 //Java 休眠(sleep) import java.util.*; public class DateTimes { public static void main(String args[]) { try { System.out.println(new Date( ) + "\n"); Thread.sleep(1000*3); // 休眠3秒 System.out.println(new Date( ) + "\n"); } catch (Exception e) { System.out.println("Got an exception!"); } } } Java 休眠(sleep) //檢測時間間隔(以毫秒為單位) import java.util.*; public class DateTimes { public static void main(String args[]) { try { long start = System.currentTimeMillis( ); System.out.println(new Date( ) + "\n"); Thread.sleep(5*20*5); System.out.println(new Date( ) + "\n"); long end = System.currentTimeMillis( ); long diff = end - start; System.out.println("Difference is : " + diff); //Difference is : 520 } catch (Exception e) { System.out.println("Got an exception!"); } } } 檢測時間間隔