JAVA小米門,以下是個人學習JAVA整理的隨手筆記,希望能夠幫助到你們。
1. JDK中Integer是一個final類,其值一旦初始化便不可以被改變(不可變的整型包裝類Integer);
2. Java函數傳遞時,基本類型傳遞的是值,對象類型傳遞的是引用,無論是基本類型還是對象類型,在函數體中沒有改變對象的操作的話原來對象就不會改變!
3.String與StringBuffer的區別:
就是一個變量和常量的關係。StringBuffer對象的內容可以修改;而String對象一旦產生後就不可以被修改,重新賦值其實是兩個對象。
String:對象不可改變->優點:編譯器可以把字符串設爲共享的,“+”;
StringBuffer:對一個字符串進行修改,例如插入、刪除等操作,“append”,效率高,線程安全,多線程使用,方法:append方法、deleteCharAt方法(刪除指定位置的字符)、insert方法(對象中插入內容)、reverse方法(內容反轉)、trimToSize方法(將StringBuffer對象的中存儲空間縮小到和字符串長度一樣的長度,減少空間的浪費)、length()、substring、replace、toString()。
4、string操作(字符串):
1)數組相關:length()(長度)、toCharArray(將任意字符串轉換爲一個char數組)
2)字母相關:
charAt(index),得到index位置的字符。
indexOf(char ch),默認取得第一個ch的下標,如果沒有則返回-1.
lastIndexOf(char ch)最後一個出現的位置。
toLowerCase(String str)、toUpperCase(String str)
equalsIgnoreCase(),字符串比較,忽略大小寫。
compareTo(),讓兩個字符串做字典比較,返回首個不同字符ASCII碼之差。如果每一位都相同,返回長度之差。
compareToIgnoreCase()字符串字典比較忽略大小寫。
3)操作技巧有關:
- str.contains(‘XXX’)String對象裏面是否包含XXX。
- str.startWith(“XXX”)String對象是否以XXX開頭
- str.endWith(“XXX”)String對象是否以XXX結尾
- str.replace(‘X’,’Y’);替換字符
- str.replace(“XXX”,”YYY”)替換字符串子串
- str.replaceAll(“XXX”,”YYY”);所有都替換
- replaceFirst(“l”,”fuck”);
- 4)特殊應用:
- trim方法,去掉String對象的前後空格。接收到用戶輸入的操作,因爲用戶可能輸入空格。
- split方法,根據分隔符拆分String對象。網絡數據傳輸時常用到。特殊性:當以分隔符結尾的時候,將不再拆分。
- 5)matches方法,正則表達式校驗:
三個包下都有matches方法:
java.lang包中的String類:boolean b = "abc".matches("[a-z]{3}";
java.util.regex包中的Pattern:
boolean b = Pattern.matches("[a-z]{3}","abc");
java.util.regex包中的Matcher類中:
Pattern p = Pattern.compile("[a-z]{3}");
Matcher m = p.matcher("acc");
boolean b =m.matches()
以上b都爲true。
5、Java中的數據類型:
基本數據類型:在棧(Stack)中直接分配內存的數據類型;
引用數據類型:變量名(引用)存放在棧中,而變量實際的內容存放在堆(heap)中的一類數據類型。
6、使用list時:比較兩個list的大小或者相等時,使用equals,而不是用“=”
7、方法中的變量不存在非線程安全問題,永遠都是線程安全的;
8、線程安全的:Vector、HashTable、StringBuffer,是通過synchronized關鍵字來同步控制(public synchronized void fun(){})
多線程操作同一個對象時,不會出現問題。
9、線程不安全的:ArrayList、HashMap、StringBuilder
多線程操作同一個對象時,可能會出現問題。
10、多線程機制:
-. 目的:更好的利用CPU資源;
-. 並行(Concurrent)和併發(Parrallel):並行是真正的同時,併發則不然;
-. 線程安全:在併發下,多線程調用代碼,線程的調度順序不影響任何結果。
-. 線程狀態:
1)內功心法:每個對象都有點的機制
synchronized, wait, notify關鍵字 是任何對象都具有的同步工具,有一個JAVA monitor,在synchronized (多線程)範圍內,監視器發揮作用。
synchronized單獨使用:(用於方法public synchronized run(){}和用於代碼塊)
synchronized, wait, notify結合:典型場景生產者消費者問題:public synchronized produce(){}和public synchronized resume(){}
volatile關鍵字:每次針對該變量的操作都激發一次load and save,線程會把值從主存load到本地棧,完成操作後再save回去
- 太祖長拳:基本線程類
基本線程類指的是Thread類,Runnable接口,Callable接口:
Thread 類實現了Runnable接口,啓動一個線程的方法:(Thread thread = new Thread(); thread.start();),有start、yield、sleep、join和interrupt方法。
不能用try,catch來獲取線程中的異常
3)九陰真經:高級多線程控制類
1.ThreadLocal類:保存線程的獨立變量,常用於用戶登錄控制,如記錄session信息。(實現:TreadLocalMap類型的變量,是一個輕量級的map)
2.原子類(AtomicInteger、AtomicBoolean……):前者實現樂觀鎖,後者加入版本號。()
3.Lock類:主要目的是和synchronized一樣, 兩者都是爲了解決同步問題,處理資源爭端而產生的技術。但lock更靈活、有多種加鎖機制。(ReentrantLock、ReentrantReadWriteLock.ReadLock、ReentrantReadWriteLock.WriteLock)
4.容器類:阻塞隊列(BlockingQueue)和線程安全哈希map(ConcurrentHashMap)。
5.管理類:用於管理線程,本身不是多線程的。
- java繼承:子類繼承父類的小戶型和方法,extends(提高代碼的重用性和程序的擴展性)---在兩個類存在重用關係時,就用繼承。
方法重寫:
至少兩個存在繼承關係的類、方法的訪問修飾符必須大於或者等於父類中方法的訪問修飾符
繼承一個類:(只允許繼承一個父類)
實現接口:(可以繼承多個父類):關鍵字是implements
super
super主要有兩種用法:
1)super.成員變量/super.成員方法;
2)super(parameter1,parameter2....)
第一種用法主要用來在子類中調用父類的同名成員變量或者方法;第二種主要用在子類的構造器中顯示地調用父類的構造器,要注意的是,如果是用在子類構造器中,則必須是子類構造器的第一個語句。
訪問一個類:(聲明並實例化)class Person(){String name; int age; public Person(){}} Person per = new Person(); (聲明:棧空間;實例化:new關鍵字堆內存)
11、訪問修飾符:同包內 protected 或 default 相當於 public,異包內 protected 恢復原有的特性,而 default 則被提升爲 private。
公開、受保護、默認和私有。
12、java類的加載:按需加載,只加載一次;且先執行對象的成員變量,然後再執行構造器。父類的構造器調用以及初始化過程一定在子類的前面
13、Java中的封裝型的體現:(保護某些屬性和方法不被外部看到)
實現:通過private關鍵字實現;通過get和set方法爲外部所訪問。
14、JDK常用的類和不常用的類:
- 精讀源碼:java.lang:string包:字符串的讀寫,判斷、異常等
15、Get()和set()方法的意義和好處:
- 靈活性:(易修改性)。
- 安全性:(封裝),操作get/use方法,而不直接操作對象。
- Comparable接口的實現:(自然排序,自然比較方法)
- 意義:若是單個數組排序(直接sort方法);若是一個類排序(多個對象,則必須實現comparable接口)
- 只有一個方法:int compareTo(T O) (i = x.compareTo(y))
- 與comparator區別:
- @Override意義:表明重寫了父類的方法(斷言assert作用)。
- Java中instanceof關鍵字總結:(二元操作符(運算符),和==,>,<是同一類東西)
判斷其左邊對象是否爲其右邊類的實例,返回boolean類型的數據。
16、循環總結:
Int demo[] = {1,2,3};
for(int i=0; i < demo.length();i++){}
for(int i: demo)(i是對象,demo是數組名)
迭代器:iterator:輕量級,代價小(用於for循環和while循環)
17、Java中的多態性總結:
18、HashMap深度剖析:
- HashMap數據結構(數組和引用結合:散列表):
默認的:
初始容量(intial_capacity,哈希表在創建時的容量,也即數組的長度):16
最大容量(maximum_capacity)
加載因子(load_factor,哈希表在容量增加之前可以達到多滿的一種尺度):0.75f
表示散列表空間使用程度,越大:空間利用高,時間效率低;
極限容量(threshold):容量*加載因子
(參考網頁)
- 存儲的步驟put(key, value):(put源碼分析)
- 傳入(key, value),判斷key=null?,是:調用(putForNullKey函數),null返回作爲key;
- 計算hash(key)(hash函數),使用得到的hash值搜索在hash表中的位置,對該位置的Entry表進行遍歷,若鏈中存在該key,則覆蓋,舊的返回;
- 調用(addEntry函數),key-value創建一個新的節點,並插入到表頭部。
(頭插法優點:get()方法查找的可能性大)
- 讀取的步驟get(key):
得到hash(key)值,使用indexFor(hash)得到索引位置,遍歷索引位置,得到value。
- HashMap:1. 可以使用鍵作爲NULL返回的原因:
(如果key=null,則調用putForNullKey)
- 不能有兩個相同的key的原因:
(若存在該key,傳入的value將會覆蓋舊value)
- 相關問題:
- HashMap遍歷無序的原因:
HashMap遍歷時,按哈希表的每一個索引的鏈表從上往下遍歷,由於HashMap的存儲規則,最晚添加的節點都有可能在第一個索引的鏈表中
-
- 通過鍵值對(Entry)存儲在一個數組裏;
- Put(k,v);containsKey(k)/containsValue(V);keyset()鍵集合和values值集合。
- 額外擴展:
hashMap的默認初始長度:16(爲了服務hash算法),每次擴展後增加2次冪;
實現hash算法:位運算的方式(既可以實現取模運算效果,又提高了性能);
19、Java中的集合
- 集合均實現了Collection根接口
- list接口(有序,可重複):子類ArrayList(非同步、線程不安全)和Vector(同步、線程安全);
(ArrayList(基於動態數組)與LinkedList(基於鏈表)在使用上相同,刪改用後者)
- set接口(無序,不能重複):子類HashSet(無序)和TreeSet(有序,二叉樹排序)
- Map集合
- HashMap(key只能返回一個Null,隨機,非同步,線程不安全)
- HashTable(同步、線程安全)
- conCurrentHashMap(線程安全、鎖分離):
相對於hashMap:
-
- 線程安全的;
- 在併發下無需家額外的同步;
- 多線程環境下優於hashMap
- 用於緩存;
相對於hashTable:
- hashTable是在所有方法前加sychronized關鍵字來實現線程安全的(效率低下)
- conCurrentHashMap實現了鎖分離,允許16個線程讀和寫,有需要才上鎖哪一段。
- LinkedHashMap(記錄插入的順序)
- TreeMap(根據鍵key排序)
- 遍歷兩種方式:
- keySet() { Iterator it = map.keySet().iterator();
while(it.hasNext()){
Object key = it.next();
System.out.println(map.get(key));}}
- entrySet() (推薦,效率高)
{ Iterator it = map.entrySet().iterator();
while(it.hasNext()){
Entry e =(Entry) it.next();
System.out.println("鍵"+e.getKey () + "的值爲" + e.getValue());}