List集合、Set集合、Collections類、java數據結構、集合框架【學習筆記】

一、數據結構
1.棧結構
特點:先進後出
棧內存:先進後出。主方法最先壓棧,剩餘的方法隨着調用就會不斷的進棧。當執行完畢時,立即從棧內存消失
堆內存:當new對象的時候,對象纔出現。當這個對象沒有任何引用的時候,會變成垃圾。由垃圾回收器不定時的回收
棧結構只能操作一端,不是運算受限的線性表

2.隊列結構
    特點:先進先出
    舉例:排隊
    運算受限的線性表
    能對首尾進行操作
    LinkedList中的addFrist()和addLast()可以模擬出隊列

3.數組結構
    特點:
        查詢快:數組是一塊連續的內存空間。而且有對應的索引。通過索引快速的定位到要查找的內容
        增刪慢:數組的長度是固定的,如果要對元素進行增刪。則需要創建新數組來完成

4.鏈表結構
    數據結構層面特點:
        查詢慢:鏈表的地址不是連續的,查詢的時候需要一個一個的進行查找
        增刪快:每個元素都會記錄上一個元素的地址值(雙向的是互相記錄地址)。如果想刪除或增加一個元素,其他的元素不需要變動,只需要將對應的記錄更改即可
    LinkedList集合:
        此集合也是有索引的。有索引但是查詢慢的原因如下:
        我們傳入一個要查詢的索引,底層先會做一個判斷。
         結果1:如果傳入的索引要是比集合長度的中間值索引要小,從前向後查找。而且是一個一個的找
         結果2:如果傳入的索引要是比集合長度的中間值索引要大,從後向前查找。而且是一個一個的找

    總結:
        如果查詢多,優先使用ArrayList
        如果增刪多,優先使用LinkedList
        如果不確定,優先使用ArrayList

5.樹結構
    圖解略~

二、List
1.List特點
有索引、可以存儲重複元素、存取有序
ArrayList:底層是數組實現,查詢快、增刪慢。
|–ArrayList集合底層是數組結構,第一個數組是長度爲10,如果添加的元素超過10,那麼下一個就會
以1.5倍的速度去創建一個新的集合,再使用Arrays.copyOfRange(Object []original,start,end) 不包含end

               /*
                    //這就屬於多態   只能用List接口裏面的方法
                    List<String> list = new ArrayList<>();
                    //欲想使用ArrayList集合中的trimToSzie()方法,那麼就不許轉型    
                    // 這僅僅是爲了演示一下多態的轉型概念
                    ArrayList<String> arr = (ArrayList<String>) list;
                    arr.trimToSize();   //這時候就可以使用這個方法了
               */
    LinkedList:底層是鏈表實現,查詢慢、增刪快。
        |--可以對首尾進行操作(添加或者刪除操作)比add(int index,E element) 和 remove(int index)
           方法的效率要稍微高那麼一點點,因爲他在進行添加刪除操作的時候不用去通過下標去查找
2.常用方法
    void add(int index,E e);         向集合中指定索引位置去添加元素
    E get(int index);                獲取指定索引處的元素
    E remove(int index);             刪除指定索引上的元素
    E set(int index,E e);        修改指定索引上的元素
3.示例代碼:
public class Demo01List {
            public static void main(String[] args) {
                //創建一個List集合對象,多態
                List<String> list = new ArrayList<>();
                //使用add方法往集合中添加元素
                list.add("a");
                list.add("b");
                list.add("c");
                list.add("d");
                list.add("a");
                //打印集合
                System.out.println(list);//[a, b, c, d, a]  不是地址重寫了toString

                //public void add(int index, E element): 將指定的元素,添加到該集合中的指定位置上。
                //在c和d之間添加一個itheima
                list.add(3,"itheima");//[a, b, c, itheima, d, a]
                System.out.println(list);

                //public E remove(int index): 移除列表中指定位置的元素, 返回的是被移除的元素。
                //移除元素
                String removeE = list.remove(2);
                System.out.println("被移除的元素:"+removeE);//被移除的元素:c
                System.out.println(list);//[a, b, itheima, d, a]

                //public E set(int index, E element):用指定元素替換集合中指定位置的元素,返回值的更新前的元素。
                //把最後一個a,替換爲A
                String setE = list.set(4, "A");
                System.out.println("被替換的元素:"+setE);//被替換的元素:a
                System.out.println(list);//[a, b, itheima, d, A]
            }
        }
