天天看點

javaSe個人難點總結

1.java關鍵字transient:

transient使用總結

(1)一旦變量被transient修飾,變量将不再是對象持久化的一部分,該變量内容在序列化後無法被通路。

(2) transient關鍵字隻能修飾變量,而不能修飾方法和類。注意,本地變量是不能被transient關鍵字修飾的。變量如果是使用者自定義類變量,則該類需要實作Serializable接口。

(3)一個靜态變量不管是否被transient修飾,均不能被序列化(如果反序列化後類中static變量還有值,則值為目前JVM中對應static變量的值)。序列化儲存的是對象狀态,靜态變量儲存的是類狀态,是以序列化并不儲存靜态變量。

使用場景

(1)類中的字段值可以根據其它字段推導出來,如一個長方形類有三個屬性長度、寬度、面積,面積不需要序列化。

(2)一些安全性的資訊,一般情況下是不能離開JVM的。

(3)如果類中使用了Logger執行個體,那麼Logger執行個體也是不需要序列化的

2.java關鍵字native:

native關鍵字用法

native是與C++聯合開發的時候用的!java自己開發不用的

使用native關鍵字說明這個方法是原生函數,也就是這個方法是用C/C++語言實作的,并且被編譯成了DLL,由java去調用。 這些函數的實作體在DLL中,JDK的源代碼中并不包含,你應該是看不到的。對于不同的平台它們也是不同的。這也是java的底層機制,實際上java就是在不同的平台上調用不同的native方法實作對作業系統的通路的。

1。native 是用做java 和其他語言(如c++)進行協作時用的 也就是native 後的函數的實作不是用java寫的 2。既然都不是java,那就别管它的源代碼了,呵呵

native的意思就是通知作業系統, 這個函數你必須給我實作,因為我要使用。 是以native關鍵字的函數都是作業系統實作的, java隻能調用。

java是跨平台的語言,既然是跨了平台,所付出的代價就是犧牲一些對底層的控制,而java要實作對底層的控制,就需要一些其他語言的幫助,這個就是native的作用了

3.java關鍵字assert:

Java2在1.4中新增了一個關鍵字:assert。在程式開發過程中使用它建立一個斷言(assertion)。,它的文法形式有如下所示的兩種形式:

1、assert condition;

這裡condition是一個必須為真(true)的表達式。如果表達式的結果為true,那麼斷言為真,并且無任何行動

如果表達式為false,則斷言失敗,則會抛出一個AssertionError對象。這個AssertionError繼承于Error對象,

而Error繼承于Throwable,Error是和Exception并列的一個錯誤對象,通常用于表達系統級運作錯誤。

2、asser condition:expr;

這裡condition是和上面一樣的,這個冒号後跟的是一個表達式,通常用于斷言失敗後的提示資訊,說白了,它是一個傳到AssertionError構造函數的值,如果斷言失敗,該值被轉化為它對應的字元串,并顯示出來。

用一個例子說明一下:

java public class Test { public static void main(String[] args) { System.out.println("start"); assert true; System.out.println("go on"); assert false:"stop"; System.out.println("end"); } }

這裡有一個測試類,通過之前簡單的文法介紹後,可以這樣簡單的了解這個例子:

當程式運作到assert true這一句時,condition為true,系統會繼續執行下去。而後執行到 assert false:"stop"的時候,由于condition=false,系統會抛出AssertionError。

但是試試上是不是這樣的呢?

看看運作結果就知道了

> start go on end

這個運作結果和我們一開始的預期不一緻,問題出在哪裡了?

原來java的斷言與C語言中的斷言還有有些不同的地方。

Java的assertion的開啟也和C語言不太一樣,在C語言中,assertion的開啟是在編譯時候決定的。當我們使用debug方式編譯程式時候,assertion被開啟,而使用release方式編譯時候,assertion自動被關閉。 而Java的assertion卻是在運作的時候進行決定的。其實,這兩種方式是各有優缺點。如果采用編譯時決定方式,開發人員将處理兩種類型的目标碼,debug版本和release版本,這加大了文檔管理的難度,但是提高了代碼的運作效率。 Java采用運作時決定的方式,這樣所有的assertion資訊将置于目标代碼 中,同一目标代碼可以選擇不同方式運作,增強目标代碼的靈活性,但是它将犧牲因為assertion而引起一部分性能損失。

