數據結構和對應的集合

棧結構和隊列結構
        棧:
                先進後出。數組

        隊列:
                先進先出。數據結構

6.數組和鏈表
        數組:
                在內存中是一片連續的空間。
                查詢快,增刪慢。ide

                查詢快:由於能夠經過數組的地址值和索引直接定位到某個元素。
                增刪慢:由於數組不可變,每次要添加或者刪除都要建立一個新的數組。
                                把老數組中的元素賦值給新數組。源碼分析

        鏈表:
                是多個節點組成的。
                每個節點都是單獨new出來的對象,在內存中鏈表不是一個連續的空間。
                是經過互相記錄地址值實現的。學習

                單向鏈表:
                        前一個記錄後一個地址值。
                        可是後一個不會記錄前一個地址值。this

                雙向鏈表
                        也是由節點組成的。
                        前一個記錄後一個地址值。
                        後一個也會記錄前一個。
                        對象

7.ArrayList 和 LinkedList
        ArrayList : 底層是一個數組。
                                        特色:查詢快,增刪慢排序

        LinkedList : 底層是一個雙向鏈表。
                                        特色:查詢慢,增刪快索引

        總結:
                ArrayList 和 LinkedList 基本使用是如出一轍的。
                增 刪 改 查,所寫代碼幾乎同樣。
                可是在底層數據結構是不同的。接口

8.LinkedList
          void addFirst(E e)      向集合中第一個位置添加元素
      void addLast(E e)      向集合中最後一個位置添加元素
      E getFirst()                獲取集合中第一個元素
      E getLast()                獲取集合中最後一個元素
      E removeFirst()          刪除集合中第一個元素
      E removeLast()          刪除集合中最後一個元素

目前爲止:
        List集合已經所有學習完畢了

                ArrayList :此時查詢較多

                LinkedList :此時增刪較多

                Vector 是List中最爲古老的一個集合在JDK1.0的時候就出現了。
                           在JDK1.2的時候Java提出了集合理論。
                           把ArrayList全面替代了Vector

                疑問:
                        我也不知道增刪多仍是查詢多怎麼辦?
                        當你不知道用什麼的時候,請使用: ArrayList

9.單列集合的第二分支 Set

        List: 有序 有索引 能夠重複
        Set : 無序 無索引 不能夠重複

        注意點:
                當你使用到Set的時候,就不要想着他存取有序了。

10.哈希值
        問:
                1.什麼是哈希值?
                        其實就是根據"地址值"或者內部"元素的屬性值"計算出來的一個數值。

                2.何時根據地址值計算?
                        Object 中的hashCode 返回的就是根據地址值計算出來的哈希值。

                3.何時根據元素的屬性值計算?
                        在任意一個已經將hashCode進行重寫以後。
                        只要重寫了,就按照元素的屬性值進行計算,此時跟地址值就沒有任何關係了。好比: String Integer Character...

                4.若是屬性值不一樣,那麼哈希值有可能相同嗎?
                        有可能,概率比較低。

                        哈希值是一個int類型 -21億 ~ 21億 一共有42億多的值。
                        那麼如今我建立了50億個對象分別調用他的hashCode方法。
                        其中至少8億左右的對象哈希值是重複的。
        
        做用:
                通常不單獨使用。
                跟 HashSet , LinkedHashSet , HashMap 這三個集合有關。

11.HashSet集合保證元素惟一性源碼分析

        得出一個結論:
                HashSet集合保證惟一性是依賴兩個方法:
                        hashCode和equlas

12.HashSet的底層分析:
        a.HashSet底層其實依賴的是HashMap集合的鍵位置。
                        每次在存儲的時候,元素放到鍵位置,值就是一個 new Object();

        b.哈希表
                其實HashSet LinkedHashSet HashMap 這三個集合中底層一個數據結構。

          哈希表其實就是一個數組跟鏈表的結合體
          到了JDK1.8 哈希表 = 數組 + 鏈表 + 二叉樹 

總結:
        HashSet  LinkedHashSet HashMap的鍵
        在存儲元素的時候,這個類裏面必定要重寫hashCode和equals方法。

        String Integer ...Java中已經提供的這些類已經幫咱們重寫好了這兩個方法。

        "當咱們要在這些集合中存儲自定義對象時,要重寫hashCode和equals方法。"

13.LinkedHashSet
        特色:
                有序 + 不能夠重複

        ArrayList  
                        //當實在不知道用什麼的時候。
                        //查詢多,增刪少。

        LinkedList
                        //查詢少,增刪多。

        Vector//確定不用

        HashSet
                        //數據須要去重時

        LinkedHashSet
                        //數據需求去重且存取有序。

        練習1:
                鍵盤錄入3個不重複的字符串?
                HashSet<String> hs = new HashSet();
                Scanner sc = new Scanner(System.in);
                while(true){
                        if(hs.size == 3){
                                break;
                        }else{
                                String line = sc.nextLine();
                                hs.add(line);//若是已經有了,此時就存儲失敗
                                                        //若是沒有,才能存到集合中。
                        }
                }

        練習2:
                讓多個數據進行總體去重
                ArrayList<String> list = new ArrayList<>();
                list.add("a");
                list.add("a");
                list.add("a");
                list.add("a");
                list.add("a");
                list.add("a");
                list.add("a");
                list.add("a");

                //去重裏面重複的元素

                HashSet<String> hs = new HashSet();
                hs.addAll(list);//把list集合中全部的元素添加到hs裏面
                System.out.println(hs);//此時就已是去重以後的結果了。

14.TreeSet
        誤區:
                哈希表,哈希值只跟 HashSet LinkedHashSet HashMap的鍵有關
                
        TreeSet 跟哈希值,哈希表,hashCode方法,equals方法都是無關的。

        特色:
                能夠排序。//咱們得給他指定一個排序的規則,若是沒有這樣的規則,會報錯的。
                
                TreeSet<String> ts = new TreeSet<>(); //採起的是默認方式進行比較。

                TreeSet<String> ts = new TreeSet<>(比較的規則);//採起傳遞的規則進行比較。

        底層結構:
                二叉樹結構

15.TreeSet的默認比較方式。
        天然排序。

        案例:
                 TreeSet<Student> ts = new TreeSet<>();
        //如今要存誰,this就表示誰。
        //如今要跟誰比較,o就表示誰。
      ts.add(new Student("zhangsan",23,"男"));
      ts.add(new Student("lisi",24,"男"));
      ts.add(new Student("wangwu",25,"女"));

        System.out.println(ts);

                注意點,        Student類要實現接口Comparable

                  @Override
                        public int compareTo(Student o) {
                                System.out.println(this);
                                //按照年齡從大到小,年齡相同就不要。
                                int result = o.age - this.age;
                                return result;
                        }

16.比較器排序Comparator
        代碼的書寫方式跟第一種基本是同樣。

        注意點:
                1.當第一種和第二種同時存在時,聽第二種的。
                2.第二種方式何時用?
                        當咱們不知道用哪種的時候咱們使用第一種方式。
                        當第一種沒法知足的時候,會使用第二種。

        練習1:
                我要按照字符串的長度排序?
                默認使用天然排序,可是天然排序的規則是:字典順序。
                由於String是Java提供的,咱們沒法修改源代碼的。

                在這種狀況下:第一種天然排序就沒法知足我如今的要求了。
                因此此時用第二種。

總結:
        若是Java提供好的類中排序方式不能知足如今的要求,用第二種。

        自定義類可使用第一種。

         TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
          @Override
          public int compare(String o1, String o2) {
              //o1  如今要存入的元素
              //o2  已經存在的元素

              //o1和o2所表示的含義不重要,最多就是運行完畢後,修改一下先後順序就能夠了
              //重點就是比較規則的書寫。
              return o2.length() - o1.length();
          }
      });
      ts.add("b");
      ts.add("aaa");
      ts.add("aa");
      ts.add("aaaaa");
      ts.add("aaaa");

      System.out.println(ts);

練習2:
        我要按照字符串的長度排序?若是長度同樣,請按照字典順序排?

        TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {
          @Override
          public int compare(String o1, String o2) {
              int temp = o1.length() - o2.length();
              temp = temp == 0 ? o1.compareTo(o2) : temp;
              return temp;
          }
      });
      ts.add("b");
      ts.add("aaa");
      ts.add("aa");
      ts.add("aaaaa");
      ts.add("aaaa");
      ts.add("a");

      System.out.println(ts);

    }

相關文章
相關標籤/搜索