集合與泛型
1、集合
集合對象是內存中的一個容器對象,用來方便的存貯批量的數據,集合中的數據在沒有持久化,程序運行結束后,數據將消失。在java語言中,設計的集合主要為3大類
? ? Set集合:實現Set接口的集合類稱為Set集合;
? ? List集合:實現List接口的集合類稱為List集合;
? ? Map集合:實現Map接口的集合類稱為Map集合
java對集合設計的相關接口與類放在:java.util包中,在我們使用集合時,需要導入對應的集合類或者接口
集合中只能放引用類型數據,不能放基本數據類型,如果要放,請使用基本數據類型的包裝類型
Collection是Set、List、Queue三個集合共同的接口
2、Set集合
Set集合特性:不包含重復元素,通過調用元素的equals方法實現判斷兩個元素是不是同一個元素
public interface Set<E> extends Collection<E>
Set接口的實現類:HashSet、TreeSet
1.HashSet
基于hash算法決定元素在集合中的存放位置,HashSet存取效率非常高
熟練Set集合的基本操作API:添加、刪除、獲取元素、集合大小,清空集合等獲取集合元素:
1、轉成數組
Set接口的實現類:HashSet、TreeSet
1.HashSet
基于hash算法決定元素在集合中的存放位置,HashSet存取效率非常高
熟練Set集合的基本操作API:添加、刪除、獲取元素、集合大小,清空集合等
獲取集合元素:
1、轉成數組
Set set = new HashSet();
set.add(1);
set.add(2);
set.add(3);
Object[] arr = set.toArray();
for (int i = 0; i < arr.length; i++) {
? ? System.out.println(arr[i]);
}
2、迭代器(Iterable)
迭代器:
- 一個遞歸獲取集合元素的方式 ,需要集合實現Iterable接口,此接口定義了迭代訪問集合元素的方法
- 迭代器是一個指針對象,默認指向集合第一個元素前,通過調用
hashNext()
方法可以移動迭代器 -
// 迭代器:Iterable
Iterator<T> iterator(); // 實現Iterable接口的方法,就能得到的一個迭代器對象// Iterator的主要方法
boolean hasNext(); ?// 如果仍有元素可以迭代,則返回true
E next(); ?// 返回迭代的下一個元素
void remove(); // 從迭代器指向的collection中移除迭代器返回的最后一個元素// 通過迭代器獲取Set集合元素
Set set = new HashSet();
set.add(1);
// ....
Iterator it = set.iterator();
while(it.hasNext()) {
? ? System.out.println(it.next());
} -
? ? 對Set集合,如果放到集合里的是一個對象,且當對象的某個屬性一致時,判斷為同一個屬性,如何操作?
Set集合默認是調用對象的equals方法比較,此時,已不能滿足我們的業務需要
解決方法:根據新的業務重寫equals方法, 此時還要重寫hashcode方法
下面的例子是當tel相同時視為同一個對象:
User類:
@Data
public class User {? ? private int id;
? ? private String name;
? ? private String tel;
? ? @Override
? ? public int hashCode(){
? ? ? ? // 這里重寫了hashCode方法,將tel作為hashCode的值
? ? ? ? return Integer.parseInt(tel);
? ? }? ? @Override
? ? public boolean equals(Object o){
? ? ? ? if (this == o) {
? ? ? ? ? ? return true;
? ? ? ? }
? ? ? ? if (o == null || getClass() != o.getClass()) {
? ? ? ? ? ? return false;
? ? ? ? }
? ? ? ? User user = (User) o;
? ? ? ? // 根據Tel是否相同判斷是否為同一個人
? ? ? ? if (tel.equals(user.getTel())) {
? ? ? ? ? ? return true;
? ? ? ? }
? ? ? ? return Objects.equals(id, user.id);
? ? }
} - 測試:
-
public static void main(String[] args){
? ? Set set = new HashSet();? ? User u1 = new User();
? ? u1.setId(1);
? ? u1.setName("張三");
? ? u1.setTel("183");? ? User u2 = new User();
? ? u2.setId(2);
? ? u2.setName("李四");
? ? u2.setTel("183");? ? set.add(u1);
? ? set.add(u2);? ? // 可以看到,只輸出了1,證明只有1個對象存進去了
? ? System.out.println(set.size());? ? Iterator it = set.iterator();
? ? while (it.hasNext()){
? ? ? ? System.out.println(it.next());
? ? }}
-
2.TreeSet
Set接口的第2個實現類,TreeSet相對于HashSet,多了一個排序的功能
排序方法:使用元素的自然順序對元素進行排序
元素的自然順序:此元素實現Comparable接口,當將元素放到TreeSet集合中,TreeSet集合就根據Comparable接口定義的比較規則來比較元素
// 返回值為整型: 為0 表示兩個元素相等,大于0 表示大于,小于0 表示小于
public interface Comparable{
? int compareTo(T o) ?
}如果放到TreeSet集合中的元素沒有實現自然排序,則意味會出異常。在JDK中,8種基本數據類型的包裝類型和字符串都實現了此接口
-
如果在集合中放其它類型的元素,必須手動實現Comparable接口,并實現接口中定義的compareTo方法
-
@Data
public class User implements Comparable<User>{? ? private int id;
? ? private String name;
? ? private String tel;
? ? @Override
? ? public int compareTo(User o) {
? ? ? ? // 根據id排序
? ? ? ? int compare = Integer.compare(this.id, o.getId());
? ? ? ? if (compare == 0) {
? ? ? ? ? ? // 若id相同,則根據名字排序
? ? ? ? ? ? return this.name.compareTo(o.getName());
? ? ? ? }
? ? ? ? return compare;
? ? }
}