第一章 Java語言概述與開發環境
一、java程序的運行機制
1.語言的分類
編譯型語言:如C++等,在特定的操作系統上編譯為機器語言,執行效率高,但是通常無法在系統間移植,需要重新修改並編譯。
解釋型語言:如ruby、Python,用專用的解釋器對源程序逐行解釋成特定平台的機器碼並立即執行,不是編譯生成可執行文件,而是每次運行,都需要重新解釋一遍,直接運行。執行效率低,但是具有跨平台特性。
混合型語言:java是先編譯成與系統無關的字節碼,即*.class文件,再由解釋器來解釋執行,即java虛擬機(java virtual machine),class文件只需要面向jvm,不同操作系統的jvm不同,但是接口相同,jvm相當於一種轉換器,jvm是java實現跨平台的原因。
2.Java基礎知識
JDK(java development kit)提供編譯運行java程序所需的各種工具和資源,包括java編譯器,java運行環境(JRE,java runtime environment,包含jvm和其他環境支持。),以及java類庫。
安裝目錄下的文件夾
Bin:存放jdk的各種工具命令,常用的javac、java命令就是在該路徑下。
Lib:存放了bin目錄下命令的實際執行程序。
Src.zip:核心類庫的源代碼。
設置環境變量,將bin目錄的路徑添加環境變量,這樣系統就可以找到javac和java等命令,來編譯生成字節碼、解釋運行字節碼。
3.編譯運行helloworld程序
添加環境變量后,系統可以找到編譯命令javac,所以在命令行窗口輸入
編譯
Javac –d desdir srcfile 可以用.號代替desdir,表示當前路徑 , java文件中定義了多少個個,就生成多少個class文件。
運行
Java helloworld //java 是運行命令(類名稱)
4.CLASSPATH設置環境變量和定位類
1.4版本以前的jdk需要設置環境變量CLASSPATH用來指定運行java程序時,查找class文件的路徑,用.表示當前路徑,並添加“安裝目錄\lib\dt.jar”和“安裝目錄\lib\tools.jar”兩個目錄路徑,指定加載java類。
1.5版本后,不需要添加CLASSPATH環境變量,和dt.jar、tools.jar的路徑。如果添加了,則按照添加的路徑搜索。
也可以用–classpath命令參數臨時指定搜索路徑,會嚴格按照指定路徑搜索,不會在當前路徑下搜索。CLASSPATH環境變量設置的路徑臨時無效。
Java –classpath dir1;dir2;…….dirN 執行的java類名
5.java程序的基本規則
純面向對象,所有的東西必須放在類里,空類編譯可以,運行時找不到入口函數報錯,入口函數的格式是不可變的。Java程序有很多個類,只要有一個類有入口函數即可。
public class helloworld
{
public static void main(String[] args)
{
System.out.println("Hello World!");
}
}
6.Java源文件命名規則
Java源文件中只可以有一個public類,且源文件的名稱必須與該類名相同,可以有多個類,可以沒有public類,此時文件名隨便定義。
7.常見問題
設置CLASSPATH環境變量,沒有加點,不能搜索當前路徑;java大小寫是區分的;java的安裝路徑不要包含空格;
8.垃圾回收機制
當一個對象不再被引用時,JRE會有一個后台線程來檢測和回收對象,並整理內存碎片,解決了內存泄漏的問題,但是增大了開銷,影響性能,且回收算法不能100%搜集所有內存。將對象的引用設置為null,即表示可以回收該對象。回收機制能標記活着的對象,能定位對象之間的引用關系。
第二章理解面向對象
面向對象的編程粒度比面向過程大,java不支持多繼承。面向對象軟件開發需要經過單個過程:OOA(面向對象分析,對目標系統進行分析,建立分析模型,文檔化),OOD(面向對象設計,將文檔進行細化,得出設計模式。),OOP(面向對象編程)。
1.UML(universal model language)對程序進行建模
用例圖:描述系統的功能,以橢圓表示用例,人形表示角色。
類圖:顯示系統的靜態結構,包括類名,類屬性,類方法;以及類之間的關系。
類之間有三種關系
關聯關系:一條實線表示雙向關聯,一條箭頭表示單向關聯,實心箭頭表示組合關系,空心箭頭表示聚合關系,聚合關系的實體可以同時是另外一個實體的一部分,比如學生可以籃球協會的會員,同時也是 協會的會員;組合關系的不可以,比如一個人的老婆不可以同時是另外一個人的老婆。
泛化關系:即繼承關系,用一個空心箭頭表示。
依賴關系:改動一個類,需要被動的改動另外一個類。用虛線箭頭表示。
組件圖:組件相當於一個功能模塊,包括組件名稱、接口、和port等圖元,組件圖顯示系統中組件的依賴關系。
部署圖:用於描述軟件系統如何部署到硬件環境中,系統的不同組件之間的分布地理位置、通訊方式、依賴關系。
順序圖:用於描述各個用例之間的交互信息、交互關系和交互順序,時間順序是從上往下的,交互對象的順序是水平方向箭頭指定的順序。
Java不允許直接訪問對象,而是通過對象的引用來操作對象。Java類之間有兩種關系:一般特殊關系,例如水果與蘋果;整體與部分關系,例如身體和手臂的關系。
第三章數據類型和運算符
Java是一個強類型的語言,變量需先聲明后使用,數值類型之間可以自動或強制類型轉換。
1.文檔注釋
Java的文檔注釋是對java基礎類的一個說明,包括類的功能介紹,使用方法,可在官方網站下載。打開index.html即可查看目錄。可以在自定義的類中添加文檔注釋,用javadoc命令生成文檔,Javadoc只處理源文件在類、接口、方法、成員變量、構造器和內部類之前的注釋,忽略其他地方的文檔注釋,只處理public和protect標記的類、接口、方法、成員變量、構造器和內部類。加上參數-private,可以提取私有的。開始/**,結束*/。
格式:javadoc 參數 java源文件或者包
支持*.Java,表示所有的java文件,
參數包括三種
-private 提取私有的文檔注釋
-d<路徑> 指定生成的API文檔路徑
-windowtitle<一個字符串,指定API文檔的瀏覽器窗口標題>
-doctitle<字符串,指定概述頁面的標題>
在文檔注釋中用@加上一些變量名稱,指定咋文檔中生成對應的選項。
@author 作者
@version 版本
@deprecated 不推薦使用的方法
@param 方法參數說明信息,
@return 返回值說明信息
@see 參考內容
@拋出異常的類容
使用@author 作者 @version 版本兩個是需要在javadoc命令中加入 –author 和-version 兩個命令參數,其他的不用。
2.標識符和關鍵字
Java可以跨越多行書寫,一個字符串或變量名不能跨多行書寫。
Java的變量名稱,可以是中文字符日文字符美元符號。
Java所有的 關鍵字都是小寫,例如false;
用超出int范圍的值給long變量賦值時,數值后面加上l或L表示long數據,否則會出錯。
二進制0B或0b開頭,八進制0開頭,十六進制以0x或0X開頭,負數以補碼的形式保存在程序中,補碼是源碼取反加一。
Java底層保存的字符的編號是0~65535之間的數字,所以可以可以直接計算。
3.基本數據類型
char兩個字節,字符類型String用雙引號表示,反斜杠需要用轉義字符\\。float只能表示8位小數,默認浮點數為double類型,若想表示float值,則后面加上f或F,512表示成指數形式為5.12E2。
java提供三個特殊的浮點值:正無窮大(POAITIVE_INFINITY,正浮點數除以0)、負無窮大(NEGATIVE_INFINITY,負浮點數除以0),非值(NaN,0.0/0.0或者0/0.0或者0.0/0,或者對一個負數開方,0/0出現異常。),NaN不與任何值相等,與NaN自己都不相等。正數除以0會出現異常。用下划線分隔數字,清楚的看出是多少位。
Java的boolean是一種特殊的數據類型,只要一位保存,但由於計算機最小分配單元是字節,所以實際是占1字節,它的取值可以是true或false。它與其他數據類型之間不能相互賦值。String str=true+“”;str會變成“true”;數值型變量也可+“”變為字符串。字符串不能直接轉化為基本類型,需要包裝類integer.parseInt(“54”);
System.out.println(‘a’+7+”hello”);輸出結果為104hello
4.直接量
Null直接量可以直接賦值給String或者引用類型的變量。
第一次使用string直接量時,java類中會有一個常量池保存,后續再使用該字符串直接量時,使用常量池中的直接量。常量池指在編譯期間,保存.class中的數據包括類接口、方法中的常量,和字符串直接量。String s2=”hel”+”lo”;String s1=”hello”;s1和s2都是常量池中hello的引用。
Java支持連續復制,但可讀性不強,不建議。
取反位運算符包括符號位一起取反,負數的取反是對補碼的取反,取反之后變為正數。-5取反之后是4。
左移用0補齊后面空白,右移用符號位補齊空白,無符號右移>>>是用0補齊左邊的空白。
位運算時,byte,char,short自動轉化為int,為32位,移動位數a需要對32取余后運算。Long是對64取余。
邏輯運算符&和|具有不短路的功能,即第一個為false時繼續執行第二個,^兩個操作數不同時返回true。
第四章流程控制與數組
1.流程控制
Java7的switch語句可以是java.lang.String類型的變量和表達式,不能是stringBuffer或StringBuilder。
2.數組
定義數組格式建議用type[] arrayname;不建議采用type arrayname[];把type[]看成是一種類型。數組靜態初始化:程序員指定初始值,系統決定數組長度;
Array=new type[] {元素1,元素2…..};
Jianhua簡化的初始化type[] Array= {元素1,元素2…..};定義的同時初始化。
動態初始化:程序員指定數組長度,系統分配初始值。
type[] Arrayname=new type[10]; 默認初始值整數為0,浮點數為0.0,字符為‘\u0000’,boolean為false,引用為null。
不要同時指定長度又賦值初始化。
數組有length屬性,獲取數組長度。int[] prices=new int[5]; prices.length
Foreach循環語句
book相當於一個臨時變量,循環會把books中的元素依次賦值給book變量,所以不能通過修改book的值來修改books數組中的元素。
public class helloworld
{
public static void main(String[] args)
{
String[] books={"qqqqq","sssss","aaaaaa"};
for(String book:books)
{
System.out.println(book);
book="wwwwwwww";
}
System.out.println('\n');
for(String book:books)
{
System.out.println(book);
}
}
}