說直白一點就是:assert關鍵字需要在運作時候顯式開啟才能生效,否則你的斷言就沒有任何意義。

4.Java關鍵字volatile的兩層語義

  一旦一個共享變量(類的成員變量、類的靜态成員變量)被volatile修飾之後,那麼就具備了兩層語義:

  1)保證了不同線程對這個變量進行操作時的可見性,即一個線程修改了某個變量的值,這新值對其他線程來說是立即可見的。

  2)禁止進行指令重排序。

  

5.Java關鍵字instanceof:

嚴格來說是Java中的一個雙目運算符,用來測試一個對象是否為一個類的執行個體,用法為:

boolean result = obj instanceof Class

  其中 obj 為一個對象,Class 表示一個類或者一個接口,當 obj 為 Class 的對象,或者是其直接或間接子類,或者是其接口的實作類,結果result 都傳回 true,否則傳回false。

 注意:編譯器會檢查 obj 是否能轉換成右邊的class類型,如果不能轉換則直接報錯,如果不能确定類型,則通過編譯,具體看運作定。

  

6.Java關鍵字const:

const是java中的預留關鍵字(java中預留關鍵字還有goto),現在沒有作為關鍵字,以後的版本中可能擴充用,但現在常用于C,C++中。C中的const類似于final。

7.Java枚舉enum關鍵字

枚舉的了解

枚舉其實就是一個類,枚舉類的執行個體是一組限定的對象

傳統的方式建立枚舉 【了解】

對比:單例類
1、構造器私有化
2、本類内部建立對象
3、通過public static方法,對外暴露該對象

枚舉類
1、構造器私有化
2、本類内部建立一組對象,添加public static修飾符,直接暴露對象
           

八大排序算法

1、直接插入排序

2、希爾排序

3、簡單選擇排序

4、推排序

5、冒泡排序

6、快速排序

7、歸并排序

8、桶排序

面向過程

優點:性能比面向對象高,因為類調用時需要執行個體化,開銷比較大,比較消耗資源;比如單片機、嵌入式開發、 Linux/Unix等一般采用面向過程開發,性能是最重要的因素。

缺點:沒有面向對象易維護、易複用、易擴充

面向對象

優點:易維護、易複用、易擴充,由于面向對象有封裝、繼承、多态性的特性,可以設計出低耦合的系統,使系統 更加靈活、更加易于維護

缺點:性能比面向過程低

Collection ——> List ——> ArrayList類

Collection ——> List ——> LinkedList類

Collection ——> Set ——> HashSet類

Collection ——> Set ——> SortedSet接口 ——> TreeSet類

Map ——> HashMap類

Map ——> SortedMap ——> TreeMap類

1、

List是一個有序集合,既存入集合的順序和取出的順序一緻 List集合允許添加的元素重複

2、

  1. ArrayList和Vector都是基于數組實作的,兩者用法差不多
  2. ArrayList随機查詢效率高,随機增删元素效率較低
  3. Vector提供了一個Stack子類,模拟“棧”資料結構——”先進後出”
  4. ArrayList是線程不安全的,Vector是線程安全的

3、

LinkedList是雙向連結清單實作的 随機查詢效率低,随機增删效率高

4、

List主要有兩個實作ArrayList和LinkedList,他們都是有順序的,也就是放進去是什麼順序,取出來還是什麼順序

ArrayList——周遊、查詢資料比較快,添加和删除資料比較慢(基于可變數組)

LinkedList——查詢資料比較慢,添加和删除資料比較快(基于連結清單資料結構)

Vector——Vector已經不建議使用,Vector中的方法都是同步的,效率慢,已經被ArrayList取代

