天天看點

Java集合(常用方法)

*1*|集合什麼是集合概念

對象的容器,實作了對對象常用的操作

和數組的差別

  1. 數組長度固定,集合長度不固定
  2. 數組可以存儲基本類型和引用類型,集合隻能存儲引用類型(基本類型可以通過裝箱操作存儲)

位置

java.util.*;
           

*1*|***2***Collection體系

Java集合(常用方法)

Collection 父接口

特點:代表一組任意類型的對象,無序、無下标、不能重複。

建立集合

Collection collection = new ArrayList();

常用方法

  1. 添加元素 collection.add(“蘋果”);
  2. 删除元素

    collection.remove(“蘋果”);

    collection.clear();

    //清空
  3. 周遊元素(重點)
    1. 使用增強for(因為無下标)
      for(Object object : collection){ 
         sout
      }
                 
    2. 使用疊代器(專門周遊集合)
      //haNext(); 有下一個元素,傳回true
      //next(); 擷取下一個元素
      //remove(); 删除目前元素
      Iterator it = collection.iterator();
      while(it.hasNext()){
        String object = (String)it.next(); //強轉
        // 可以使用it.remove(); 進行移除元素
        // collection.remove(); 不能用collection其他方法 會報并發修改異常
      }
                 
  4. 判斷 collection.contains(); collection.isEmpty();

List 子接口

特點:有序、有下标、元素可重複

建立集合對象 List list = new ArrayList<>( );

常用方法

  1. 添加元素

    list.add( );

    會對基本類型進行自動裝箱
  2. 删除元素 可以用索引

    list.remove(0)

    當删除數字與索引沖突時 對數字強轉

    list.remove((Object) 10)

    list.remove(new Integer(10))

  3. 周遊
    1. 使用for周遊
      for(int i = 0; i < lise.size(); i++){
        sout(list.get(i)); 
      }
                 
    2. 使用增強for

      for(Object list: collection){ }

    3. 使用疊代器
      Iterator it = collection.iterator();
      while(it.hasNext()){
        String object = (String)it.next(); //強轉
        // 可以使用it.remove(); 進行移除元素
        // collection.remove(); 不能用collection其他方法 會報并發修改異常
      }
                 
    4. 使用清單疊代器 💡(注意和疊代器差別)
      ListIterator li = list.listIterator();
      while(li.hasNext()){
        System.out.println(li.nextIndex() + ":" + li.next()); //從前往後周遊
      }
      
      while(li.hasPrevious()){
        System.out.println(li.previousIndex() + ":" + li.previous()); //從後往前周遊
      }
                 
  4. 擷取

    list.indexOf( );

  5. 傳回子集合

    sublist(x, y);

    左閉右開

    List subList = list.subList(1, 3);

    傳回索引 1、2

List實作類

  • ArrayList 【重點】
    • 數組結構實作,必須要連續空間,查詢快、增删慢
    • jdk1.2版本,運作效率塊、線程不安全
  • Vector
    • 數組結構實作,查詢快、增删慢
    • jdk1.0版本,運作
  • LinkedList
    • 雙向連結清單結構實作,無需連續空間,增删快,查詢慢

ArrayList

建立集合

ArrayList arrayList = new ArrayList<>();

  1. 添加元素

    arrayList.add();

  2. 删除元素

    arrayList.remove(new Student("name", 10));

    這裡重寫了 equals(this == obj) 方法
    public boolean equals(Object obj){
      //1 判斷是不是同一個對象
      if(this == obj){
        return true;
      }
      //2 判斷是否為空
      if(obj == null){
        return false;
      }
      //3 判斷是否是Student類型
      if(obj instanceof Student){
        Student == (Student)obj;
        //4 比較屬性
        if(this.name.equals(s.getName()) && this.age == s.getAge()){
          return true;
        }
      }
      //5 不滿足條件傳回false
      return false;
    }
               
  3. 周遊元素【重點】
    1. 使用疊代器
      Iterator it = arrayList.iterator();
      while(it.hasNext()){
        Student s = (Student)it.next(); //強轉
      }
                 
    2. 清單疊代器
      ListIterator li = arrayList.listIterator();
      while(li.hasNext()){
        Student s = (Student)li.next(); //從前往後周遊
      }
      
      while(li.hasPrevious()){
        Student s = (Student)li.previous();//從後往前周遊
      }
                 
  4. 判斷

    arrayList.contains();

    arrayList.isEmpty();

  5. 查找

    arrayList.indexof();

