心得感悟
這兩天都在學(xué)集合的方法,如果沒理解透忙厌,很容易混淆不同的集合的概念和方法凫岖,在多番查閱后,總結(jié)了一點(diǎn)集合之間的區(qū)別逢净。雖然老師講課的知識(shí)點(diǎn)是有順序的哥放,但剛聽完課腦子里還是一團(tuán)亂麻,寫博客的確是一個(gè)梳理思路的好辦法爹土,感覺寫博客就像自己當(dāng)老師一樣甥雕,如果要去教別人,肯定自己心里要有數(shù)着饥。
內(nèi)容簡(jiǎn)概
- 一犀农、集合框架圖
- 二、HashSet集合
- 三宰掉、HashMap集合
- 四呵哨、TreeSet集合
- 五、HashSet和HashMap的區(qū)別
- 六轨奄、HashSet和ArrayList的區(qū)別
具體內(nèi)容
一孟害、集合框架圖
在上一篇文章中,我講解了Collection中的幾個(gè)子類挪拟,這篇文章我將主要講解Map類的幾個(gè)子類挨务,如下圖。
二、HashSet集合
1. 概念:
特點(diǎn):作為Set集合的一種谎柄,首先是無序的丁侄,不可重復(fù)的;允許存放null值
2. 常用方法
因?yàn)镠ashSet繼承Colletion朝巫,其實(shí)方法都大同小異鸿摇,具體的代碼請(qǐng)看上一篇文章,這里再講一下removeIf方法劈猿,其他方法只列出方法名與功能拙吉。
方法名 | 功能 |
---|---|
add() | 添加元素 |
isEmpty() | 如果此 set 不包含任何元素,則返回 true |
contains(Object o) | 判斷是否包含某個(gè)元素 |
int size() | 獲取集合的大芯救佟(所含元素個(gè)數(shù)) |
removeIf | 根據(jù)條件刪除元素 |
HashSet<String> names = new HashSet<>();
names.add("jack");
names.add("marry");
names.add("abc");
names.removeIf(ele -> ele.compareTo("c")>0);
運(yùn)行結(jié)果:
[abc]
compareTo方法會(huì)用元素的首字母和指定元素的ASCII碼比較筷黔,因?yàn)?code>m,j的·ASCII碼比c
的ASCII碼大仗颈,故會(huì)移除jack
和marry
三佛舱、HashMap集合
1. 概念
HashMap其實(shí)就是一個(gè)有映射關(guān)系的集合。其存儲(chǔ)數(shù)據(jù)特點(diǎn)為:鍵key- 值value揽乱。比如小明語文98分名眉,小花語文92分粟矿,小亮語文98分凰棉。人物就是key,分?jǐn)?shù)就是value陌粹,一個(gè)key只能有一個(gè)value撒犀,但是多個(gè)key可以指向同一個(gè)value。
2. 常用方法
方法名 | 功能 |
---|---|
put | 添加元素 |
size() | 獲取鍵值對(duì)的個(gè)數(shù) |
keySet() | 獲取所有的key |
values() | 獲取所有的value |
entrySet() | 獲取Entry:key-value |
get() | 獲取一個(gè)鍵對(duì)應(yīng)的值 |
3. 簡(jiǎn)單例子
運(yùn)行結(jié)果為:
(1){English=92, Chinese=89, Math=94}
(2){English=92, Chinese=91, Math=94}
(3)3
(4)[English, Chinese, Math]
(5)[92, 91, 94]
(6)[English=92, Chinese=91, Math=94]
(7)92
```java
HashMap<String,Integer> score = new HashMap<>();
// 1.添加對(duì)象:鍵值對(duì)
score.put("Chinese",89);
score.put("Math",94);
score.put("English",92);
System.out.println(score);
// 2.更改某個(gè)鍵對(duì)應(yīng)的值
// 由于Set集合的不可重復(fù)性掏秩,再定義一個(gè)相同的key時(shí)或舞,若value不同,后者會(huì)覆蓋前者
score.put("Chinese",91);
System.out.println(score);
// 3.獲取鍵值對(duì)的個(gè)數(shù)
System.out.println(score.size());
//4. 獲取所有的key
System.out.println(score.keySet());
//5. 獲取所有的value
System.out.println(score.values());
// 6.獲取Entry:key-value
System.out.println(score.entrySet());
// 7.獲取一個(gè)鍵對(duì)應(yīng)的值
System.out.println(score.get("English"));
4. 鍵值對(duì)的遍歷方法
(1)通過遍歷key來得到每個(gè)key對(duì)應(yīng)的值蒙幻,運(yùn)行結(jié)果為:
key:English value:92
key:Chinese value:91
key:Math value:94
for(String key: score.keySet()){
//通過key得到值
int s = score.get(key);
System.out.println("key:"+ key+" value:"+s);
}
(2)通過EntrySet 得到Entry對(duì)象的集合映凳,運(yùn)行結(jié)果為:
key:English value:92
key:Chinese value:91
key:Math value:94
// 一個(gè)Entry管理一個(gè)鍵值對(duì) getKey getValue
Set<Map.Entry<String,Integer>> enteys = score.entrySet();
for (Map.Entry entry:enteys){
// 得到Entry對(duì)應(yīng)的key
String key = (String)entry.getKey();
// 獲取Entry對(duì)應(yīng)的值
Integer value = (Integer)entry.getValue();
System.out.println("key:"+ key+" value:"+ value);
}
四、TreeSet集合
1. 概念
TreeSet是用來排序的集合邮破,可以實(shí)現(xiàn)對(duì)元素按照某種規(guī)則進(jìn)行排序诈豌。
2. 排序方式(1)自然排序
TreeSet會(huì)調(diào)用集合元素的compareTo(Object obj)方法來比較元素之間大小關(guān)系,然后將集合元素按升序排列抒和,這種方式就是自然排序矫渔。(比較的前提:兩個(gè)對(duì)象的類型相同)。(2)比較器排序
自然排序的使用十分有限摧莽,當(dāng)我們希望一個(gè)程序能按照名字排序或者降序時(shí)庙洼,則需要自定義一個(gè)比較器,即編寫一個(gè)
TreeSet默認(rèn)采用自然排序。
- 自然排序例子
【錯(cuò)誤版】在這個(gè)例子中油够,添加一個(gè)元素不會(huì)報(bào)錯(cuò)蚁袭,但添加兩個(gè)以上的元素后,但是沒進(jìn)行比較排序石咬,程序會(huì)報(bào)錯(cuò)撕阎,那么如何使用默認(rèn)的自然排序呢?請(qǐng)往下看碌补。
public class Test1{
public static void main(String[] args) {
TreeSet<Number> ts = new TreeSet();
Number n1 = new Number(2);
Number n2 = new Number(1);
//向TreeSet集合中添加兩個(gè)Number對(duì)象
ts.add(n1);
ts.add(n2);
System.out.println(ts);
}
}
class Number{
int num;
public Number(int num){
this.num = num;
}
}
【正確版】只要讓該類繼承Comparable接口就可以了虏束,然后使用接口規(guī)定的compareTo方法。我們的輸入順序是[2,1]厦章,但是自然排序已經(jīng)按升序順序?qū)λ匦屡帕姓蛟龋蔬\(yùn)行結(jié)果為:[1,2]
public class Test1 {
public static void main(String[] args) {
TreeSet<Number> ts = new TreeSet();
Number n1 = new Number(2);
Number n2 = new Number(1);
//向TreeSet集合中添加兩個(gè)Number對(duì)象
ts.add(n1);
ts.add(n2);
System.out.println(ts);
}
}
class Number implements Comparable {
int num;
public Number(int num){
this.num = num;
}
@Override
public int compareTo(Object o) {
return 0;
}
}
【進(jìn)階版】在升序排列的前提下,如果還有其他排序要求袜啃,可以重寫compareTo的方法汗侵。注意的是,數(shù)字優(yōu)先排序群发。下面這個(gè)例子在先按年齡升序排序晰韵,再按名字排序。運(yùn)行結(jié)果為:
[Person{name='jack', age=5}, Person{name='rose', age=18}, Person{name='rose', age=19}, Person{name='jack', age=30}]
public class Test1 {
public static void main(String[] args) {
TreeSet<Person> score = new TreeSet<>((Person p1,Person p2) -> p1.compareTo(p2));
score.add(new Person("jack",5));
score.add(new Person("jack",30));
score.add(new Person("rose",18));
score.add(new Person("rose",19));
System.out.println(score);
}
}
class Person implements Comparable{
String name;
int age;
public Person(String name, int age){
this.name = name;
this.age = age;
}
@Override
public String toString() {
return "Person{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
@Override
public int compareTo(Object o) {
// 1.判斷o對(duì)象是不是person的一個(gè)對(duì)象
if (o instanceof Person){
Person o1 = (Person)o;
//自己規(guī)定比較的策略
if (this.age != o1.age){
return this.age - o1.age;
}else {
//年齡相同的情況下 再比姓名的字母
return this.name.compareTo(o1.name);
}
}else {
return -1;
}
}
- 比較器排序例子
在這個(gè)例子中熟妓,我們用比較器實(shí)現(xiàn)降序排序雪猪,可以使用Comparator接口。該接口里包含一個(gè)int compare(T o1,T o2)方法起愈,該方法用于比較o1和o2的大小只恨。運(yùn)行結(jié)果為:[Number{num=54}, Number{num=9}, Number{num=4}, Number{num=-3}]
public class Test1 {
public static void main(String[] args) {
TreeSet<Number> ts = new TreeSet<>(new Comparator<Number>() {
@Override
public int compare(Number num1, Number num2) {
Number m1 = num1;
Number m2 = num2;
if (m1.num > m2.num) {
return -1;
} else if (m1.num == m2.num) {
return 0;
} else {
return 1;
}
}
});
ts.add(new Number(-3));
ts.add(new Number(9));
ts.add(new Number(54));
ts.add(new Number(4));
System.out.println(ts);
}
}
class Number {
int num;
public Number(int num){
this.num = num;
}
@Override
public String toString() {
return "Number{" +
"num=" + num +
'}';
}
}
五、HashSet和HashMap的區(qū)別
HashMap | HashSet |
---|---|
實(shí)現(xiàn)了Map接口 | 實(shí)現(xiàn)Set接口 |
存儲(chǔ)鍵值對(duì) | 僅存儲(chǔ)對(duì)象 |
調(diào)用put()向map中添加元素 | 調(diào)用add()方法向Set中添加元素 |
使用鍵(Key)計(jì)算Hashcode | 使用成員對(duì)象來計(jì)算hashcode值抬虽,對(duì)于兩個(gè)對(duì)象來說hashcode可能相同官觅,所以equals()方法用來判斷對(duì)象的相等性,如果兩個(gè)對(duì)象不同的話阐污,那么返回false |
相對(duì)于HashSet較快休涤,因?yàn)樗鞘褂梦ㄒ坏逆I獲取對(duì)象 | 較HashMap來說比較慢 |
六、HashSet和ArrayList的區(qū)別
ArrayList | HashSet |
---|---|
元素可重復(fù) | 元素不可重復(fù) |
有序存放 | 無序存放 |
存儲(chǔ)數(shù)組 | 存儲(chǔ)對(duì)象 |