Java 集合

Java 集合



1. 集合基本概念

  集合表示一組對象,每個對象被稱爲其元素。一些集合允許重複的元素,而另一些則不允許。一些是有序的,而其他則是無序的。



2. 集合與數組的區別

區別 元素類型 元素個數
數組 基本類型、引用類型 固定,不能任意擴展
集合 引用類型(存儲基本類型時自動裝箱) 不固定,可任意擴展

集合的優點:

  • 不受容器大小限制,可以隨時添加、刪除元素。
  • 提供了大量操作元素的方法(判斷、獲取等)。


3. 泛型

  泛型,顧名思義指的是任意類型,又叫參數化類型(ParameterizedType),對具體類型的使用起到輔助作用,類似於方法參數。

Java 泛型百度百科

菜鳥教程講解 Java 泛型


3.1 集合類泛型

  表示該集合中存放指定類型的元素,例如:

List<String> list = new ArrayList<>() 。

3.2 泛型好處

  • 泛化:可以用T代表任意類型。
  • 類型安全:使用泛型可以使編譯器知道變量的類型限制,進而可以在更高程度上驗證類型假設。
  • 消除強制類型轉換:使代碼更加可讀,並減少出錯的機會。

注意:

  • 泛型一般只會和集合類結合使用。
  • 泛型是JDK5的新特性,從JDK7開始,右邊的泛型可以不用寫具體的數據類型了。(菱形泛型)

應用舉例:

//指定集合中的元素時 String 類型
List<String> list2 = new ArrayList<>();
list2.add("abc");
list2.add("bcd");
list2.add("cde");

//2. 遍歷集合:增強 for
for (String str : list2) {
    System.out.println(str);
}


4. 迭代器(Iterator)

  迭代器是遍歷Collection集合的通用方式,可以在對集合遍歷的同時進行添加、刪除等操作。

迭代器的API介紹


4.1 迭代器中的方法

方法名 描述
boolean hasNext() 如果還有可迭代元素,則返回true。
E next() 返回迭代中的下一個元素對象。
default void remove() 從基礎集合中移除此迭代器返回的最後一個元素(可選操作)。

應用演示:

// list 集合對象
List list = new ArrayList();
//使用迭代器遍歷 list 集合
Iterator it = list.iterator();
while (it.hasNext()){
    System.out.println(it.next());
}
//使用增強 for 來遍歷 list 集合
for (Object object: list){
            System.out.println(object);
        }


5. Collections 接口

  Collection 是最基本的集合接口,一個 Collection 代表一組 Object,即 Collection 的元素, Java不提供直接繼承自Collection的類,只提供繼承於的子接口(如List和set)。

Collection 接口的 API 介紹


5.1 Collections中常用方法

方法名 描述
sort​(List list) 根據其元素的自然順序,將指定列表按升序 排序。
max​(Collection<? extends T> coll) 根據其元素的自然順序返回給定集合的最大元素。
reverse​(List<?> list) 反轉指定列表中元素的順序。
shuffle​(List<?> list) 使用默認的隨機性源隨機排列指定的列表。

實例演示:

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;

/**
 * 演示Collections類
 */
public class Test {
    public static void main(String[] args) {
        //創建集合對象
        List<Integer> list = new ArrayList<>();
        //添加元素
        list.add(1);
        list.add(2);
        list.add(3);
        list.add(4);
        list.add(5);
        list.add(4);
        list.add(3);
        list.add(2);
        list.add(1);
        //打印集合
        System.out.println(list);
        System.out.println("---------------------分割線-------------------------");
        //max()方法:獲取最大元素
        Integer max = Collections.max(list);
        System.out.println("集合中最大的元素爲:"+max);
        System.out.println("---------------------分割線-------------------------");
        //sort();按升序排序
        Collections.sort(list);
        System.out.println("升序排列後的結果爲:"+list);
        System.out.println("---------------------分割線-------------------------");
        //reverse():對集合中的數據進行翻轉
        Collections.reverse(list);
        System.out.println("反轉以後的數據爲:"+list);
        //降序排序==升序排序+反轉
        System.out.println("---------------------分割線-------------------------");
        //shuffle():隨機置換
        Collections.shuffle(list);
        System.out.println("隨機置換後的數據:" + list);
    }
}

運行結果:

[1, 2, 3, 4, 5, 4, 3, 2, 1]
---------------------分割線-------------------------
集合中最大的元素爲:5
---------------------分割線-------------------------
升序排列後的結果爲:[1, 1, 2, 2, 3, 3, 4, 4, 5]
---------------------分割線-------------------------
反轉以後的數據爲:[5, 4, 4, 3, 3, 2, 2, 1, 1]
隨機置換後的數據:[2, 1, 4, 1, 5, 3, 3, 2, 4]



