目錄
一. Set接口
-
1. HashSet
-
1.1數(shù)據(jù)結構:哈希表
-
1.2無序不重復
-
1.3保證元素的唯一性
-
-
2. TreeSet
-
2.1 數(shù)據(jù)結構:紅黑樹(特殊的二叉查找樹)
-
2.2 TreeSet集合排序的兩種方式
-
二. Map接口
-
1. HashTable
-
2. HashMap
-
2.1 使用示例
-
2.2鍵值對的遍歷
-
-
3. TreeMap
三. Java異常處理
-
1.主要內(nèi)容
-
2. 自定義異常類
==============================================================
正文
一、Set接口
??Set繼承于Collection接口,是一個不允許出現(xiàn)重復元素,并且無序的集合,使用了默認排序,主要有HashSet和TreeSet兩大實現(xiàn)類。
- 注意: 無序指的是:元素的存入和取出的順序不一定一致
- 在判斷重復元素的時候,Set集合會調(diào)用hashCode()和equal()方法來實現(xiàn)。
- 它沒有提供額外的方法,可以說Set就是一個Collection
set集合添加元素并使用迭代器迭代元素:
public class MyClass {
public static void main(String[] args) throws IOException {
//Set 集合存和取的順序不一致
Set set = new HashSet();
set.add("唐僧");
set.add("孫悟空");
set.add("豬八戒");
set.add("沙和尚");
System.out.println(set);
//[沙和尚, 孫悟空, 豬八戒, 唐僧]
Iterator iterator = set.iterator();
while(iterator.hasNext()){
System.out.println(iterator.next());
}
}
}
Set集合框架圖:
Set常見方法 :
| 編號 | 方法 | 描述 |
|---|---|---|
| 1 | add() | 添加一個對象到集合中。 |
| 2 | clear() | 從集合中刪除所有對象。 |
| 3 | contains() | 如果指定的對象是集合中的元素,則返回true。 |
| 4 | isEmpty() | 如果集合沒有元素,則返回true。 |
| 5 | iterator() | 返回集合的Iterator對象,該對象可用于檢索對象。 |
| 6 | remove() | 從集合中刪除指定對象。 |
| 7 | size() | 返回集合中的元素數(shù)。 |
1. HashSet
- LinkedHashSet會保存插入的順序。
1.1數(shù)據(jù)結構:哈希表
??Hash是一種數(shù)據(jù)結構,用戶查找對象。Hash為每一個對象計算出一個整數(shù),稱為Hash Code(哈希值)。哈希表是按照哈希值來存的。當我們添加元素時,哈希值是一樣的,這時候,會進行是否是同一對象判斷equals,如果不是同一對象,那么會在當前對象下順延(串下來的)。
??HashSet對于判斷元素是否存在以及刪除等操作依賴的方法是元素的hashcode和equals方法
查看哈希值:
Person xw = new Person();
System.out.println(xw);
//swu.gyl.javatest.Person@75b84c92
//Object 類的 toString 方法返回一個字符串
//getClass().getName() + '@' + Integer.toHexString(hashCode())
//75b84c92就是哈希值
1.2無序不重復
public static void main(String[] args) {
HashSet<String> hs = new HashSet<String>();
System.out.println(hs.add("java1"));
System.out.println(hs.add("java1"));
hs.add("java2");
Iterator<String> it = hs.iterator();
while(it.hasNext()){
System.out.println(hs.add(it.next()));
}
}
//哈希值一樣,同一對象。添加失敗。存入和取出順序不一致。
輸出:
1.3保證元素的唯一性
( 1 ) 如果元素的hashCode值不同,不會調(diào)用equals,添加成功
( 2 ) 如果元素的hashCode值相同,才會判斷equals是否為true,為true添加失敗
舉一個栗子:hashSet存自定義對象Person,當姓名和年齡一致,元素重復。
所以,當我們自定義對象的時候,一般要復寫hashcode和equals方法,因為自定義對象可能要存放到hashSet集合中。還有,復寫hashCode要盡量保證哈希值的唯一性,一般根據(jù)判斷條件生成。
public static void main(String[] args) {
HashSet<Person> hs = new HashSet<Person>();
hs.add(new Person("a1", 11));
hs.add(new Person("a2", 22));
hs.add(new Person("a3", 33));
hs.add(new Person("a3", 33));
Iterator<Person> it = hs.iterator();
while(it.hasNext()){
Personperson = (Person)it.next();
sop(person.getName()+"::"+person.getAge());
}
//重寫了equals,沒重寫hashcode方法。發(fā)現(xiàn)equals發(fā)現(xiàn)沒被調(diào)用,而且都存入成功。說明計算得到是不同的哈希值。
// 鑒于需求,我們需要去重寫。說明,我們需要覆蓋hashcode方法,建立自己的哈希值。
// 哈希值的生成根據(jù)判斷條件
// 重寫hashcode方法,發(fā)現(xiàn),去重成功了。而且equals方法運行了。
}
class Person{
private String name;
private int age;
public Person(String n,int a){
this.name = n;
this.age = a;
}
public String getName(){
return this.name;
}
public int getAge(){
return this.age;
}
public boolean equals(Object obj){
if(!(obj instanceof Person))
return false;
Personp = (Person)obj;
System.out.println(this.name+"...."+this.age);
return this.name.equals(p.getName()) && this.age == p.getAge();
}
public int hashCode()
{
System.out.println(this.name+"...hashcode");
//return 60; 會有很多重復比較
return this.name.hashCode()+this.age*13;
}
2. TreeSet
??紅-黑樹的數(shù)據(jù)結構,默認對元素進行自然排序,如果在比較的時候兩個對象返回值為0,那么元素重復
2.1 數(shù)據(jù)結構:紅黑樹(特殊的二叉查找樹)
紅黑樹算法的規(guī)則: 左小右大。
2.2 TreeSet集合排序的兩種方式:
- 方式一: 讓元素自身具備比較性,實現(xiàn)Comparetor<t>接口,并重寫compare方法;
// 可以排序的集合
TreeSet<People> score = new TreeSet<>(new Comparator<People>() {
@Override
public int compare(People people, People t1) {
return people.compareTo(t1);
}
});
class People implements Comparable{
String name;
int age;
@Override
public String toString() {
return "People{" +
"name='" + name + '\'' +
", age=" + age +
'}';
}
public People(String name, int age){
this.name = name;
this.age = age;
}
- 方式二:讓容器自身具備比較性,自定義比較器,實現(xiàn)Comparable接口,覆蓋compareTo 方法。
TreeSet<People> score = new TreeSet<>((People p1,People p2) -> p1.compareTo(p2));
People p1 = new People("jack",20);
People p2 = new People("marry",30);
People p3 = new People("Tom",25);
score.add(p1);
score.add(p2);
score.add(p3);
if (p1.hashCode() == p2.hashCode()){
System.out.println("相同");
}else{
System.out.println("不相同");
}
System.out.println(score);
//equals 比較對象內(nèi)部的內(nèi)容
// 使用的兩個對象必須實現(xiàn) Comparable接口的compareTo方法
//在compareTo里面實現(xiàn)具體該如何比較
@Override
public int compareTo(Object o) {
// 1.判斷o對象是不是People的一個對象
if (o instanceof People){
People o1 = (People)o;
//自己規(guī)定比較的策略
if (this.age != o1.age){
return this.age - o1.age;
}else {
//年齡相同的情況下 再比姓名的字母
return this.name.compareTo(o1.name);
}
}else {
return 0;
}
}
}
二、Map接口
??Map是一種依照鍵(key)存儲元素的容器,鍵(key)很像下標,在List中下標是整數(shù)。在Map中鍵(key)可以使任意類型的對象。Map中不能有重復的鍵(Key),每個鍵(key)都有一個對應的值(value)。
一個鍵(key)和它對應的值構成map集合中的一個元素。
Map中的元素是兩個對象,一個對象作為鍵,一個對象作為值。鍵不可以重復,但是值可以重復。
將鍵映射到值的對象,一個映射不能包含重復的鍵;每個鍵最多只能映射到一個值。
[圖片上傳中...(image.png-7df4a3-1566048732614-0)]
Map 接口常用方法:
| 序號 | 方法 | 描述 |
|---|---|---|
| 1 | void clear() | 從此映射中移除所有映射關系。 |
| 2 | boolean containsKey(Object k) | 如果此映射包含指定鍵的映射關系,則返回 true。 |
| 3 | boolean containsValue(Object v) | 如果此映射將一個或多個鍵映射到指定值,則返回 true。 |
| 4 | Set entrySet( ) | 返回此映射中包含的映射關系的 Set 視圖。 |
| 5 | boolean equals(Object obj) | 比較指定的對象與此映射是否相等。 |
| 6 | Object get(Object k) | 返回指定鍵所映射的值;如果此映射不包含該鍵的映射關系,則返回 null。 |
| 7 | nt hashCode( ) | 返回此映射的哈希碼值。 |
| 8 | boolean isEmpty( ) | 如果此映射未包含鍵-值映射關系,則返回 true。 |
| 9 | Set keySet( ) | 返回此映射中包含的鍵的 Set 視圖。 |
| 10 | Object put(Object k, Object v) | 將指定的值與此映射中的指定鍵關聯(lián)。 |
| 11 | void putAll(Map m) | 從指定映射中將所有映射關系復制到此映射中。 |
| 12 | Object remove(Object k) | 如果存在一個鍵的映射關系,則將其從此映射中移除。 |
| 13 | int size( ) | 返回此映射中的鍵-值映射關系數(shù)。 |
| 14 | Collection values( ) | 返回此映射中包含的值的 Collection 視圖。 |

1. HashTable
??底層是哈希表數(shù)據(jù)結構,線程是同步的,不可以存入null鍵,null值。
效率較低,被HashMap 替代。
2. HashMap
??底層是哈希表數(shù)據(jù)結構,線程是不同步的,可以存入null鍵,null值。要保證鍵的唯一性,需要覆蓋hashCode方法,和equals方法。
??它的子類LinkedHashMap,是雙向鏈表來維護key-value對的次序,該鏈表定義了迭代順序,該迭代順序與key-value對的插入順序保持一致。
2.1 使用示例:
//HashMap 集合 存儲數(shù)據(jù)的特點 鍵key-值value
//key不能重復 可以是任意的對象類型 通常使用字符串String
HashMap<String,Integer> score = new HashMap<>();
//添加對象 鍵值對
score.put("Chinese",89);
score.put("Math",95);
score.put("English",99);
//更改某個鍵對應的值
score.put("Chinese",91);
//獲取鍵值對的個數(shù)
score.size();
//獲取所有的key
System.out.println(score.keySet());
//獲取所有的值
System.out.println(score.values());
//獲取Entry:key-value
System.out.println(score.entrySet());
//獲取一個key對應的值
System.out.println(score.get("English"));
2.2鍵值對的遍歷
- 方式一:通過遍歷key來得到每一個 key對應的值
for (String key:score.keySet()){
//通過key得到值value
int s = score.get(key);
System.out.println("key: "+key+" value: "+s);
}
- 方式二:通過EntrySet 得到Entry對象的集合
//一個Entry管理一個鍵值對 getKey getValue
Set<Map.Entry<String,Integer>> entries = score.entrySet();
for (Map.Entry entry:entries){
//得到Entry對應的key
String key = (String)entry.getKey();
//獲取Entry對應的值
Integer value = (Integer) entry.getValue();
System.out.println("key: "+key+" value: "+value);
}
- 方式三:通過values 獲取所有值,不能獲取到key對象
Map<Integer, String> map = new HashMap<Integer, String>();
map.put(1, "aaaa");
map.put(2, "bbbb");
map.put(3, "cccc");
System.out.println(map);
// 通過values 獲取所有值,不能獲取到key對象
// Collection<V> values()
Collection<String> vs = map.values();
Iterator<String> it = vs.iterator();
while (it.hasNext()) {
String value = it.next();
System.out.println(" value=" + value);
}
3. TreeMap
??底層是哈希表數(shù)據(jù)結構,線程是不同步的,可以存入null鍵,null值。要保證鍵的唯一性,需要覆蓋hashCode方法,和equals方法。
//主要實現(xiàn)
Set<Entry<Person, String>> entrySet = hm.entrySet();
Iterator<Entry<Person, String>> it = entrySet.iterator();
while (it.hasNext()) {
Entry<Person, String> next = it.next();
Person key = next.getKey();
String value = next.getValue();
System.out.println(key + " = " + value);
}
@Override
public int hashCode() {
return this.name.hashCode() + age * 37;
}
@Override
public boolean equals(Object obj) {
if (obj instanceof Person) {
Person p = (Person) obj;
return this.name.equals(p.name) && this.age == p.age;
} else {
return false;
}
}
@Override
public String toString() {
return "Person@name:" + this.name + " age:" + this.age;
}
三、異常處理(點擊了解更多)
??異常處理 ,處理運行過程中出現(xiàn)的不可控的錯誤,使程序更健壯。

1.主要內(nèi)容
- 如果需要自己處理異常 就catch
- 如果有多個異常 可以使用多個catch來捕獲, catch 的順序從小到大
- 如果異常出現(xiàn) 后面的代碼將不會執(zhí)行
- finally關鍵字用來創(chuàng)建在 try 代碼塊后面執(zhí)行的代碼塊。無論是否發(fā)生異常,finally 代碼塊中的代碼總會被執(zhí)行。在 finally 代碼塊中,可以運行清理類型等收尾善后性質(zhì)的語句。
- 使用throws拋出異常 交給外部處理
public static void test() throws FileNotFoundException,NullPointerException{
FileReader fr = new FileReader("");
}
- 使?throw拋出?個??創(chuàng)建的異常對象
public static void test2() throws IllegalAccessException {
//自己拋出異常
if (1 > 2){
throw new IllegalAccessException();
}
}
2. 自定義異常類:能夠??定義輸出內(nèi)容 更快地找到出現(xiàn)問題的位置
public static void test3() throws GYLException {
//....
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
StackTraceElement e = stackTrace[2];
String detail = e.getFileName()+"->"+e.getMethodName()+"->"+e.getLineNumber();
throw new GYLException("自己的異常類:無所作為"+detail);
}
//自定義異常
class GYLException extends Exception{
//1.提供一個無參構造方法
public GYLException(){
}
//2.提供一個有參構造方法 參數(shù)是一個字符串
public GYLException(String desc){
super(desc);
}
}
//捕獲自己的異常
try {
TException.test3();
} catch (GYLException e) {
e.printStackTrace();
}
// 輸出結果:
// GYLException: 自己的異常類:無所作為Exception1.java->main->74
四、心得體會
??今天學到了很多新知識點,要花更多的時間來消化,加油?。?!