JavaSEday08List、Set、數據結構和Collections

第8天_面向對象(List、Set、數據結構、Collections)
    一.數據結構
        1.什麼是數據結構
            容器中存放組織數據的一種結構
        2.常見的4+1中數據結構
            堆棧結構
                可以看作只有一端開口的容器,先進後出(FILO)
            隊列結構
                可以看成兩端開口的容器。一端進,一端出,先進先出(FIFO)
            數組結構
                在內存中是一塊連續的區域,查詢快(通過索引),增刪慢(長度固定)。(垃圾回收機制)
            鏈表結構
                在內存中可以分散,鏈表中的元素我們一般成爲節點,一般有兩個屬性,數據域和指針域
                查詢慢,增刪快
            紅黑樹結構
                查詢速度非常恐怖O(log(n))
                增刪速度包括創建時都是非常慢的            
            哈希表結構底層就是數組和鏈表,jdk8之後加入紅黑樹優化。
    二.List接口
        1.List接口的特點
            a.有序的collection(也成爲序列)。
            b.有索引
            c.元素可重複
        API的描述:
            有序的 collection(也稱爲序列)。此接口的用戶可以對列表中每個元素的插入位置進行精確地控制。用戶可以根據元素的整數索引(在列表中的位置)訪問元素,並搜索列表中的元素。

        2.List接口中常用的方法以及常用實現類
            a.擁有Collection接口中的方法和迭代器
            b.還有四個和索引相關的增刪改查方法
                public void add(int index, E e):插入元素
                public E remove(int index):根據索引刪除元素
                public E set(int index, E e):修改指定索引的元素
                public E get(int index):根據索引獲取元素
            c.List接口的實現類
                ArrayList
                LinkedList
                Vector
        3.ArrayList的數據結構以及使用
            ArrayList底層是數組結構,特點是查詢快,增刪慢!!!
            特有方法:無    
        4.LinkedList的數據結構以及使用
            LinkedList底層是鏈表結構,特點是查詢慢,增刪快!!!
            特有方法(8個):8個和首尾操作相關的方法
                public void addFirst(E e):添加首
                public void addLast(E e):添加尾

                public E removeFirst():刪除首
                public E removeLast():刪除尾

                public E getFirst():返回首
                public E getLast():返回尾                public E pop():刪除首,就是跟removeFirst一樣的
                public void push(E e):添加首,就是跟addFirst一樣的
                addFirst和removeFirst是1.2就有的,java是1.5開始火的,這兩個方法是jdk1.6之後添加的,商業需要,爲了吸引更多的開發者(別的語言中增添方法名就是push和pop)

public class TestLinkedList {
    public static void main(String[] args) {
        //1.創建一個LinkedList
        LinkedList<String> list = new LinkedList<String>();
        //2.添加首尾
        list.addLast("劉巖");
        list.addFirst("賈乃亮");
        list.addLast("蔡徐坤");
        list.addFirst("馬蓉");
        list.addLast("王寶強");
        list.addFirst("宋吉吉");
        list.addLast("李小璐");
        list.addFirst("PGOne");
        //3.打印
        //"PGOne" "宋吉吉" "馬蓉" "賈乃亮" "劉巖" "蔡徐坤" 王寶強" "李小璐"
        System.out.println(list);
        //3.刪除首尾
        String first = list.removeFirst();
        System.out.println(first);
        System.out.println(list);

        String last = list.removeLast();
        System.out.println(last);
        System.out.println(list);
        //[宋吉吉, 馬蓉, 賈乃亮, 劉巖, 蔡徐坤, 王寶強]
        //4.獲取首尾
        String first1 = list.getFirst();
        System.out.println(first1);
        System.out.println(list);

        String last1 = list.getLast();
        System.out.println(last1);
        System.out.println(list);
        //[宋吉吉, 馬蓉, 賈乃亮, 劉巖, 蔡徐坤, 王寶強]
        //5.push和pop
        list.push("666");
        System.out.println(list);

        String pop = list.pop();
        System.out.println(pop);
        System.out.println(list);
    }
}        

    三.Set接口
        1.Set接口的特點
            a.無序的(是指存的和取的順序是不一定一致的,LinkedHashSet除外,它是有序的)
            b.無索引
            c.元素唯一
        2.Set接口的常用方法以及常用子類
            a.擁有Collection接口中的方法和迭代器
            b.特有方法:無
            c.Set接口常見的實現類
                HashSet(無序)
                    LinkedHashSet(有序)
                TreeSet

        3.HashSet的數據結構以及使用
            HashSet底層採用哈希表結構
            特有方法:無