4.LinkedList集合
        特有方法:
            java.util.LinkedList集合 implements List接口
            LinkedList集合的特點:
                1.底層是一個鏈表結構:查詢慢,增刪快
                2.裏邊包含了大量操作首尾元素的方法
                注意:使用LinkedList集合特有的方法,不能使用多態

                void addFirst(E e):將指定元素插入此列表的開頭。
                void addLast(E e):將指定元素添加到此列表的結尾。
                void push(E e):將元素推入此列表所表示的堆棧。

                E getFirst():返回此列表的第一個元素。
                E getLast():返回此列表的最後一個元素。

                E removeFirst():移除並返回此列表的第一個元素。
                E removeLast():移除並返回此列表的最後一個元素。
                E pop():從此列表所表示的堆棧處彈出一個元素。

                boolean isEmpty():如果列表不包含元素,則返回truepublic class Demo02LinkedList {
            public static void main(String[] args) {
                show03();
            }

            /*
                - public E removeFirst():移除並返回此列表的第一個元素。
                - public E removeLast():移除並返回此列表的最後一個元素。
                - public E pop():從此列表所表示的堆棧處彈出一個元素。此方法相當於 removeFirst
             */
            private static void show03() {
                //創建LinkedList集合對象
                LinkedList<String> linked = new LinkedList<>();
                //使用add方法往集合中添加元素
                linked.add("a");
                linked.add("b");
                linked.add("c");
                System.out.println(linked);//[a, b, c]

                //String first = linked.removeFirst();
                String first = linked.pop();
                System.out.println("被移除的第一個元素:"+first);
                String last = linked.removeLast();
                System.out.println("被移除的最後一個元素:"+last);
                System.out.println(linked);//[b]
            }

            /*
                - public E getFirst():返回此列表的第一個元素。
                - public E getLast():返回此列表的最後一個元素。
             */
            private static void show02() {
                //創建LinkedList集合對象
                LinkedList<String> linked = new LinkedList<>();
                //使用add方法往集合中添加元素
                linked.add("a");
                linked.add("b");
                linked.add("c");

                //linked.clear();//清空集合中的元素 在獲取集合中的元素會拋出NoSuchElementException

                //public boolean isEmpty():如果列表不包含元素,則返回true。
                if(!linked.isEmpty()){
                    String first = linked.getFirst();
                    System.out.println(first);//a
                    String last = linked.getLast();
                    System.out.println(last);//c
                }
            }

            /*
                - public void addFirst(E e):將指定元素插入此列表的開頭。
                - public void addLast(E e):將指定元素添加到此列表的結尾。
                - public void push(E e):將元素推入此列表所表示的堆棧。此方法等效於 addFirst(E)。
             */
            private static void show01() {
                //創建LinkedList集合對象
                LinkedList<String> linked = new LinkedList<>();
                //使用add方法往集合中添加元素
                linked.add("a");
                linked.add("b");
                linked.add("c");
                System.out.println(linked);//[a, b, c]

                //public void addFirst(E e):將指定元素插入此列表的開頭。
                //linked.addFirst("www");
                linked.push("www");
                System.out.println(linked);//[www, a, b, c]

                //public void addLast(E e):將指定元素添加到此列表的結尾。此方法等效於 add()
                linked.addLast("com");
                System.out.println(linked);//[www, a, b, c, com]
            }
        }
5.Vector集合
    ArrayList和Vector集合的區別
        相同點:底層都是數組實現的
        不同點:ArrayList是JDK1.2版本出現的。Vector是JDK1.0版本出現的
                ArrayList是線程不安全的,效率較高,但是數據不安全
                Vector是線程安全的,效率較低,但是數據安全
    示例代碼:
    public class Demo01 {
                public static void main(String[] args) {
                    Vector<String> v = new Vector<>();
                    v.addElement("abc");
                    v.addElement("bcd");
                    v.addElement("def");

                    for (String s : v) {
                        System.out.println(s);
                    }

                    System.out.println("================");

                    Iterator<String> it = v.iterator();
                    while(it.hasNext()) {
                        System.out.println(it.next());
                    }

                    System.out.println("================");

                    Enumeration<String> e = v.elements();
                    while(e.hasMoreElements()) {
                        System.out.println(e.nextElement());
                    }

                }
            }

三、Set
1.Set集合特點
無索引、不能存儲重複元素、存取無序
HashSet:底層是哈希算法(紅黑樹),無索引、不能存儲重複元素、存取無序
LinkedHashSet:底層是哈希算法+鏈表雙實現,無索引、不能存儲重複元素。可以保證存取順序
|–LinkedHashSet是有序的

    注意事項:
    ???Set集合遍歷的時候不能使用for循環(因爲沒有下標,無法對其遍歷)
        |--增強for循環
        |--迭代器

    ???紅黑樹(平衡二叉樹/排序樹)查詢速度相當快  -->桶結構存儲
2.示例代碼:
public class Demo01Set {
            public static void main(String[] args) {
                Set<Integer> set = new HashSet<>();
                //使用add方法往集合中添加元素
                set.add(1);
                set.add(3);
                set.add(2);
                set.add(1);
                //使用迭代器遍歷set集合
                Iterator<Integer> it = set.iterator();
                while (it.hasNext()){
                    Integer n = it.next();
                    System.out.println(n);//1,2,3    無序,沒有重複的
                }
                //使用增強for遍歷set集合
                System.out.println("-----------------");
                for (Integer i : set) {
                    System.out.println(i);
                }
            }
        }
3.Set集合不重複的原理
    第一種情況:哈希值不同,直接存儲
    第二種情況:哈希值相同,但是equals方法不同。以桶結構存儲
    第三種情況:哈希值相同,但是equals方法也相同。不存儲了

4.HashSet存儲自定義類型數據
    此類實現 Set 接口,由哈希表(實際上是一個 HashMap 實例)支持。
    它不保證 set 的迭代順序;特別是它不保證該順序恆久不變。此類允許使用 null 元素。
    //Person類
        public class Person {
            private String name;
            private int age;

            public Person() {
            }

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

            @Override
            public boolean equals(Object o) {
                if (this == o) return true;
                if (o == null || getClass() != o.getClass()) return false;
                Person person = (Person) o;
                return age == person.age &&
                        Objects.equals(name, person.name);
            }

            @Override
            public int hashCode() {
                return Objects.hash(name, age);
            }

            @Override
            public String toString() {
                return "Person{" +
                        "name='" + name + '\'' +
                        ", 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;
            }
        }


        //測試類
        public class Demo03HashSetSavePerson {
            public static void main(String[] args) {
                //創建HashSet集合存儲Person
                HashSet<Person> set = new HashSet<>();
                Person p1 = new Person("小美女",18);
                Person p2 = new Person("小美女",18);
                Person p3 = new Person("小美女",19);

                set.add(p1);
                set.add(p2);
                set.add(p3);

                System.out.println(set);
            }
        }
5.LinkedHashSet集合的使用
    public class Demo04LinkedHashSet {
            public static void main(String[] args) {
                HashSet<String> set = new HashSet<>();
                set.add("www");
                set.add("abc");
                set.add("abc");
                set.add("itcast");
                System.out.println(set);//[abc, www, itcast] 無序,不允許重複

                LinkedHashSet<String> linked = new LinkedHashSet<>();
                linked.add("www");
                linked.add("abc");
                linked.add("abc");
                linked.add("itcast");
                System.out.println(linked);//[www, abc, itcast] 有序,不允許重複
            }
        }

四、可變參數
1.定義格式
數據類型…變量名

2.注意事項
    一個方法的參數中只能有一個可變參數
    如果有多個參數,可變參數必須放在最後一個