Stack——繼承Vector實作的棧,棧結構是先進後出,但已被LinkedList取代

5、

  1. Set是一個無序集合,既存入集合的順序和取出的順序不一緻
  1. Set集合中元素不重複

    3.TreeSet底層由TreeMap實作。可排序,預設自然升序。

6、Map集合

Map用于儲存具有映射關系的資料,是以Map集合裡儲存兩組值。

一組值用于儲存key,一組值用于儲存value key~value之間存在單向一對一關系,通過指定key可以找到唯一的value值

key和value都可以是任何引用類型對象 允許存在value為null,但是隻允許存在一個key為null

  1. HashMap類

【特點】

key無序不可重複
底層是哈希表
           

1

2

【哈希表實作原理】

HashMap實際上是一個"連結清單的數組"的資料結構,每個元素存放連結清單頭結點的數組,即數組和連結清單的結合體。

當我們往HashMap中put元素的時候,先根據key的hashCode重新計算hash值,根據hash值得到這個元素在數組中的位置(即下标),如果數組該位置上已經存放有其他元素了,那麼在這個位置上的元素将以連結清單的形式存放,新加入的放在鍊頭,最先加入的放在鍊尾。如果數組該位置上沒有元素,就直接将該元素放到此數組中的該位置上。

隻有相同的hash值的兩個值才會被放到數組中的同一個位置上形成連結清單。

如果這兩個Entry的key通過equals比較傳回true,新添加Entry的value将覆寫集合中原有Entry的value,但key不會覆寫

HashMap實際上是一個"連結清單的數組"的資料結構,每個元素存放連結清單頭結點的數組,即數組和連結清單的結合體。

當我們往HashMap中put元素的時候,先根據key的hashCode重新計算hash值,根據hash值得到這個元素在數組中的位置(即下标),如果數組該位置上已經存放有其他元素了,那麼在這個位置上的元素将以連結清單的形式存放,新加入的放在鍊頭,最先加入的放在鍊尾。如果數組該位置上沒有元素,就直接将該元素放到此數組中的該位置上。

隻有相同的hash值的兩個值才會被放到數組中的同一個位置上形成連結清單。

如果這兩個Entry的key通過equals比較傳回true,新添加Entry的value将覆寫集合中原有Entry的value,但key不會覆寫。

【總結】

HashMap中key的hashCode值決定了<k,v>鍵值對組成的entry在哈希表中的存放位置。

HashMap中key通過equals()比較,确定是覆寫key對應的value值還是在連結清單中添加新的entry。

綜合前兩條,需要重寫hashCode()和equals()方法。

  1. HashSet底層由HashMap實作
  2. 無序不可重複

java.util.LinkedList集合 implements List接口 * 特點: *

1.底層是一個連結清單結構,查詢慢;增删快 * 2.裡面包含了大量操作首尾元素的方法 * 注意:使用LinkedList集合特有的方法,不能使用多态

  • java.util.Set接口 extends Collection接口 * 特點: * 1.不允許存儲重複的元素 *

    2.沒有索引,也沒有帶索引的方法 * java.util.HashSet類 implements Set接口 * 特點: * 1.是一個無序集合 * 2.底層是一個哈希表結構(查詢速度非常快)

  • java.util.LinkedHashSet集合 extends HashSet集合 * 特點: *

    底層是一個哈希表(數組+連結清單/紅黑樹)+連結清單:多了一條連結清單(記錄元素的存儲順序),保證元素有序 * *

    java.util.LinkedHashMap<K,V> extends HashMap<K,V> * 底層原理: *

    哈希表+連結清單(有序

  • java.util.Hashtable<K,V>集合 implements Map<K,V>接口 * *

    Hashtable:底層是一個哈希表,是一個線程安全的集合,單線程集合,速度慢 *

    HashMap:底層是一個哈希表,是一個線程不安全的集合,多線程集合,速度快 * *

    HashMap集合(之前學過的所有集合):可以存儲null值、null鍵 * Hashtable集合:不可以存儲null值、null鍵