public class TestHashSet {
    public static void main(String[] args) {
        //1.創建一個HashSet
        HashSet<String> set = new HashSet<String>();
        //2.添加
        set.add("jack");
        set.add("jack");
        set.add("jack");
        set.add("rose");
        set.add("rose");
        set.add("lilei");
        set.add("hanmeimei");
        set.add("hanmeimei");
        set.add("lucy");
        set.add("lucy");
        set.add("lucy");
        System.out.println(set);
        //[lilei, hanmeimei, rose, lucy, jack]
    }
}


        

        4.哈希表結構的介紹[擴展]
            哈希表結構 = 數組(默認長度16) + 鏈表 + 紅黑樹(jdk1.8)
            i.對象的哈希值(對象的“數字指紋”)
                我們怎麼獲取到對象的哈希值?
                    只要調用對象的hashCode方法即可獲取到對象的哈希值
                Java中的地址值是假的!而是哈希值轉成了16進制而已

                Java中有沒有真正的地址值?
                    有!!!對象名中保存就是真正的地址值
                    但是我們打印不出來,因爲我們打印對象名的時候,會默認調用toString方法,屏蔽了真正的地址值,是一                    種內存保護機制,因此Java的安全性很高
                public String toString() {
                        return getClass().getName() + "@" + Integer.toHexString(hashCode());
                }//返回值爲包名.類名@hashCode的十六進制值

                不同對象的Hash值可能一樣的
                    "abc"和"acD"都是96354(hashCode方法在String類重寫了)
*************結論:哈希表結構如何保證元素的唯一性??***************
        哈希表會比較新舊元素的哈希值,以及調用equals方法,
        只有哈希值一致的情況下,並且equals返回true,才判定元素重複
*******************************************************************
        注意:桶的長度爲8,當桶中的元素超過8時,結構自動變成紅黑樹
            

        5.LinkedHashSet的數據結構以及使用
            LinkedHashSet底層採用鏈式哈希表
            特有方法:無

public class TestLinkedHashSet {
    public static void main(String[] args) {
        //1.創建一個HashSet
        LinkedHashSet<String> set = new LinkedHashSet<String>();
        //2.添加
        set.add("lucy");
        set.add("hanmeimei");
        set.add("rose");
        set.add("rose");
        set.add("rose");
        set.add("lilei");
        set.add("jack");
        System.out.println(set);
        //[lucy, hanmeimei, rose, lilei, jack]
    }
}


        練習:使用哈希表結構保存自定義類型的元素******************
******************************************************************************
    使用哈希表結構保存自定義類型時,
    爲了保證元素是唯一,需要重寫自定義類型中的hashCode和equals方法(工具自動生成)
******************************************************************************

public class Cat {
    int age;
    String name;
    public Cat() {
    }
    public Cat(int age, String name) {
        this.age = age;
        this.name = name;
    }
    @Override
    public String toString() {
        return "Cat{" +
                "age=" + age +
                ", name='" + name + '\'' +
                '}';
    }
    //爲了保證元素的唯一性,自定義類型必須重寫hashCode和equals方法
    //alt+insert
    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Cat cat = (Cat) o;
        return age == cat.age &&
                Objects.equals(name, cat.name);
    }
    @Override
    public int hashCode() {
        return Objects.hash(age, name);
    }
}


//練習:使用哈希表結構保存自定義類型的元素*********************

public class HashCodeTestDemo {
    public static void main(String[] args) {
        //1.LinkedHashSet
        LinkedHashSet<Cat> cats = new LinkedHashSet<Cat>();
        //2.保存貓
        cats.add(new Cat(1, "小貓咪"));
        cats.add(new Cat(2, "中貓咪"));
        cats.add(new Cat(3, "大貓咪"));
        cats.add(new Cat(3, "大貓咪"));
        cats.add(new Cat(4, "老貓咪"));
        cats.add(new Cat(5, "死貓咪"));
        //3.打印
        System.out.println(cats);
    }
}


        6.可變參數
            可變參數是指參數的個數可以變化
            格式:
                數據類型... 變量名
            本質:
                實際上可變參數就是數組(語法糖)
            注意:
                a.一個方法最多只能有一個可變參數
                b.如果既有可變參數,也有正常參數,正常參數要寫在可變參數的前面