3.深入數組
當一個方法執行時,會建立自己的內存棧,方法內定義的局部變量保存在內存棧中,數組的引用保存在棧內存中,數組的值保存在堆內存中。方法執行完后,棧中局部變量會銷毀,但是堆中的變量只有當它不被任何引用變量引用時才會被銷毀。
二維數組
Type[][] arrname;arrname=new type[10][]; type[0]=new type[4];將二維數組看成一維數組的定義,數組元素類型是type[]。
Type[][] arrayname=type[3[4];
Strign[][] str=new stirng[][]{new string[3],new string[] {“hello”,”world”}};
4.Arrays類操作函數
int binarySearh(type[] a,type key);二分法查找key值的元素位置
int binarySearh(type[] a,int fromindex,int toindex,type key);二分法查找key值的元素位置
type[] copyOf(type[] orginal,int length);復制original數組中的元素為到新數組
type[] copyOfRanger(type[] orginal,int from ,int to);復制original數組中的元素為到新數組
Boolean equals(type[] a , type[] b);判斷數組a,b長度和值是否相等。
Void fill(type[] a,type val );賦值給數組val。
Void fill(type[] a,int from, int to );賦值給數組val。
Void sort(type[] a);對數組進行排序。
Void sort(type[] a,int from, int to );賦值給數組val。
String toString(type[] a);
第五章面向對象
1.java的靜態方法
Static修飾的方法屬於類,用類直接來調用該方法,不能調用類中的其它非靜態函數,因為無法確定調用的是哪個對象的方法。不同的對象去調用靜態方法,得到相同的結果,因為底層依然是用所屬的類去調用。
This默認代表對象本身,當方法中有與成員變量同名的局部變量時,需要在成員變量前加this以區分。同一個類中,一個方法調用另一個方法,被調用者是普通方法,默認使用this作為調用者,如果方法是靜態方法,默認使用類作為調用者。
Java中方法不能獨立定義,獨立執行,要么屬於類,要么屬於對象。
2.java的參數傳遞
方法的基本類型的參數傳遞是值傳遞,方法中對參數的操作不影響實參的值。引用類型的參數傳遞也是值傳遞,實參將引用值賦值給形參變量,但是引用指向同一塊堆內存,並沒有賦值堆內存中的值,修改形參變量引用指向的變量值,會同時修改實參引用指向的值。
Func(int df,String… arraystring)Sting后面的三個點表示可以傳入多個String類型的實參,arraystring作為一個數組接收多個參數值。調用是Func(2,“sfsa”,“dsff”);只能是最后一個參數才能這樣。也可以用數組實參去賦值給這個可變形參,例如:FunC(2,new String[] {“sfsa”,“dsff“})
方法重載遇到可變形參時,test(String str); test(String… str);只有參數個數為1個時才會調用test(String str);當參數個數為0或2個以上時會調用test(String… str);用數組形式實參test(new String[] {“aa”});一個參數也會調用test(String… str);
第八章集合
| HashSet |
無序,不重復,hashcode()和equals()相等,線程不安全 |
| LinkedHashSet |
插入順序排序,不重復,以鏈表,線程不安全 |
| TreeSet |
有序,不重復,排序通過CompareTo和equals()相等,線程不安全 |
| EnumSet |
有序,以枚舉值在枚舉類中的定義順序為順序。線程不安全 |
| Arraylist |
插入順序,可重復,按照索引存儲值,線程不安全 |
| Vector |
線程安全 |
| Stack(棧), |
后進先出,線程安全 |
| arraydeque |
Deque是一個雙端隊列,兩頭操作。 |
|
|
|
8.3.Set集合
8.3.1HashSet
無序,不重復,存取查找性能好,非線程同步,集合元素可以是null,判斷相同元素的標准是hashcode()方法返回值相等且equals()返回值也相等。Hashcode不同,equals相同,會存在不同位置。hashcode()方法計算存儲位置,快速存取;比數組,長度可變,內存可不連續。改變元素的值容易引起混亂。Add,remove;相同元素多次插入HashSet時,會以鏈表的形式存儲在相同位置,稱為hash桶,會影響性能。
8.3.2LinkedHashSet
根據插入順序排序,不重復,以鏈表維護元素的次序,先插入在前。性能低於hashset。
8.3.3TreeSet
有序,不重復,排序通過CompareTo(Object obj)方法,CompareTo相同的無法添加。定義類需要實現Comparable接口。保存相同類型的對象。存儲規則:equals和CompareTo返回結果同步。修改元素會引起混亂。last(),first(),lower()等。自然排序按升序排列,定制排序在構造函數中傳入Comaprator接口lambda表達式。
TreeSet是有序,通過插入對象的CompareTo方法比較,返回為0表示相同,則無法在添加,自定義類需要實現該方法。TreeSet中應該添加同一個類的對象。
Equals和CompareTo返回的結果要一致,否則會出錯。
修改TreeSet里的實例變量會導致不在有序,且可能出現重復值,刪除重復的對象會失敗,可以刪除沒有沒修改過或不與修改過的對象相同的對象。所以盡量不要修改TreeSet和hassSet的對象。
自然排序:TreeSet自動調用集合元素的CompareTo方法來比較元素之間的大小關系,進行升序排列。
定制排序,創建TreeSet對象時,以lambda表達式傳入函數式接口Comparator,實現compare函數,用於比較。還是根據返回值判斷大小。對象自身的CompareTo接口就不用了。
專為枚舉類設計的集合類,有序,按枚舉類中定義的順序排序,存儲緊湊高效。
8.3.4EnumSet類
有序,以枚舉值在枚舉類中的定義順序為順序,不可插入null;
Set都是線程不安全的,hashset性能高於treeset,要求有序時才使用treeset。迭代訪問時linkedhashset性能高於hashset;
8.4List集合
8.4.1List接口和ListIterator接口
List是按索引插入值,0開始,可重復,通過對象equals函數判斷是否相等。
indexOf(Objrct o);查找object對象第一次出現的索引
sort(Comparator c)根據參數對list排序。
Set只提供iterator()方法,List還有額外的listIterator()方法,返回listIterator對象,有hasPrevious() previous(),add()三個方法。
ListIterator可以通過hasNext正向遍歷list,可以通過hasPrevious反向遍歷list。
8.4.2ArrayList和Vector實現類
Arraylist和Vector默認大小為10 ,可以用initialCapacity(int)或ensureCapacity(int)方法來設置初始大小,通過trimToSize()將大小設置為容量大小,減少空間占用。
Vector的子類Stack(棧),后進先出,性能差。
ArrayList是線程不安全的,而Vector是線程安全的。
Arrays中有一個aslist(object… a)將一個數組或者指定個數的對象轉換成list集合,格式固定,不可增加或刪除。
List實例
import java.util.*;
public class helloworld
{
public static void main(String[] args)
{
List booklist=new ArrayList();
booklist.add(new String("瘋狂java講義1"));
booklist.add(new String("瘋狂java講義2"));
booklist.add(new String("瘋狂java講義3"));
ListIterator lit=booklist.listIterator();
while(lit.hasNext())
{
System.out.println(lit.next());
lit.add(new String("-----------分隔符----------"));
}
System.out.println("開始反向");
while(lit.hasPrevious())
{
System.out.println(lit.previous());
}
}
}
8.5Queue集合
Queue隊列,先進先出,插入隊尾,對頭取出。
8.5.1PriorityQueue實現類
PriorityQueue實現類,並不是先進先出,而是進行排序,小的在頭,大的在尾,不能是null,需要相同對象。排序分自然排序很定制排序,定制排序需在構造器中傳入實現Comparable接口。
8.5.2deque接口和arraydeque實現類
Deque是一個雙端隊列,兩頭操作。XXXFirst() XXXLast()操作函數。
ArrayDeque是接口Deque的實現類,
8.5.3 Linkedlist實現類
可以當做list、stack和deque來使用,內部采用鏈表實現,隨機訪問性能較差,插入刪除性能較好。
遍歷集合元素,ArrayList和Vector采用get方法,linkedlist采用itertor。
8.6 Map集合
Hashmap
線程不安全能使用null作為key或者value;hashtable線程安全,不能使用null作為key或者value,equals判斷鍵值是否相等。 如果采用可變對象作為hashmap的鍵值,程序修改了對象,導致map無法正常訪問修改的鍵值。
Linkedhashmap
按插入順序保存鍵值對。
TreeMap
有序,是紅黑樹結構,每個節點是一個key-value對,根據key值進行排序,有自然排序和定制排序。
Properties
方便的操作屬性文件,,文件內容格式屬性名=屬性值,load加載,store保存,setProperty()設置,getProperty()獲取值。
WeakHashMap
保留對對象的弱引用,一旦系統垃圾回收后,則map里的對象會被刪除,wmap.Put(“java”,“new String(中等));java是直接量是強引用,不會刪除。wmap.Put(new Stirng(“C++”),“new String(中等));C++為弱引用,回收會被刪除。
IdentyHashMap
與hashmap類似,只是采用==來判斷key值是否相等。而不是equels和CompareTo對比。允許使用null作為key和value。
EnumMap
創建時必須指定枚舉類,將枚舉值與對應的關聯值對應起來,以枚舉值作為key值,根據枚舉值的順序排列,不允許null作為key值,可以作為value值。
8.8操作結合的工具類Collection
8.8.1集合的操作
void reverse(List list),反序
void shuffle(List list),隨機排序,打亂排序
void sort(List list)自然順序排序
void swap(List list,int i,int j)調換list中的兩個惡元素
void rotate(List list,int distence)根據distence的值將list中的元素循環移位。
Int binarySearch(List list , Object key)list必須有序,快速查找鍵值的索引。
Int frequency(collection c,Object o)查找集合中出現的次數。
Boolean replaceAll(List list, Object oldVal,Object newVal)新值代替所有舊值。
8.8.2集合同步封裝Collection.synchronizedXxx
List list=Collection.synchronizedList(new ArrayList());
8.8.3集合的只讀設置
通過Collection的emptyXxx()方法創建空的只讀集合,使用singletonXxx()創建只含有一個對象的只讀集合,通過unmodifiableXxx()創建只讀集合。
第九章泛型
使集合能夠識別保存的類型 List<String> strlist=new ArrayList<String>();java7后紅色String可省略。泛型的實質是允許在定義接口、類時聲明類型形參,創建對象時傳入類型實參,類似C++的模板。Public class Appple<T>, 泛型解決集合不確定保存什么類型的對象問題,解決了雷和接口不確定采用什么類型的參數問題。
9.2泛型類、接口定義和繼承
從泛型類派生子類或泛型接口實現類,需要泛型的實參。Public calss A extends Apple<String>。不傳入實參,則泛型當做Object處理。泛型形參不同,但是不是不同的類,靜態中不允許使用泛型。List<String>不是List<Object>的子類,不能進行傳遞。
9.3類型通配符
List<String>不能當做實參傳遞給List<Object>,需要定義List<?>類型通配符。test(List<?> c), List<?>表示各種泛型List的父類,但是只能作為泛型形參,不能創建對象保存數據。Test(List<? extends fruit>); extends fruit表示只有fruit的子類才可以單做形參傳入,因為無法確定List保存的到底是哪個子類對象,所以不能執行add操作。定義泛型類時,也可以限制,例如public class Apple<T extends Number>表示只有number的子類才可以傳入。多個限制用&號連接public class Apple<T extends Number & String>。類限必須在前,接口限制在后。
9.4泛型方法
為了解決使用通配符時,不能進行寫操作,只能進行讀操作,java提供泛型方法。
Static <T> void addArrayToCollection(T[] a, Collection<T> c)
{
For(T o:a){c.add(o);}
}
static <T> void test(Collection<? externs T> from, Collection< T> to)
自己開發了一個股票智能分析軟件,功能很強大,需要的點擊下面的鏈接獲取:
