集合的介紹和使用

集合的結構圖

這裏寫圖片描述
這裏寫圖片描述

集合框架

List集合面試兩大陷阱:

1.用for循環一邊遍歷一邊刪除
刪除不乾淨:一邊遍歷一邊刪除,集合角標每次再自增1,而每次刪除一個元素後集合下標和大小size會改變,所以只可以刪除一半的元素
2.數組轉換集合
Arrays.asList–返回值是Arrays類的一個靜態內部類,而這個內部類不支持增加和修改,只能支持查看和修改

這裏寫圖片描述

Vector是同步的,線程安全
ArrayList是異步的,線程不安全

Collection是List和Set的父接口
Collections是集合的工具類

*集合中存儲的都是對象的地址

Collection分爲兩大類:List和Set
List:元素是有序的,元素可以重複,因爲該集合體繫有下標
Set:元素是無序的,元素不可以重複,因爲該集合體系沒有下標

①List又包含三種類型的數據存儲容器:ArrayList、 LinkedList 和Vector
–ArrayList:底層的數據結構使用的是數組結構,線程不同步,默認長度大小爲10,當不夠用時每次增長度的50%。
特點:查詢 速度很快,但是增刪稍慢
–LinkedList:底層使用的鏈表數據結構。特點:增刪速度很快,查詢慢
–Vector:底層使用的也是數組數據結構,線程同步。默認長度大小爲10,當不夠用時每次增長度的100%。 被ArrayList替代了
Set包含兩種數據存儲容器類型:HashSet和TreeSet

②List集合特有的迭代器。ListIterator是Iterator的子接口。在迭代時,不可以通過集合對象的方法操作集合中的元素,會發生ConcurrentModificationException異常。所以,在使用迭代器時,只能用迭代器的方法操作元素,可是Iterator方法是有限的。只有三個方法:hasNext( )判斷是否存在下一個元素、next( )取下一個元素、remove( )移除元素引用的操作,如果想要其他的操作如添加,修改等,就需要使用其子接口ListIterator,該接口中有許多Iterator接口中不存在的方法,且該接口只能通過List集合的listIterator方法獲取

Set下面的集合:

一、TreeSet(即排序,又查重):

① 比較器的實現
查重標準:比較器接口中自己定義規則
set集合中的自定義對象都要實現比較器接口Comparable(),覆寫裏面的compareTo()方法。
如果放入set集合中的類型無法在其本類中實現比較器接口,那麼要通過第三方類實現比較的功能,則在此第三方類中實現Comparator接口,並覆寫其中的compare()方法,則此時在TreeSet的參數裏面傳入實現Comparator接口的類對象

compareTo()和compare()方法中當前類對象的某個屬性大於另外一個對象的相同屬性是,return 1,如果小於的話return -1;如果相同的話return 0

實現代碼例子:

package TreeSet;

import java.util.Comparator;

public class Person {
    String name;
    int age;
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }

    @Override
    public int compareTo(Person o) {
        if(this.age > o.age){
            return 1;
        }
        if(this.age < o.age){
            return -1;
        }

        return this.name.compareTo(o.name);
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return this.name + "    " + this.age;
    }


}

二、HashSet(只查重,不排序)

hashCode是定義在Object中的方法,根據對象的地址動態計算出一個值

如果set集合中的放入的是引用數據類型,則查重標準爲:
①hashCode: 首先調用hashCode方法進行HashCode值的比較。也就是==比較,因爲hashCode方法就是和地址有關
所以調用父類的hashCode方法沒有意義,需要覆寫

②equals:如果兩個對象hashCode值一樣,調用equals,比較的是地址,所以也無意義,因爲比較地址就是比較hashCode的值。所以要對equals方法進行覆寫

總而言之,當兩個對象的hashCode值相同時,就調用equals方法再進行各項屬性之間的比較。如果hashCode值不同時,則就不再需要進行equals比較。