public class TestDemo {
    public static void main(String[] args) {
        //調用方法
        System.out.println(getSum());
        System.out.println(getSum(1));
        System.out.println(getSum(1, 2));
        System.out.println(getSum(1, 2, 3, 4, 5, 6, 7, 8, 9,10));
    }
    //使用可變參數
    public static int getSum(int... a) {
        //數組求和
        int sum = 0;
        for (int i : a) {
            sum+=i;
        }
        return sum;
    }
}


    四.Collections
        1.Collections的介紹
            Collections是一個工具類(方法都是靜態的)
        2.常用功能方法
            public static void shuffle(List<?> list):打亂集合順序
            public static void sort(List<?> list):升序排列集合

public class CollectionsDemo01 {
    public static void main(String[] args) {
        //1.sort方法
        ArrayList<Integer> nums = new ArrayList<Integer>();
        //2.數據
        nums.add(80);
        nums.add(20);
        nums.add(70);
        nums.add(40);
        nums.add(10);
        nums.add(50);
        nums.add(100);
        nums.add(60);
        nums.add(30);
        nums.add(90);
        //3.打印
        System.out.println(nums);
        //4.排序
        Collections.sort(nums);
        //5.打印
        System.out.println(nums);
    }
}


            關於sort方法的排序規則:
                如果元素是數值類型,按照大小升序
                如果元素是字符類型,按照ASCII碼值升序
                如果元素是字符串類型,首先按照首字母的ASCII碼值升序,首字母一樣按照次字母ASCII碼值升序,依次類推
        3.擴展1:Comparator<T>比較器接口******************

public class CollectionsDemo02 {
    public static void main(String[] args) {
        //1.sort方法
        ArrayList<Integer> nums = new ArrayList<Integer>();
        //2.數據
        nums.add(80);
        nums.add(20);
        nums.add(70);
        nums.add(40);
        nums.add(10);
        nums.add(50);
        nums.add(100);
        nums.add(60);
        nums.add(30);
        nums.add(90);

        //4.排序
        Collections.sort(nums,new Comparator<Integer>(){
            //此方法稱爲比較方法
            //返回值表示
            //正數  表示前者大於後者
            //0  表示前者等於後者
            //負數 表示前者小於後者
            @Override
            public int compare(Integer o1, Integer o2) {
                //升序 前-後
//                return o1-o2;
                return o2-o1;
            }
        });
        //5.打印
        System.out.println(nums);
    }
}

4.排序練習(代碼實現)

/**
 * 使用集合保存學生對象,對集合進行排序
 */
public class CollectionsDemo03 {
    public static void main(String[] args) {
        //1.創建一個ArrayList
        ArrayList<Student> ss = new ArrayList<Student>();
        //2.添加學生
        ss.add(new Student(20,"haneimei",50));
        ss.add(new Student(10,"jack",90));
        ss.add(new Student(8,"ady",95));
        ss.add(new Student(9,"tonny",100));
        ss.add(new Student(25,"yy",30));
        //3.遍歷
        for (Student s : ss) {
            System.out.println(s);
        }
        System.out.println("===========================");
        Collections.sort(ss, new Comparator<Student>() {
            @Override
            public int compare(Student o1, Student o2) {
               //口訣:升序 前減後
                //a.按照年齡降序
//                return o2.age-o1.age;
                //b.按照分數升序
//                return o1.score-o2.score;
                //c.按照名字的長度降序
//                return o2.name.length()-o1.name.length();
                //d.按照姓名的第二個字母降序
                return o2.name.charAt(1)-o1.name.charAt(1);
            }
        });

        for (Student s : ss) {
            System.out.println(s);
        }
    }
}


總結:
    -[] 能夠說出List集合特點
            有序,有索引,可重複
    -[] 能夠說出常見的數據結構
    -[] 能夠說出常見的數據結構
    -[] 能夠說出數組結構特點
    -[] 能夠說出棧結構特點
    -[] 能夠說出隊列結構特點
    -[] 能夠說出單向鏈表結構特點
    -[] 能夠說出Set集合的特點
            無序,無索引,唯一
    -[] 能夠說出哈希表的特點
            哈希表中的元素是唯一的
            哈希表通過哈希值和equals共同保證元素的唯一性
    -[] 使用HashSet/LinkedHashSet集合存儲自定義元素
            自定義類型需要重寫hashCode和equals
    -[] 能夠使用集合工具類的常用方法
            public static void shuffle(List<?> list):打亂集合順序
            public staitc void sort(List<?> list):升序排序集合    -[] 能夠使用Comparator比較器進行排序
            

Collections.sort(集合<E>, new Comparator<E>{
                public int compare(E e1, E e2){
                    升序 前減後
                }
            });

    


        
            

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