集合和數(shù)組的區(qū)別
- 區(qū)別1:
- 數(shù)組即可以存儲(chǔ)基本數(shù)據(jù)類型,又可以存儲(chǔ)引用數(shù)據(jù)類型,
基本數(shù)據(jù)類型存儲(chǔ)的是值,引用數(shù)據(jù)存儲(chǔ)的是地址值
- 集合只能存儲(chǔ)引用數(shù)據(jù)類型(也可存儲(chǔ)基本數(shù)據(jù)類型坯钦,但是會(huì)裝箱變成對(duì)象)
- 區(qū)別2:
- 數(shù)組長(zhǎng)度是固定的预皇,不能自動(dòng)增長(zhǎng)
- 集合的長(zhǎng)度是可變的,可以根據(jù)元素的增加而增長(zhǎng)
- 注:數(shù)組轉(zhuǎn)集合Arrays.asList(arr);
集合轉(zhuǎn)數(shù)組:list.toArray(new String[10]);需要制定長(zhǎng)度
單列集合根接口Collection
* 兩個(gè)實(shí)現(xiàn)類:
List(有序):存和取得順序一致,有索引可以存儲(chǔ)重復(fù)
Set(無(wú)序):存和取得順序不一致婉刀,無(wú)索引吟温,不可以存儲(chǔ)重復(fù)
List集合
* ArrayList(常用):
由于底層是數(shù)組實(shí)現(xiàn)的,也具備了數(shù)組的的屬性——元素的查詢快,增刪慢突颊,
線程不安全鲁豪,效率高。
* Vector(不常用):
底層數(shù)據(jù)結(jié)構(gòu)是數(shù)組,查詢快律秃,增刪滿爬橡,線程安全,效率低
* LinkedList:
雙層鏈表,查詢慢,增刪快,線程不安全棒动,效率高
Set集合
* HashSet,LinkedHashSet(子類,有序)去重,TreeSet——排序
HashSet集合
(1)HashSet:底層是哈希表,線程不同步,無(wú)序糙申,高效
保證元素唯一性:在添加元素的時(shí)候用hashCode()和equals()方法進(jìn)行比較來(lái)保證唯一性
先用hashcode比較,提高效率
(2)存儲(chǔ)對(duì)象的時(shí)候,確保對(duì)象重寫equals方法和hashcode()方法,這樣才能比較對(duì)象的
值是否相等船惨。
why:
重寫hashCode()方法就是為了使hash值出現(xiàn)相同的情況下(哈希沖突柜裸,無(wú)法避免),然后讓兩個(gè)元素比較屬性值掷漱,
去除重復(fù)元素粘室。不重寫hashCode()方法,默認(rèn)比較的是地址值卜范,則無(wú)論兩個(gè)元素內(nèi)的
屬性值是否相同衔统,地址值永遠(yuǎn)不會(huì)相同,則集合無(wú)論是否重復(fù)海雪,都會(huì)添加锦爵。】
(3)hashSet的實(shí)現(xiàn)原理
* HashSet實(shí)現(xiàn)Set接口奥裸,由哈希表(實(shí)際上是一個(gè)HashMap實(shí)例)支持险掀。
它不保證set的迭代順序;特別是它不保證該順序恒久不變湾宙。此類允許使用null元素樟氢。HashSet中不允許有重復(fù)元素
冈绊,這是因?yàn)镠ashSet是基于HashMap實(shí)現(xiàn)的,HashSet中的元素都存放在HashMap的key上面埠啃,
而value中的值都是統(tǒng)一的一個(gè)private static final Object PRESENT = new
Object();HashSet跟HashMap一樣死宣,都是一個(gè)存放鏈表的數(shù)組。
* HashSet中add方法調(diào)用的是底層HashMap中的put()方法碴开,而如果是在HashMap中調(diào)用put毅该,首先會(huì)判斷key是否存在,
如果key存在則修改value值潦牛,如果key不存在這插入這個(gè)key-value眶掌。而在set中,因?yàn)関alue值沒有用巴碗,
也就不存在修改value值的說(shuō)法朴爬,因此往HashSet中添加元素,首先判斷元素(也就是key)是否存在良价,
如果不存在這插入寝殴,如果存在著不插入,這樣HashSet中就不存在重復(fù)值明垢。
public class Person {
private String name;
private int age;
public Person(String name, int age) {
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person [name=" + name + ", age=" + age + "]";
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
@Override
public boolean equals(Object obj) {
if(!(obj instanceof Person)){
return false;
}
Person person=(Person)obj;
if(this==obj)
return true;//用戶可能直接添加了同一個(gè)對(duì)象蚣常。
return this.getName().equals(person.getName())&&this.getAge()==person.getAge();
}
@Override
public int hashCode() {//返回唯一的hash值
// TODO Auto-generated method stub
return this.getName().hashCode()+this.getAge();
}
}
(2)LinkedHashSet:HashSet的子類(有序的),根據(jù)元素的放入順序排序
TreeSet集合
TreeSet也是用Map接口的另一個(gè)實(shí)現(xiàn)類TreeMap實(shí)現(xiàn);TreeMap是一個(gè)有序的二叉樹.
* compareTo()返回值(二叉樹實(shí)現(xiàn)元素唯一和排序原理):
0:相等就不存【保證元素的唯一性】
負(fù)數(shù):小的存在左邊【保證排序】
正數(shù):大的存在右邊
* TreeSet能對(duì)Integer和String類型的數(shù)據(jù)進(jìn)行排序
因?yàn)镮nteger和String都實(shí)現(xiàn)Comparable接口并實(shí)現(xiàn)了compareTo()方法
* 自定義的對(duì)象
(1)實(shí)現(xiàn)Comparable接口并自定義compareTo()方法來(lái)實(shí)現(xiàn)自定義的規(guī)則排序
class Person implements Comparable<Person> {
public int compareTo(Person p) {
int num = this.age - p.age;
return num == 0 ? this.name.compareTo(p.name) : num;
}
}
TreeSet<Person> ts = new TreeSet<Person>();
ts.add(new Person("zhangsan", 23));
ts.add(new Person("lisi", 24));
}
(2)在TreeSet構(gòu)造方法中傳入一個(gè)Comparator比較器
TreeSet<Person> ts = new TreeSet<Person>(new Comparator<Person>(){
public int compare(Person p1, Person p2) {
int num = p1.getAge() - p2.getAge();
return num == 0 ? p1.getName().compareTo(p2.getName()) : num;
}
});
ts.add(new Person("zhangsan", 23));
ts.add(new Person("lisi", 24));
Map集合(雙列集合)
put(K key,V value);//存儲(chǔ)的是鍵值對(duì)
entrySet();//獲取所有鍵值對(duì)
keySet();//獲取所有鍵
HashMap和HashTable(數(shù)據(jù)是哈希表,通過(guò)hashCode()和equals()來(lái)保證數(shù)據(jù)唯一)
*線程安全問題
線程安全:多線程并發(fā)訪問修改某個(gè)類,不需要額外的代碼表現(xiàn)出正確的行為
線程不安全:多線程并發(fā)訪問修改某個(gè)類,表現(xiàn)出不正確的行為
原因:多線程交替執(zhí)行任務(wù)痊银,產(chǎn)生了競(jìng)態(tài)條件
解決機(jī)制:
1.加鎖(原子性)
2.不公享狀態(tài)
3.用final修飾成不可變對(duì)象
*區(qū)別:
HashMap線程不安全抵蚊,效率高;HashTable是線程安全,效率低
HashTable可以存儲(chǔ)null key值和null value值,而HashTable都不可以
TreeMap
底層數(shù)據(jù)結(jié)構(gòu)時(shí)二叉樹溯革,不同步贞绳,可排序;與Set很像,Set底層就是使用了Map集合
* compareTo()返回值(二叉樹實(shí)現(xiàn)元素唯一和排序原理):
0:相等就不存【保證元素的唯一性】
負(fù)數(shù):小的存在左邊【保證排序】
正數(shù):大的存在右邊
* 自然排序(元素具備比較性):
實(shí)現(xiàn)Comparable接口
* 比較器排序(集合具備比較性)
實(shí)現(xiàn)Comparator接口 \
集合工具類
Collections:操作集合(一般是list集合)的工具類致稀。方法全為靜態(tài)的
sort(List list);對(duì)list集合進(jìn)行排序; sort(List list, Comparator c)
按指定比較器排序
fill(List list, T obj);將集合元素替換為指定對(duì)象冈闭;
swap(List list, int I, int j)交換集合指定位置的元素
shuffle(List list); 隨機(jī)對(duì)集合元素排序
reverseOrder() :返回比較器,強(qiáng)行逆轉(zhuǎn)實(shí)現(xiàn)Comparable接口的對(duì)象自然順序
reverseOrder(Comparator c):返回比較器抖单,強(qiáng)行逆轉(zhuǎn)指定比較器的順序
數(shù)組對(duì)象工具類
asList():將數(shù)組轉(zhuǎn)為list集合
* 好處:可通過(guò)list集合的方法操作數(shù)組中的元素:
isEmpty()萎攒、contains()、indexOf()矛绘、set()
* 弊端:數(shù)組長(zhǎng)度固定耍休,不可使用集合的增刪操作。
如果數(shù)組中存儲(chǔ)的是基本數(shù)據(jù)類型货矮,asList會(huì)將數(shù)組整體作為一個(gè)元素存入集合
集合轉(zhuǎn)為數(shù)組:Collection.toArray()羊精;
好處:限定了對(duì)集合中的元素進(jìn)行增刪操作,只需獲取元素