代碼例子:

package HashSet;

public class Person {
    String name;
    int age;
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Override
    public int hashCode() {
        int x1 =  age*31;
        int x2 = name.length()*78;
        return x1*x2;
    }
    @Override
    public boolean equals(Object obj) {
        Person p = (Person) obj;
        boolean flag1 = name.equals(p.name);
        boolean flag2 = age==p.age;
        return flag1 && flag2;
    }
    @Override
    public String toString() {
        // TODO Auto-generated method stub
        return this.name + "    " + this.age;
    }

}

Map下面的集合:(Map中鍵都不允許重複)

 Map分爲hashMap和TreeMap      

一、TreeMap(鍵不允許爲空,值可以爲空)
treeMap中鍵不允許重複

在自定義對象類中實現比較器接口Comparable或着在第三方類中實現Comparable接口,覆寫其中的comparaTo()方法進行查重和比較

二、hashMap(鍵和值都可以爲空null)
hashMap只可以實現查重,不可以實現排序,它和HashSet一樣,都是通過類對象覆寫hashCode()和equals()方法來實現通過具體的屬性進行查重。

Hashtable:底層是哈希表數據結構,不可以存入null鍵、null值。該集合時線程同步的

HashMap:底層是哈希表數據結構,允許使用bull值和null鍵,該集合是不同步的

map集合的兩種取出方式:
Map集合的取出原理:將map集合轉成set集合,再通過迭代器取出。
1.keyset:返回類型是Set。將map中的所有的鍵存入到Set集合。因爲set具備迭代器,所以可以用迭代器方式取出所有的鍵,再根據get方法,獲取每一個鍵對應的值
2.entrySet:返回類型是Set

   public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("06", "java06");
        map.put("03", "java03");

        Set<String> keySet = map.keySet();
        Iterator<String> it = keySet.iterator();
        while(it.hasNext()){
            String key = it.next();
            String value = map.get(key);
            System.out.println("Key:" + key + "  Value:" + value);
        }
    }

entrySet圖例:
這裏寫圖片描述
entrySet代碼樣例:

public static void main(String[] args) {
        Map<String, String> map = new HashMap<String, String>();
        map.put("05", "java05");
        map.put("02", "java02");

        Set<Map.Entry<String, String>> entrySet = map.entrySet();
        Iterator<Map.Entry<String, String>> it = entrySet.iterator();
        while(it.hasNext()){
            Map.Entry<String, String> me = it.next();
            String key = me.getKey();
            String value = me.getValue();
            System.out.println("key:" + key + " value:" + value);
        }
    }

Entry<K, V>是一個接口,是Map<K, V>接口中的內部接口,是用static修飾符所修飾的靜態內部接口,用來存放映射項(鍵-值對)

TreeSet、HashSet、TreeMap和HashMap的代碼實現:
主函數類:

public class Test {
    /**
     * HashMap只可以查重,不可以排序
     *        和HashSet一樣,都是需要覆寫hashCode和equals方法進行查重
     */
    public static void main(String[] args) {
        HashMap<String,Person> map = new HashMap<>();
        map.put("xx2", new Person("張三2",18));
        map.put("xx1", new Person("張三1",12));
        map.put("xx5", new Person("張三5",13));
        map.put("xx1", new Person("張三1",15));
        map.put("xx7", new Person("張三7",16));
        map.put("xx6", new Person("張三7",16));
        map.put("xx3", new Person("張三3",14));
        Set<String> key = map.keySet();
        Iterator<String> it = key.iterator();
        while(it.hasNext()){
            String k = it.next();
            Person p = map.get(k);
            System.out.println("鍵:" + k + "   學生:" + p);
        }
    }
/**
     * TreeMap:可以查重和排序
     *         在將數據放入集合中以後可以通過Set集合將map集合中的鍵存入set集合中
     *         用的是keySet方法,在通過Set的迭代器將鍵的和遍歷
     *         通過while循環取出鍵,再通過鍵在map集合中取出該鍵對應的值。
     */
    public static void main3(String[] args) {
        TreeMap<String,Person> map = new TreeMap<>();
        map.put("xx2", new Person("張三2",18));
        map.put("xx1", new Person("張三1",12));
        map.put("xx5", new Person("張三5",13));
        map.put("xx1", new Person("張三1",15));
        map.put("xx7", new Person("張三7",16));
        map.put("xx6", new Person("張三7",16));
        map.put("xx3", new Person("張三3",14));
        Set<String> key = map.keySet();
        Iterator<String> it = key.iterator();
        while(it.hasNext()){
            String k = it.next();
            Person p = map.get(k);
            System.out.println("鍵:" + k + "   學生:" + p);
        }
    }