原碼分析

DEFAULT_CAPACITY = 10; //預設容量
//注意:如果沒有向集合中添加任何元素時,容量0,添加一個後,容量為10
//每次擴容是原來的1.5倍
elementData存放元素的數組
size 實際元素個數
           

Vector

建立集合

Vector vector = new Vector<>();

增加、删除、判斷同上

周遊中枚舉器周遊

Enumeration en = vector.elements();
while(en.hasMoreElements()){
  String o = (String)en.nextElement();
  sout(o);
}
           

LinkedList

建立連結清單集合

LinkedList li = new LinkedList<>();

常用方法與List一緻

*1*|***3***泛型

  • 本質是參數化類型,把類型作為參數傳遞
  • 常見形式有泛型類、泛型接口、泛型方法
  • 文法 T成為類型占位符,表示一種引用類型,可以寫多個逗号隔開
  • 好處 1. 提高代碼重用性 2. 防止類型轉換異常,提高代碼安全性

泛型類

// 寫一個泛型類
public class MyGeneric<T>{
  //使用泛型T
  //1 建立變量
  T t;
  //2 泛型作為方法的參數
  public void show(T t){
    sout(t);
  }
  //3 泛型作為方法的傳回值
  public T getT(){
    return t;
  }
}
           
// 使用泛型類
public class TestGeneric{
  public static void main(String[] args){
    //使用泛型類建立對象
    // 注意: 1. 泛型隻能使用引用類型
    //			 2. 不用泛型類型對象之間不能互相指派
    MyGeneric<String> myGeneric = new MyGeneric<String>();
    myGeneric.t = "hello";
    myGeneric.show("hello world!");
    String string = myGeneric.getT();
    
    MyGeneric<Integer> myGeneric2 = new MyGeneric<Integer>();
    myGeneric2.t = 100;
    myGeneric2.show(200);
    Integer integer = myGeneric2.getT();
    
  }
}
           

泛型接口

文法:接口名

注意:不能泛型靜态常量

泛型方法

文法: 傳回值類型

public class MyGenericMethod{
  //泛型方法
  public <T> T show(T t){
    sout("泛型方法" + t);
    return t;
  }
}

//調用
MyGenericMethod myGenericMethod = new MyGenericMethod();
myGenericMethod.show("字元串");// 自動類型為字元串
myGenericMethod.show(200);// integer類型
myGenericMethod.show(3.14);// double類型
           

泛型集合

概念:參數化類型、類型安全的集合,強制集合元素的類型必須一緻

特點:

  • 編譯時即可檢查,而非運作時抛出異常
  • 通路時,不必類型轉換(拆箱)
  • 不同泛型之間應用不能互相指派,泛型不存在多态

*1*|***4***Set集合

特點:無序、無下标、元素不可重複

方法:全部繼承自Collection中的方法

增、删、周遊、判斷與collection一緻

HashSet 【重點】

存儲結構:哈希表(數組+連結清單+紅黑樹)

存儲過程(重複依據)

  1. 根據hashCode計算儲存的位置,如果位置為空,直接儲存,若不為空,進行第二步
  2. 再執行equals方法,如果equals為true,則認為是重複,否則形成連結清單

特點

  • 基于HashCode計算元素存放位置
    • 利用31這個質數,減少散列沖突
      • 31提高執行效率

        31 * i = (i << 5) - i

        轉為移位操作
    • 當存入元素的哈希碼相同時,會調用equals進行确認,如果結果為true,則拒絕後者存入

建立集合

HashSet<String> hashSet = new HashSet<String>();

添加元素

hashSet.add( );

删除元素

hashSet.remove( );

周遊操作

  1. 增強for

    for( type type : hashSet)

  2. 疊代器

    Iterator<String> it = hashSet.iterator( );

判斷

hashSet.contains( );

hashSet.isEmpty();

TreeSet

特點

  • 基于排列順序實作元素不重複
  • 實作SortedSet接口,對集合元素自動排序
  • 元素對象的類型必須實作Comparable接口,指定排序規則
  • 通過CompareTo方法确定是否為重複元素

存儲結構:紅黑樹

建立集合