3.示例代碼
        public class Demo01VarArgs {
            public static void main(String[] args) {
                //int i = add();
                //int i = add(10);
                int i = add(10,20);
                //int i = add(10,20,30,40,50,60,70,80,90,100);
                System.out.println(i);

                method("abc",5.5,10,1,2,3,4);
            }

            /*
                可變參數的注意事項
                    1.一個方法的參數列表,只能有一個可變參數
                    2.如果方法的參數有多個,那麼可變參數必須寫在參數列表的末尾
             */
            /*public static void method(int...a,String...b){

            }*/

            /*public static void method(String b,double c,int d,int...a){
            }*/

            //可變參數的特殊(終極)寫法
            public static void method(Object...obj){

            }

            /*
                定義計算(0-n)整數和的方法
                已知:計算整數的和,數據類型已經確定int
                但是參數的個數不確定,不知道要計算幾個整數的和,就可以使用可變參數
                add(); 就會創建一個長度爲0的數組, new int[0]
                add(10); 就會創建一個長度爲1的數組,存儲傳遞來過的參數 new int[]{10};
                add(10,20); 就會創建一個長度爲2的數組,存儲傳遞來過的參數 new int[]{10,20};
                add(10,20,30,40,50,60,70,80,90,100); 就會創建一個長度爲2的數組,存儲傳遞來過的參數 new int[]{10,20,30,40,50,60,70,80,90,100};
             */
            public static int add(int...arr){
                //System.out.println(arr);//[I@2ac1fdc4 底層是一個數組
                //System.out.println(arr.length);//0,1,2,10
                //定義一個初始化的變量,記錄累加求和
                int sum = 0;
                //遍歷數組,獲取數組中的每一個元素
                for (int i : arr) {
                    //累加求和
                    sum += i;
                }
                //把求和結果返回
                return sum;
            }
        }

