java里的集合(Collection)是java里面非常重要的一個概念货矮。剛開始看java數(shù)組的時候出于先入為主的影響责蝠,總是難免會以為是JS里面的Array,區(qū)別也就在于java里面的數(shù)組里的每一項都是單一類型的(畢竟是強類型語言)躲因。然而java里面的數(shù)組長度是不可變的棘伴,也就不可能出現(xiàn)JS里面類似push,shift等直接改變數(shù)組長度的操作了摩骨,可是前后端交互時我們通過ajax拿到的數(shù)據(jù)分明就是一個數(shù)組通贞,長度也不是固定的。沒錯恼五,實際上JS里面的數(shù)組在java里面更像是ArrayList
昌罩,它繼承List
,而List
又繼承了本文的主角Collection
灾馒。
什么是集合茎用,下面是java文檔的原文
A collections framework is a unified architecture for representing and > manipulating collections. All collections frameworks contain the following:
- Interfaces: These are abstract data types that represent collections. Interfaces allow collections to be manipulated independently of the details of their representation. In object-oriented languages, interfaces generally form a hierarchy.
- Implementations: These are the concrete implementations of the collection interfaces. In essence, they are reusable data structures.
- Algorithms: These are the methods that perform useful computations, such as searching and sorting, on objects that implement collection interfaces. The algorithms are said to be polymorphic: that is, the same method can be used on many different implementations of the appropriate collection interface. In essence, algorithms are reusable functionality.
最核心的集合如下圖所示
List
數(shù)組(Array)
在集合類中,List
是最基礎(chǔ)的一種集合:它是一種有序列表睬罗。在數(shù)據(jù)結(jié)構(gòu)里面轨功,我們有兩種表示有序集合的結(jié)構(gòu)。
數(shù)組(Array)
數(shù)組是一種聚合數(shù)據(jù)類型容达,它是將具有相同類型的若干變量有序地組織在一起的集合古涧。數(shù)組可以說是最基本的數(shù)據(jù)結(jié)構(gòu),在各種編程語言中都有對應(yīng)花盐。一個數(shù)組可以分解為多個數(shù)組元素羡滑,按照數(shù)據(jù)元素的類型,數(shù)組可以分為整型數(shù)組算芯、字符型數(shù)組柒昏、浮點型數(shù)組、指針數(shù)組和結(jié)構(gòu)數(shù)組等也祠。數(shù)組還可以有一維昙楚、二維以及多維等表現(xiàn)形式。
鏈表( Linked List)
鏈表是一種數(shù)據(jù)元素按照鏈?zhǔn)酱鎯Y(jié)構(gòu)進行存儲的數(shù)據(jù)結(jié)構(gòu)诈嘿,這種存儲結(jié)構(gòu)具有在物理上存在非連續(xù)的特點堪旧。鏈表由一系列數(shù)據(jù)結(jié)點構(gòu)成削葱,每個數(shù)據(jù)結(jié)點包括數(shù)據(jù)域和指針域兩部分。其中淳梦,指針域保存了數(shù)據(jù)結(jié)構(gòu)中下一個元素存放的地址析砸。鏈表結(jié)構(gòu)中數(shù)據(jù)元素的邏輯順序是通過鏈表中的指針鏈接次序來實現(xiàn)的。
java針對這兩種結(jié)構(gòu)實現(xiàn)了ArrayList
和LinkedList
爆袍,通過名字我們也很容易知道對應(yīng)的種類首繁,下面是主要的區(qū)別。
ArrayList | LinkedList | |
---|---|---|
獲取指定元素 | 速度很快 | 需要從頭開始查找元素 |
添加元素到末尾 | 速度很快 | 速度很快 |
在指定位置添加/刪除 | 需要移動元素 | 不需要移動元素 |
內(nèi)存占用 | 少 | 較大 |
在需要索引值來定位的地方使用ArrayList
要更合理陨囊,所以實際開發(fā)中ArrayList
使用的場合要比LinkedList
多一些弦疮。
另外,要使用foreach的方式去遍歷
for (String s : list) {
System.out.println(s);
}
如果采用下面的方法蜘醋,在遍歷非ArrayList的時候胁塞,索引越大,遍歷越慢压语。
for (int i=0; i<list.size(); i++) {
String s = list.get(i);
System.out.println(s);
}
Map
上面我們說了前后端交互的時候java一般會以ArrayList的結(jié)構(gòu)去返回值啸罢,那形如
{
a:1,
b:2
}
的結(jié)構(gòu)也就是Map
了,Map
主要有三種實現(xiàn) HashMap
, TreeMap
, 和 LinkedHashMap
胎食。
HashMap
性能最高的map扰才,由于采用的是散列(Hash)的數(shù)據(jù)結(jié)構(gòu),是用空間換時間的方式厕怜,效率高衩匣,但是不能保證順序。
我們可以看到遍歷的順序不能保證酣倾。
TreeMap
使用紅黑樹(red-black tree)的數(shù)據(jù)結(jié)構(gòu)儲存key舵揭,比hashmap要慢,在不自定義實現(xiàn)Comparable
的情況下會以自然順序排序(類似1->2->3 a->b->c
)
LinkedMap
內(nèi)部使用鏈表(linked list)的數(shù)據(jù)結(jié)構(gòu)儲存key躁锡,在不自定義實現(xiàn)Comparable
的情況下會以元素添加的順序排序午绳。上面那個例子會以“apple”,“pear”映之,“banana”的順序返回拦焚。
Set
Map
用于存儲key-value的映射,對于充當(dāng)key的對象杠输,是不能重復(fù)的赎败,并且,不但需要正確覆寫equals()
方法蠢甲,還要正確覆寫hashCode()
方法僵刮。
如果我們只需要存儲不重復(fù)的key,并不需要存儲映射的value,那么就可以使用Set
搞糕。
與Map
類似勇吊,Set
實現(xiàn)了HashSet
, TreeSet
, 和 LinkedHashSet
,基本都是在對應(yīng)map類上的一些封裝窍仰,這里就不再贅述了汉规。
另外,js現(xiàn)在也有了Map和Set驹吮,mdn上的描述如下
Map
對象保存鍵值對针史,并且能夠記住鍵的原始插入順序。任何值(對象或者原始值) 都可以作為一個鍵或一個值碟狞。
Set
對象是值的集合啄枕,你可以按照插入的順序迭代它的元素。 Set中的元素只會出現(xiàn)一次族沃,即 Set 中的元素是唯一的射亏。
相信看了上面的知識,會很容易就知道js Map和Set的數(shù)據(jù)結(jié)構(gòu)是哪一種了竭业。