6. List 接口

  List 接口是一個有序的 Collection,使用此接口能夠精確的控制每個元素插入的位置,能夠通過索引(元素在 List 中位置,類似於數組的下標)來訪問List中的元素,第一個元素的索引爲 0,而且允許有相同的元素。
  List是單列集合,具有重複性、有序(存取順序相同)等特點。

List 接口的 API 介紹


6.1 List 接口中常用方法

方法名 描述
void add​(int index, E element) 將指定的元素插入此列表中的指定位置。
boolean add​(E e) 將指定的元素追加到此列表的末尾。
E get​(int index) 返回此列表中指定位置的元素。
int size() 返回此列表中的元素數。

實例演示:

  1. 定義一個標準類:學生類
/**
 * 標準類:學生類
 * 屬性:name,age
 */
public class Student {
    private String name;
    private int age;
    public Student() {
    }
    public Student(String name, int age) {
        this.name = name;
        this.age = age;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public int getAge() {
        return age;
    }
    public void setAge(int age) {
        this.age = age;
    }
    @Override
    public String toString() {
        return "Student{" +
                "name='" + name + '\'' +
                ", age=" + age +
                '}';
    }
}
  1. 定義測試類
import java.util.ArrayList;
import java.util.List;
/**
 * 演示List操作
 */
public class Test {
    public static void main(String[] args) {
        //創建集合對象和學生對象
        List list = new ArrayList();
        Student s1 = new Student("劉備", 40);
        Student s2 = new Student("劉備", 40);
        Student s3 = new Student("關羽", 39);
        Student s4 = new Student("張飛", 37);
        //添加到集合
        list.add(s1);
        list.add(s2);
        list.add(s3);
        list.add(s4);
        //直接打印集合
        System.out.println(list);
        System.out.println("----------------------分割線---------------------");
        //獲取索引爲2的元素
        Object obj = list.get(2);
        System.out.println(obj);
        //獲取集合中的元素個數
        System.out.println("集合長度爲:" + list.size());
        System.out.println("----------------------分割線---------------------");
        //遍歷集合
        for (int i = 0; i < list.size(); i++) {
            Object obj2 = list.get(i);
            System.out.println("索引爲 " + i + " 的元素時" + obj2);
        }
    }
}

運行結果:

[Student{name='劉備', age=40}, Student{name='劉備', age=40}, Student{name='關羽', age=39}, Student{name='張飛', age=37}]
----------------------分割線---------------------
Student{name='關羽', age=39}
集合長度爲:4
----------------------分割線---------------------
索引爲 0 的元素時Student{name='劉備', age=40}
索引爲 1 的元素時Student{name='劉備', age=40}
索引爲 2 的元素時Student{name='關羽', age=39}
索引爲 3 的元素時Student{name='張飛', age=37}


7. Set 接口

  Set 具有與 Collection 完全一樣的接口,只是行爲上不同,Set 不保存重複的元素。

  Set 接口存儲一組唯一,無序的對象。

Set 接口的 API 介紹

案例演示:

  1. 在上面Student類的基礎上加上equals()和hashCode()兩個方法
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Student student = (Student) o;
        return age == student.age &&
                Objects.equals(name, student.name);
    }

    @Override
    public int hashCode() {
        return Objects.hash(name, age);
    }
  1. 編寫定義測試類
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;

/**
 * Set集合演示
 */
public class Test {
    public static void main(String[] args) {
        //創建集合對象
        Set<Student> set = new HashSet<>();
        //創建元素對象
        Student s1 = new Student("趙雲",20);
        Student s2 = new Student("關羽",26);
        Student s3 = new Student("張飛",24);
        Student s4 = new Student("馬超",23);
        Student s5 = new Student("黃忠",28);
        Student s6 = new Student("黃忠",28);

        //添加
        set.add(s1);
        set.add(s2);
        set.add(s3);
        set.add(s4);
        set.add(s5);
        set.add(s6);

        //打印整個集合
        System.out.println(set);
        /**
         * Set集合保證元素的唯一性依賴:equals()和hashCode()兩個方法
         * 需要在Student中重寫這兩個方法
         */
        System.out.println("通過迭代器遍歷集合:");
        Iterator<Student> it = set.iterator();
        //判斷迭代器中是否有元素
        while(it.hasNext()){
            Student s = it.next();
            System.out.println(s);
        }
        System.out.println("----------------------分割線-----------------------");
        System.out.println("通過增強for遍歷集合:");
        for (Student student : set) {
            System.out.println(student);
        }
    }
}
[Student{name='關羽', age=26}, Student{name='趙雲', age=20}, Student{name='馬超', age=23}, Student{name='張飛', age=24}, Student{name='黃忠', age=28}]
----------------------分割線-----------------------
通過迭代器遍歷集合:
Student{name='關羽', age=26}
Student{name='趙雲', age=20}
Student{name='馬超', age=23}
Student{name='張飛', age=24}
Student{name='黃忠', age=28}
----------------------分割線-----------------------
通過增強for遍歷集合:
Student{name='關羽', age=26}
Student{name='趙雲', age=20}
Student{name='馬超', age=23}
Student{name='張飛', age=24}
Student{name='黃忠', age=28}