五、集合的工具類
1.Collections工具類
- public static boolean addAll(Collection c, T… elements):往集合中添加一些元素。
- public static void shuffle(List

            public class Demo01Collections {
                public static void main(String[] args) {
                    ArrayList<String> list = new ArrayList<>();

                    //public static <T> boolean addAll(Collection<T> c, T... elements):往集合中添加一些元素。
                    Collections.addAll(list,"a","b","c","d","e");

                    System.out.println(list);//[a, b, c, d, e]

                    //public static void shuffle(List<?> list) 打亂順序:打亂集合順序。
                    Collections.shuffle(list);
                    System.out.println(list);//[b, d, c, a, e], [b, d, c, a, e]
                }
            }
    - public static <T> void sort(List<T> list):將集合中元素按照默認規則排序。
    示例代碼:
    //Person類
            public class Person implements Comparable<Person>{
                private String name;
                private int age;

                public Person() {
                }

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

                @Override
                public String toString() {
                    return "Person{" +
                            "name='" + name + '\'' +
                            ", 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 int compareTo(Person o) {
                    //return 0;//認爲元素都是相同的
                    //自定義比較的規則,比較兩個人的年齡(this,參數Person)
                    //return this.getAge() - o.getAge();//年齡升序排序
                    return o.getAge() - this.getAge();//年齡降序排序
                }
            }

            //測試類
            public class Demo02Sort {
                public static void main(String[] args) {
                    ArrayList<Integer> list01 = new ArrayList<>();
                    list01.add(1);
                    list01.add(3);
                    list01.add(2);
                    System.out.println(list01);//[1, 3, 2]

                    //public static <T> void sort(List<T> list):將集合中元素按照默認規則排序。
                    Collections.sort(list01);//默認是升序

                    System.out.println(list01);//[1, 2, 3]

                    ArrayList<String> list02 = new ArrayList<>();
                    list02.add("a");
                    list02.add("c");
                    list02.add("b");
                    System.out.println(list02);//[a, c, b]

                    Collections.sort(list02);
                    System.out.println(list02);//[a, b, c]

                    ArrayList<Person> list03 = new ArrayList<>();
                    list03.add(new Person("張三",18));
                    list03.add(new Person("李四",20));
                    list03.add(new Person("王五",15));
                    System.out.println(list03);//[Person{name='張三', age=18}, Person{name='李四', age=20}, Person{name='王五', age=15}]

                    Collections.sort(list03);
                    System.out.println(list03);
                }
            }
    - public static <T> void sort(List<T> list,Comparator<? super T> ):將集合中元素按照指定規則排序。
    示例代碼:
        //學生類
            public class Student {
                private String name;
                private int age;
                private int score;

                public Student() {
                }

                public Student(String name, int age, int score) {
                    this.name = name;
                    this.age = age;
                    this.score = score;
                }

                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;
                }

                public int getScore() {
                    return score;
                }

                public void setScore(int score) {
                    this.score = score;
                }

                @Override
                public String toString() {
                    return "Student{" +
                            "name='" + name + '\'' +
                            ", age=" + age +
                            ", score=" + score +
                            '}';
                }
            }

            //測試類
            public class Test02 {
                public static void main(String[] args) {
                    ArrayList<Student> list = new ArrayList<>();

                    Student s1 = new Student("張三",23,88);
                    Student s2 = new Student("李四",22,85);
                    Student s3 = new Student("王五",25,95);
                    Student s4 = new Student("趙六",22,87);

                    list.add(s1);
                    list.add(s2);
                    list.add(s3);
                    list.add(s4);

                    System.out.println(list);

                    //按照年齡的升序爲主要條件
                    //如果年齡一樣的情況,再按照成績的降序排序
                    Collections.sort(list, new Comparator<Student>() {
                        @Override
                        public int compare(Student s1, Student s2) {
                            int result = s1.getAge() - s2.getAge(); // 按照年齡的升序排序
                            //如果年齡相同,再按照成績的降序排序
                            return (result == 0) ? s2.getScore() - s1.getScore() : result;
                        }
                    });



                    //按照年齡的升序排序
                    // [Student{name='李四', age=22, score=85}, Student{name='趙六', age=22, score=87}, Student{name='張三', age=23, score=88}, Student{name='王五', age=25, score=95}]
                    /*Collections.sort(list, new Comparator<Student>() {
                        @Override
                        public int compare(Student s1, Student s2) {
                            int result = s1.getAge() - s2.getAge();
                            return result;
                        }
                    });*/

                    System.out.println(list);
                }
            }

            補充:
                /*下面我想對一個ArrayList集合進行降序排序(本來默認的都是升序排序)*/
                    ArrayList<Integer> list =  new ArrayList<>();
                    list.add(1);
                    list.add(5);
                    list.add(3);
                    list.add(7);
                    list.add(4);
                    Collections.sort(list, new Comparator<Integer>() {
                        @Override
                        public int compare(Integer o1, Integer o2) {
                            return o2 - o1;    //重寫之後的方法進行的是降序排序
                        }
                    });
                    System.out.println(list);
2.補充的工具類方法
    public class Demo04 {
            public static void main(String[] args) {
                ArrayList<String> list = new ArrayList<>();
                list.add("aa");
                list.add("bb");
                list.add("cc");
                list.add("dd");
                list.add("ee");


                //int binarySearch(List list, T key)    使用二分查找法獲取元素在集合中出現的索引位置   如果查找的元素不存在,則返回此元素的-插入點-1
                int index = Collections.binarySearch(list,"cc");
                System.out.println(index);

                //boolean replaceAll(List<T> list, T oldVal, T newVal)   使用新元素對集合中的老元素進行替換
                Collections.replaceAll(list,"dd","kk");
                System.out.println(list);

                //void reverse(List<?> list)            反轉集合
                Collections.reverse(list);

                System.out.println(list);

                //void swap(List<?> list, int i, int j) 將兩個索引位置上的元素交換
                Collections.swap(list,0,1);

                System.out.println(list);


                //void copy(List dest, List src)        將源集合複製到目標集合中.目標集合長度必須大於等於源集合的長度
               /* ArrayList<String> dest = new ArrayList<>();
                dest.add("a");
                dest.add("b");
                dest.add("c");
                dest.add("d");
                dest.add("e");
                dest.add("f");

                Collections.copy(dest,list);

                System.out.println(dest);*/
            }
        }
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章