棧結構和隊列結構
棧:
先進後出。數組
隊列:
先進先出。數據結構
6.數組和鏈表
數組:
在內存中是一片連續的空間。
查詢快,增刪慢。ide
查詢快:由於能夠經過數組的地址值和索引直接定位到某個元素。
增刪慢:由於數組不可變,每次要添加或者刪除都要建立一個新的數組。
把老數組中的元素賦值給新數組。源碼分析
鏈表:
是多個節點組成的。
每個節點都是單獨new出來的對象,在內存中鏈表不是一個連續的空間。
是經過互相記錄地址值實現的。學習
單向鏈表:
前一個記錄後一個地址值。
可是後一個不會記錄前一個地址值。this
雙向鏈表
也是由節點組成的。
前一個記錄後一個地址值。
後一個也會記錄前一個。
對象
7.ArrayList 和 LinkedList
ArrayList : 底層是一個數組。
特色:查詢快,增刪慢排序
LinkedList : 底層是一個雙向鏈表。
特色:查詢慢,增刪快索引
總結:
ArrayList 和 LinkedList 基本使用是如出一轍的。
增 刪 改 查,所寫代碼幾乎同樣。
可是在底層數據結構是不同的。接口
8.LinkedList
void addFirst(E e) 向集合中第一個位置添加元素
void addLast(E e) 向集合中最後一個位置添加元素
E getFirst() 獲取集合中第一個元素
E getLast() 獲取集合中最後一個元素
E removeFirst() 刪除集合中第一個元素
E removeLast() 刪除集合中最後一個元素
目前爲止:
List集合已經所有學習完畢了
ArrayList :此時查詢較多
LinkedList :此時增刪較多
Vector 是List中最爲古老的一個集合在JDK1.0的時候就出現了。
在JDK1.2的時候Java提出了集合理論。
把ArrayList全面替代了Vector
疑問:
我也不知道增刪多仍是查詢多怎麼辦?
當你不知道用什麼的時候,請使用: ArrayList
9.單列集合的第二分支 Set
List: 有序 有索引 能夠重複
Set : 無序 無索引 不能夠重複
注意點:
當你使用到Set的時候,就不要想着他存取有序了。
10.哈希值
問:
1.什麼是哈希值?
其實就是根據"地址值"或者內部"元素的屬性值"計算出來的一個數值。
2.何時根據地址值計算?
Object 中的hashCode 返回的就是根據地址值計算出來的哈希值。
3.何時根據元素的屬性值計算?
在任意一個已經將hashCode進行重寫以後。
只要重寫了,就按照元素的屬性值進行計算,此時跟地址值就沒有任何關係了。好比: String Integer Character...
4.若是屬性值不一樣,那麼哈希值有可能相同嗎?
有可能,概率比較低。
哈希值是一個int類型 -21億 ~ 21億 一共有42億多的值。
那麼如今我建立了50億個對象分別調用他的hashCode方法。
其中至少8億左右的對象哈希值是重複的。
做用:
通常不單獨使用。
跟 HashSet , LinkedHashSet , HashMap 這三個集合有關。
11.HashSet集合保證元素惟一性源碼分析
得出一個結論:
HashSet集合保證惟一性是依賴兩個方法:
hashCode和equlas
12.HashSet的底層分析:
a.HashSet底層其實依賴的是HashMap集合的鍵位置。
每次在存儲的時候,元素放到鍵位置,值就是一個 new Object();
b.哈希表
其實HashSet LinkedHashSet HashMap 這三個集合中底層一個數據結構。
哈希表其實就是一個數組跟鏈表的結合體
到了JDK1.8 哈希表 = 數組 + 鏈表 + 二叉樹
總結:
HashSet LinkedHashSet HashMap的鍵
在存儲元素的時候,這個類裏面必定要重寫hashCode和equals方法。
String Integer ...Java中已經提供的這些類已經幫咱們重寫好了這兩個方法。
"當咱們要在這些集合中存儲自定義對象時,要重寫hashCode和equals方法。"
13.LinkedHashSet
特色:
有序 + 不能夠重複
ArrayList
//當實在不知道用什麼的時候。
//查詢多,增刪少。
LinkedList
//查詢少,增刪多。
Vector//確定不用
HashSet
//數據須要去重時
LinkedHashSet
//數據需求去重且存取有序。
練習1:
鍵盤錄入3個不重複的字符串?
HashSet<String> hs = new HashSet();
Scanner sc = new Scanner(System.in);
while(true){
if(hs.size == 3){
break;
}else{
String line = sc.nextLine();
hs.add(line);//若是已經有了,此時就存儲失敗
//若是沒有,才能存到集合中。
}
}
練習2:
讓多個數據進行總體去重
ArrayList<String> list = new ArrayList<>();
list.add("a");
list.add("a");
list.add("a");
list.add("a");
list.add("a");
list.add("a");
list.add("a");
list.add("a");
//去重裏面重複的元素
HashSet<String> hs = new HashSet();
hs.addAll(list);//把list集合中全部的元素添加到hs裏面
System.out.println(hs);//此時就已是去重以後的結果了。
14.TreeSet
誤區:
哈希表,哈希值只跟 HashSet LinkedHashSet HashMap的鍵有關
TreeSet 跟哈希值,哈希表,hashCode方法,equals方法都是無關的。
特色:
能夠排序。//咱們得給他指定一個排序的規則,若是沒有這樣的規則,會報錯的。
TreeSet<String> ts = new TreeSet<>(); //採起的是默認方式進行比較。
TreeSet<String> ts = new TreeSet<>(比較的規則);//採起傳遞的規則進行比較。
底層結構:
二叉樹結構
15.TreeSet的默認比較方式。
天然排序。
案例:
TreeSet<Student> ts = new TreeSet<>();
//如今要存誰,this就表示誰。
//如今要跟誰比較,o就表示誰。
ts.add(new Student("zhangsan",23,"男"));
ts.add(new Student("lisi",24,"男"));
ts.add(new Student("wangwu",25,"女"));
System.out.println(ts);
注意點, Student類要實現接口Comparable
@Override
public int compareTo(Student o) {
System.out.println(this);
//按照年齡從大到小,年齡相同就不要。
int result = o.age - this.age;
return result;
}
16.比較器排序Comparator
代碼的書寫方式跟第一種基本是同樣。
注意點:
1.當第一種和第二種同時存在時,聽第二種的。
2.第二種方式何時用?
當咱們不知道用哪種的時候咱們使用第一種方式。
當第一種沒法知足的時候,會使用第二種。
練習1:
我要按照字符串的長度排序?
默認使用天然排序,可是天然排序的規則是:字典順序。
由於String是Java提供的,咱們沒法修改源代碼的。
在這種狀況下:第一種天然排序就沒法知足我如今的要求了。
因此此時用第二種。
總結:
若是Java提供好的類中排序方式不能知足如今的要求,用第二種。
自定義類可使用第一種。
TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
//o1 如今要存入的元素
//o2 已經存在的元素
//o1和o2所表示的含義不重要,最多就是運行完畢後,修改一下先後順序就能夠了
//重點就是比較規則的書寫。
return o2.length() - o1.length();
}
});
ts.add("b");
ts.add("aaa");
ts.add("aa");
ts.add("aaaaa");
ts.add("aaaa");
System.out.println(ts);
練習2:
我要按照字符串的長度排序?若是長度同樣,請按照字典順序排?
TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
int temp = o1.length() - o2.length();
temp = temp == 0 ? o1.compareTo(o2) : temp;
return temp;
}
});
ts.add("b");
ts.add("aaa");
ts.add("aa");
ts.add("aaaaa");
ts.add("aaaa");
ts.add("a");
System.out.println(ts);
}