激情久久久_欧美视频区_成人av免费_不卡视频一二三区_欧美精品在欧美一区二区少妇_欧美一区二区三区的

服務器之家:專注于服務器技術及軟件下載分享
分類導航

PHP教程|ASP.NET教程|JAVA教程|ASP教程|

服務器之家 - 編程語言 - JAVA教程 - Java集合之整體結構

Java集合之整體結構

2020-05-07 12:17liuxiaopeng JAVA教程

Java中集合類是Java編程中使用最頻繁、最方便的類。接下來通過本文給大家介紹Java集合之整體結構,一起看看吧

一、Java集合

  Java中集合類是Java編程中使用最頻繁、最方便的類。集合類作為容器類可以存儲任何類型的數據,當然也可以結合泛型存儲指定的類型(不過泛型僅僅在編譯期有效,運行時是會被擦除的)。集合類中存儲的僅僅是對象的引用,并不存儲對象本身。集合類的容量可以在運行期間進行動態擴展,并且還提供很多很方便的方法,如求集合的并集、交集等。

二、集合類結構

  Java中的集合包含多種數據結構,如鏈表、隊列、哈希表等。從類的繼承結構來說,可以分為兩大類,一類是繼承自Collection接口,這類集合包含List、Set和Queue等集合類。另一類是繼承自Map接口,這主要包含了哈希表相關的集合類。下面我們看一下這兩大類的繼承結構圖:

1、List、Set和Queue

Java集合之整體結構

圖中的綠色的虛線代表實現,綠色實線代表接口之間的繼承,藍色實線代表類之間的繼承。

   (1)List:我們用的比較多List包括ArrayList和LinkedList,這兩者的區別也很明顯,從其名稱上就可以看出。ArrayList的底層的通過數組實現,所以其隨機訪問的速度比較快,但是對于需要頻繁的增刪的情況,效率就比較低了。而對于LinkedList,底層通過鏈表來實現,所以增刪操作比較容易完成,但是對于隨機訪問的效率比較低。

我們先看下兩者的插入效率:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
package com.paddx.test.collection;
import java.util.ArrayList;
import java.util.LinkedList;
public class ListTest {
public static void main(String[] args) {
for(int i=;i<;i++){
}
long start = System.currentTimeMillis();
LinkedList<Integer> linkedList = new LinkedList<Integer>();
for(int i=;i<;i++){
linkedList.add(,i);
}
long end = System.currentTimeMillis();
System.out.println(end - start);
ArrayList<Integer> arrayList = new ArrayList<Integer>();
for(int i=;i<;i++){
arrayList.add(,i);
}
System.out.println(System.currentTimeMillis() - end);
}
}

下面是本地執行的結果:

23

1227

  可以看出,在這種情況下,LinkedList的插入效率遠遠高于ArrayList,當然這是一種比較極端的情況。我們再來比較一下兩者隨機訪問的效率:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
package com.paddx.test.collection;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.Random;
public class ListTest {
public static void main(String[] args) {
Random random = new Random();
for(int i=;i<;i++){
}
LinkedList<Integer> linkedList = new LinkedList<Integer>();
for(int i=;i<;i++){
linkedList.add(i);
}
ArrayList<Integer> arrayList = new ArrayList<Integer>();
for(int i=;i<;i++){
arrayList.add(i);
}
long start = System.currentTimeMillis();
for(int i=;i<;i++){
int j = random.nextInt(i+);
int k = linkedList.get(j);
}
long end = System.currentTimeMillis();
System.out.println(end - start);
for(int i=;i<;i++){
int j = random.nextInt(i+);
int k = arrayList.get(j);
}
System.out.println(System.currentTimeMillis() - end);
}
}

下面是我本機執行的結果:

5277

6

  很明顯可以看出,ArrayList的隨機訪問效率比LinkedList高出好幾個數量級。通過這兩段代碼,我們應該能夠比較清楚的知道LinkedList和ArrayList的區別和適應的場景。至于Vector,它是ArrayList的線程安全版本,而Stack則對應棧數據結構,這兩者用的比較少,這里就不舉例了。

  (2)Queue:一般可以直接使用LinkedList完成,從上述類圖也可以看出,LinkedList繼承自Deque,所以LinkedList具有雙端隊列的功能。PriorityQueue的特點是為每個元素提供一個優先級,優先級高的元素會優先出隊列。

  (3)Set:Set與List的主要區別是Set是不允許元素重復的,而List則可以允許元素重復的。判斷元素的重復需要根據對象的hash方法和equals方法來決定。這也是我們通常要為集合中的元素類重寫hashCode方法和equals方法的原因。我們還是通過一個例子來看一下Set和List的區別,以及hashcode方法和equals方法的作用:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package com.paddx.test.collection;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.Set;
public class SetTest {
public static void main(String[] args) {
Person p1 = new Person("lxp",10);
Person p2 = new Person("lxp",10);
Person p3 = new Person("lxp",20);
ArrayList<Person> list = new ArrayList<Person>();
list.add(p1);
System.out.println("---------");
list.add(p2);
System.out.println("---------");
list.add(p3);
System.out.println("List size=" + list.size());
System.out.println("----分割線-----");
Set<Person> set = new HashSet<Person>();
set.add(p1);
System.out.println("---------");
set.add(p2);
System.out.println("---------");
set.add(p3);
System.out.println("Set size="+set.size());
}
static class Person{
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public boolean equals(Object o) {
System.out.println("Call equals();name="+name);
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Person person = (Person) o;
return name.equals(person.name);
}
@Override
public int hashCode() {
System.out.println("Call hashCode(),age="+age);
return age;
}
}
}

  上述代碼的執行結果如下:

---------
---------
List size=3
----分割線-----
Call hashCode(),age=10
---------
Call hashCode(),age=10
Call equals();name=lxp
---------
Call hashCode(),age=20
Set size=2

  從結果看出,元素加入List的時候,不執行額外的操作,并且可以重復。而加入Set之前需要先執行hashCode方法,如果返回的值在集合中已存在,則要繼續執行equals方法,如果equals方法返回的結果也為真,則證明該元素已經存在,會將新的元素覆蓋老的元素,如果返回hashCode值不同,則直接加入集合。這里記住一點,對于集合中元素,hashCode值不同的元素一定不相等,但是不相等的元素,hashCode值可能相同。

  HashSet和LinkedHashSet的區別在于后者可以保證元素插入集合的元素順序與輸出順序保持一致。而TresSet的區別在于其排序是按照Comparator來進行排序的,默認情況下按照字符的自然順序進行升序排列。

  (4)Iterable:從這個圖里面可以看到Collection類繼承自Iterable,該接口的作用是提供元素遍歷的功能,也就是說所有的集合類(除Map相關的類)都提供元素遍歷的功能。Iterable里面包含了Iterator的迭代器,其源碼如下,大家如果熟悉迭代器模式的話,應該很容易理解。

?
1
2
3
4
5
public interface Iterator<E> {
boolean hasNext();
E next();
void remove();
}

2、Map:

Java集合之整體結構

Map類型的集合最大的優點在于其查找效率比較高,理想情況下可以實現O(1)的時間復雜度。Map中最常用的是HashMap,LinkedHashMap與HashMap的區別在于前者能夠保證插入集合的元素順序與輸出順序一致。這兩者與TreeMap的區別在于TreeMap是根據鍵值進行排序的,當然其底層的實現也有本質的區別,如HashMap底層是一個哈希表,而TreeMap的底層數據結構是一棵樹。我們現在看下TreeMap與LinkedHashMap的區別:

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
package com.paddx.test.collection;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
public class MapTest {
public static void main(String[] args) {
Map<String,String> treeMap = new TreeMap<String,String>();
Map<String,String> linkedMap = new LinkedHashMap<String, String>();
treeMap.put("b",null);
treeMap.put("c",null);
treeMap.put("a",null);
for (Iterator<String> iter = treeMap.keySet().iterator();iter.hasNext();){
System.out.println("TreeMap="+iter.next());
}
System.out.println("----------分割線---------");
linkedMap.put("b",null);
linkedMap.put("c",null);
linkedMap.put("a",null);
for (Iterator<String> iter = linkedMap.keySet().iterator();iter.hasNext();){
System.out.println("LinkedHashMap="+iter.next());
}
}
}

運行上述代碼,執行結果如下:

TreeMap=a
TreeMap=b
TreeMap=c
----------分割線---------
LinkedHashMap=b
LinkedHashMap=c
LinkedHashMap=a

  從運行結果可以很明顯的看出這TreeMap和LinkedHashMap的區別,前者是按字符串排序進行輸出的,而后者是根據插入順序進行輸出的。細心的讀者可以發現,HashMap與TreeMap的區別,與之前提到的HashSet與TreeSet的區別是一致的,在后續進行源碼分析的時候,我們可以看到HashSet和TreeSet本質上分別是通過HashMap和TreeMap來實現的,所以它們的區別自然也是相同的。HashTable現在已經很少使用了,與HashMap的主要區別是HashTable是線程安全的,不過由于其效率比較低,所以通常使用HashMap,在多線程環境下,通常用CurrentHashMap來代替。

三、總結

  本文只是從整體上介紹了Java集合框架及其繼承關系。除了上述類,集合還提供Collections和Arrays兩個工具類,此外,集合中排序跟Comparable和Comparator緊密相關。在之后的文章中將對上述提的類在JDK中實現源碼進行詳細分析。

延伸 · 閱讀

精彩推薦
主站蜘蛛池模板: 国产精选91 | 日韩一级毛毛片 | 国内免费视频成人精品 | 曰韩一二三区 | 1314成人网| 男女一边摸一边做羞羞视频免费 | 最新中文字幕第一页视频 | 在线观看麻豆 | 精品一区二区在线观看视频 | 一级α片| 91看片在线播放 | 免费一级毛片在线播放不收费 | 亚洲精品久久久久久久久久 | 国产精品视频免费看 | 久久久婷婷一区二区三区不卡 | 国产亚洲精品久久777777 | 久久69精品久久久久久国产越南 | 久久亚洲精品久久国产一区二区 | 婷婷久久青草热一区二区 | 国内xxxx乱子另类 | 久久伊人国产精品 | 国产精品啪一品二区三区粉嫩 | 精品亚洲va在线va天堂资源站 | 国产一区二区视频在线播放 | 99亚洲视频 | 国内精品伊人久久久久网站 | 国产人成免费爽爽爽视频 | 午夜天堂在线视频 | 久久亚洲精选 | 激情宗合| www.99热视频| 成人午夜天堂 | 性爱视频免费 | 成人国产精品色哟哟 | 日本视频网 | 色污视频| 色综合久久久久久久久久 | 91九色网址 | 黄色片网站在线免费观看 | 中文字幕亚洲情99在线 | 欧美 国产 亚洲 卡通 综合 |