注意:

  • Set 保證元素的唯一性依賴於 equals() 和 hashCode() 兩個方法。
  • Set 的成員方法與List相同。


8. Map 接口

  Map 接口存儲一組鍵值對象,將鍵映射到值的對象。映射不能包含重複的鍵;每個鍵最多可以映射到一個值。

Map 集合的 API介紹

應用:

Map<T1,T2> map = new HashMap<>();

泛型參數:

  • T1表示鍵的類型
  • T2表示值的類型


8.1 常用方法

方法名 描述
V put​(K key, V value) 向集合中添加鍵值對元素,第一次添加,返回null對象,如果添加的鍵已存在,會用新值覆蓋舊值,並返回舊值對象
V get​(Object key) 返回指定鍵所映射的值。
Set keySet() 獲取所有鍵的集合。

應用演示:

import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

/**
 * 演示 Map 集合
 */
public class Test {
    public static void main(String[] args) {
        //1.創建集合對象,鍵爲int型,值爲Student對象。
        Map<Integer, Student> map = new HashMap<>();
        //2.創建元素對象
        Student s1 = new Student("劉備", 44);
        Student s2 = new Student("關羽", 43);
        Student s3 = new Student("張飛", 42);
        /**
         * put()方法演示
         * 對應鍵插值
         */
        Student stu1 = map.put(1, s1);
        System.out.println("第一次添加:" + stu1);
        Student stu2 = map.put(1, s2);
        System.out.println("第二次添加,同鍵異值:" + stu2);
        Student stu3 = map.put(1, s2);
        System.out.println("第三次添加,同鍵同值:" + stu3);
        System.out.println("-----------------------分割線------------------------");
        /**
         * get()方法演示:根據鍵取值
         */
        map.put(1, s1);
        map.put(2, s2);
        map.put(3, s3);
        Student stu4 = map.get(1);
        Student stu5 = map.get(2);
        Student stu6 = map.get(3);
        System.out.println(stu4);
        System.out.println(stu5);
        System.out.println(stu6);
        System.out.println("-----------------------分割線------------------------");
        /**
         * 遍歷集合
         * 迭代器,增強for
         */

        //4 迭代器
        //4.1 獲取所有鍵的集合,keySet()
        Set<Integer> keys = map.keySet();
        //4.2 遍歷所有鍵,獲取到每一個鍵。
        Iterator<Integer> it = keys.iterator();   //創建迭代器對象
        while (it.hasNext()) {
            //4.3 獲取迭代器中的鍵
            Integer key = it.next();
            //4.4 根據鍵,獲取映射的值。
            Student value = map.get(key);
            //4.5 打印
            System.out.println("key:" + key + "...value:" + value);
        }
        System.out.println("-----------------------分割線------------------------");

        //增強for
        //獲取所有鍵
        Set<Integer> keys2 = map.keySet();
        for (Integer key : keys2) {
            //獲取所有鍵映射的值
            Student value = map.get(key);
            System.out.println("key:" + key + "...value:" + value);
        }
    }
}

運行結果:

第一次添加:null
第二次添加,同鍵異值:Student{name='劉備', age=44}
第三次添加,同鍵同值:Student{name='關羽', age=43}
-----------------------分割線------------------------
Student{name='劉備', age=44}
Student{name='關羽', age=43}
Student{name='張飛', age=42}
-----------------------分割線------------------------
key:1...value:Student{name='劉備', age=44}
key:2...value:Student{name='關羽', age=43}
key:3...value:Student{name='張飛', age=42}
-----------------------分割線------------------------
key:1...value:Student{name='劉備', age=44}
key:2...value:Student{name='關羽', age=43}
key:3...value:Student{name='張飛', age=42}
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章