package cn.itcast.collection;
import java.util.Comparator;
import java.util.TreeSet;
/*
* * Collection
* ------| List 有序列表接口列表 實現(xiàn)了List集合接口的類,特點是有序不可重復(fù)
*-----------| ArrayList 內(nèi)部維護(hù)了一個對象數(shù)據(jù),增刪慢先口,但是查詢塊
*-----------| LinedList 內(nèi)部是一個鏈表的數(shù)據(jù)結(jié)構(gòu)历涝,增刪改塊,查詢慢
*-----------| Vector? 底層維護(hù)了一個Object的數(shù)組對象秧廉,和ArrayList實現(xiàn)一樣,但是線程安全的疼电,操作效率低,已經(jīng)被ArrayList取代蔽豺。
*
* ------| Set 無序列表接口 實現(xiàn)Set集合接口的類,特點是無序不可重復(fù)
* ---------| HashSet Hash表? Set接口實現(xiàn)類? 底層使用Hash表來實現(xiàn)的修陡,特點:存儲速度快。
* ---------| TreeSet Set接口實現(xiàn)類? 如果元素具備自然順序的特性濒析,那么就按照自然順序排序存儲
*
* 無序: 元素添加進(jìn)入的順序和遍歷出來的順序是不一致的啥纸。
* 不可重復(fù):如果添加重復(fù)元素号杏,添加不會報錯斯棒,但是不會添加成功;
* Set 接口的實現(xiàn)類
* HashSet 集合類添加元素的原理:
* 當(dāng)向HashSet集合中添加元素的時候,HashSet對象會先調(diào)用元素的HashCode方法返回值荣暮,然后通過
*? 移位等運算就可以得出元素在Hash表中的存儲位置。也就是說如果HashSet得到的hash就是元素的hashCode方法
*? 返回的值穗酥,如果該值已經(jīng)在Hash表中存在惠遏,就不能再添加了》可能發(fā)生的情況:
*
*? 1. 如果Hash表算出的存儲位置目前沒有元素存儲骏啰,那么就可以將元素進(jìn)行存儲:
*? 2. 如果Hash表算出的存儲位置目前已經(jīng)有元素存儲节吮,就會再調(diào)用元素的equals()方法進(jìn)行比較判耕,如果返回true,
*? 說明元素重復(fù),不會進(jìn)行添加壁熄,如果不相等帚豪,說明元素不重復(fù)草丧,就科技繼續(xù)添加,也就是說一個位置放了兩個元素方仿。
*? 因此在Hash表中添加元素,一般要同時重寫元素的equals()和hashCode()方法仙蚜,如果hashCode()的值相等,就通過
*? 再次判斷equels的返回值來判斷是否重復(fù)了委粉。也就是說調(diào)用equals方法的前提是hashCode()返回的值是一樣的,
*? 所以并不是每次都會調(diào)用equals()方法贾节,這些方法都是由HashSet對象來調(diào)用。
*
* 注意:HashCode默認(rèn)情況下是對象的內(nèi)地地址栗涂,但是String對象改寫了Object的HashCode()方法
*
* treeSet 添加自定義對象
*
*
* TreeSet 自定義對象
* 1. 在TreeSet 中添加元素,如果元素本身就具備了自然順序的屬性斤程,那么就按照自然屬性排序:
* 2. 往TreeSet中添加元素的時候,如果元素本身不具備自然順序的屬性忿墅,那么元素所屬的類就要實現(xiàn)comparale接口,
* 實現(xiàn)比較的規(guī)則方法compareTo(),當(dāng)添加元素的時候由TreeSet對象類調(diào)用疚脐。
* 3.如果添加元素的時候comparaTo方法返回的結(jié)果是0,那么該元素就會被視為重復(fù)元素?zé)o法添加棍弄,
* 跟hashCode()和equals()方法沒有任何關(guān)系疟游;
* 4. 如果在TreeSet中添加元素的時候,元素本身不具備自然順序的屬性乡摹,同時元素也沒有實現(xiàn)Comparable接口,那么在創(chuàng)建
* TreeSet的時候聪廉,必須要傳入一個Comparator比較器對象,將元素之間的比較規(guī)則定義在compare函數(shù)中,當(dāng)添加元素的時候
* 自動調(diào)用比較器的compare方法;
*? ? 說明:推薦使用比較器Comparator; 因為比較器定義了可以多處使用》
*
*? ? 5.如果元素本身不具備自然順序特性板熊,元素本身實現(xiàn)了Comparable接口察绷,在創(chuàng)建TreeSet對象的時候干签,也傳入了比較器拆撼,那么安裝比較器
*? ? ? 的規(guī)則優(yōu)先使用》
*
*? ? 6.字符串具備可比性容劳,因為String類已經(jīng)實現(xiàn)了Comparable接口闸度,因此可以直接調(diào)用CompareTo方法
*? ? 字符串的比較規(guī)則:
*? ? 可以找對對應(yīng)相同的字符:比較的是長度
*? ? 可以找到對象不同的字符:比較的是對應(yīng)位置的字符的大小
*
* 自定義比較器的格式:
* class cmp impelements Comparator{
*
* }
*
* TreeSet的存儲原理:
* 底層是通過二叉樹的數(shù)據(jù)結(jié)構(gòu)實現(xiàn)的,存儲規(guī)則:左小右大莺禁,當(dāng)添加元素的時候依靠的是元素的comparable方法來添加元素
*
*/
class Cmp implements Comparator{
@Override
public int compare(Object o1, Object o2) {
// TODO Auto-generated method stub
Emp e1 = (Emp)o1;
Emp e2 = (Emp)o2;
return e1.id = e2.id;
}
}
class Emp implements Comparable{
int id; //ID號碼
String name; //姓名
double salary; //薪水
public Emp(int id, String name, double salary){
this.id = id;
this.name = name;
this.salary = salary;
}
@Override
public int compareTo(Object o) {
// TODO Auto-generated method stub
Emp e = (Emp)o;
return this.id-e.id; //安裝薪水的大寫排序
}
@Override
public String toString() {
// TODO Auto-generated method stub
return "{"+ this.id +","+ this.name +","+ this.salary +"}";
}
}
public class Demo6 {
public static void main(String[] args){
TreeSet ts = new TreeSet();
ts.add(new Emp(110, "michale", 12341.2));
ts.add(new Emp(112, "tom", 14341.2));
ts.add(new Emp(120, "jim", 32341.2));
ts.add(new Emp(150, "Ann", 124341.2));
System.out.println(ts);
}
}