    /**
     * HashSet集合中只可以進行查重,不可以進行排序。
     */
    public static void main2(String[] args) {
        HashSet<Person> set = new HashSet<>();
        set.add(new Person("xx2",12));
        set.add(new Person("xx6",16));
        set.add(new Person("xx9",19));
        set.add(new Person("xx3",13));
        set.add(new Person("xx2",12));
        set.add(new Person("xx1",11));
        set.add(new Person("xx3",13));
        Iterator it = set.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }

    /**
     * TreeSet:Set集合含有迭代器,可以進行集合的遍歷
     *         可以進行排序和查重
     */
    public static void main1(String[] args) {
        TreeSet<Person> set = new TreeSet<>();
        set.add(new Person("xx2",12));
        set.add(new Person("xx6",16));
        set.add(new Person("xx9",19));
        set.add(new Person("xx3",13));
        set.add(new Person("xx2",12));
        set.add(new Person("xx1",11));
        set.add(new Person("xx3",13));
        Iterator it = set.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }
    }
//對象類:
public class Person {
    String name;
    int age;
    public Person(String name, int age){
        this.name = name;
        this.age = age;
    }
    @Override
    public String toString() {
        return "name:" + name + "    age:" + age;
    }

      // HashMap只可以查重,不可以排序
      //通過覆寫hashCode和equals方法進行查重

    @Override
    public int hashCode() {
        int x1 = name.length()*78;
        int x2 = age*31;
        return x1*x2;
    }
    @Override
    public boolean equals(Object obj) {
        Person per = (Person)obj;
        boolean flag = this.name.equals(per.name);
        boolean flag1 = this.age == per.age;
        return flag && flag1;
    }

     //TreeMap:可以進行排序和查重,其中必須是鍵不相同,不同的鍵有相同的值是可以的
     //        需要實現比較器接口
     //        implements Comparable<Person>

    @Override
    public int compareTo(Person o) {
        if(this.age > o.age){
            return 1;
        }
        if(this.age < o.age){
            return -1;
        }
        else{
            return this.name.compareTo(o.name);
        }

    }


     // HashSet:只可以查重,不可以排序.
     //        通過在對象類中覆寫hashCode()和equals()方法
     //        先通過hashCode方法進行查重,不相同直接返回;
     //         相同則執行equals方法進行查重

    @Override
    public int hashCode() {
        int x1 = name.length()*78;
        int x2 = age*31;
        return x1*x2;
    }
    @Override
    public boolean equals(Object obj) {
        Person per = (Person)obj;
        boolean flag = this.name.equals(per.name);
        boolean flag1 = this.age == per.age;
        return flag && flag1;
    }


     // TreeSet:可以排序,也可以查重,通過實現Comparable接口,
     //         如果本類實現不了的話則選擇在第三方的類中實現Comparator接口
     //implements Comparable<Person>

    @Override
    public int compareTo(Person o) {
        if(this.age > o.age){
            return 1;
        }
        if(this.age < o.age){
            return -1;
        }
        else{
            return this.name.compareTo(o.name);
        }

    }




發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章