TreeSet<String> treeSet = new TreeSet<>()

添加元素

treeSet.add();

删除元素

treeSet.remove();

周遊 1. 增強for 2. 疊代器

判斷

treeSet.contains();

補充:TreeSet集合的使用

Comparator 實作定制比較(比較器)

Comparable 可比較的

// 重寫compare
@override
public int compare(Person o1, Person o2){
  int n1 = o1.getAge()-o2.getAge();
  int n2 = o1.getName().comareTo(o2.getName());
  return n1 == 0 ? n2 : n1;
}
           

*1*|***5***Map

Map接口的特點

1. 用于存儲任意鍵值對(key - value)
2. 鍵:無序、無下标、不允許重複(唯一)
3. 值:無序、無下标、允許重複
           

方法:

1. V put(K key, V value) 将對象存到集合中,關聯鍵值
2. Object get(Object key) 根據鍵獲得對應的值
3. Set<K> 傳回所有的Key
4. Collection<V> values() 傳回包含所有值的Collection集合
5. Set<Map.Entry<K, V>> 鍵值比對的Set集合
           

Map接口的使用

//建立Map集合
Map<String, String> map = new HashMap<>();
// 1. 添加元素
map.put("cn", "中國");
map.put("uk", "英國");
map.put("cn", "zhongguo"); // 會替換第一個 
// 2. 删除
map.remove("uk");
// 3. 周遊
// 3.1 使用KeySet()
//Set<String> keyset = map.keySet(); // 所有Key的set集合
for(String key : map.keyset){
  sout(key + "---" + map.get(key));
}
// 3.2 使用entrySet()
//Set<Map.Entry<String, String>> entries = map.entrySet();
for(Map.Entry<String, String> entry : map.entries){
  sout(entry.getKey() + "---" + entry.getValue();
}
           

HashMap 【重點】

存儲結構:哈希表(數組+連結清單+紅黑樹)

使用key可使hashcode和equals作為重複

增、删、周遊、判斷與上述一緻

原碼分析總結:

  1. HashMap剛建立時,table是null,節省空間,當添加第一個元素時,table容量調整為16
  2. 當元素個數大于門檻值(16*0.75 = 12)時,會進行擴容,擴容後的大小為原來的兩倍,目的是減少調整元素的個數
  3. jdk1.8 當每個連結清單長度 >8 ,并且數組元素個數 ≥64時,會調整成紅黑樹,目的是提高效率
  4. jdk1.8 當連結清單長度 <6 時 調整成連結清單
  5. jdk1.8 以前,連結清單時頭插入,之後為尾插入

Hashtable

線程安全,運作效率慢;不允許null作為key或是value

Properties

hashtable的子類,要求key和value都是string,通常用于配置檔案的讀取

TreeMap

實作了SortedMap接口(是map的子接口),可以對key自動排序

*1*|**6**Collection工具類

概念:集合工具類,定義了除了存取以外的集合常用方法

直接二分查找

int i = Collections.binarySearch(list, x);

成功傳回索引

其他方法 : copy複制、reverse反轉、shuffle打亂

補充:

// list轉成數組
Integer[] arr = list.toArray(new Integer[10]);
sout(arr.length);
sout(Array.toString(arr));

// 數組轉成集合
// 此時為受限集合,不能 添加和删除!
String[] name = {"張三","李四","王五"};
List<String> list2 = Arrays.asList(names);

// 把基本類型數組轉為集合時,需要修改為包裝類
Integer[] nums = {100, 200, 300, 400, 500};
List<Integer> list3 = Arrays.asList(nums);
           

***6***Collection工具類

概念:集合工具類,定義了除了存取以外的集合常用方法

直接二分查找

int i = Collections.binarySearch(list, x);

成功傳回索引

其他方法 : copy複制、reverse反轉、shuffle打亂

補充:

// list轉成數組
Integer[] arr = list.toArray(new Integer[10]);
sout(arr.length);
sout(Array.toString(arr));

// 數組轉成集合
// 此時為受限集合,不能 添加和删除!
String[] name = {"張三","李四","王五"};
List<String> list2 = Arrays.asList(names);

// 把基本類型數組轉為集合時,需要修改為包裝類
Integer[] nums = {100, 200, 300, 400, 500};
List<Integer> list3 = Arrays.asList(nums);