集合:容器,用一個對象管理多個對象;
  集合VS 數組
  數組:不能自動增長;只能存放同類型的元素
  集合:能自動擴容;部分集合允許存放不同類型的元素;

Collection:父接口;

  Set:接口 ---一個實現類: HashSet
  List:接口---三個實現類: LinkedList,Vector,ArrayList
  SortedSet:接口---實現類:TreeSet

List:有序列表,允許存放重復的元素;
  實現類:
    ArrayList:數組實現,查詢快,增刪慢,線程不安全,輕量級;下標也是從0開始;
    LinkedList:鏈表實現,增刪快,查詢慢
    Vector:數組實現,線程安全,重量級
Set: 無序集合,不允許存放重復的元素;
  實現類
    HashSet:equals返回true,hashCode返回相同的整數;哈希表;
    SortedSet:對Set排序
  實現類
    TreeSet:二叉樹實現的;

 Iterator:接口,迭代器;java.util;hasNext();next();remove();
 Iterable:可迭代的,訪問的 ;java.lang;實現了可迭代的接口就可以用迭代的方式訪問;
         只需實現 iterator();方法即可;Iterator iterator();

 模擬:
  class ArrayList{
 Iterator  iterator(){
  return new Iterator(){
   public boolean hasNext(){}
   public Object next(){}
   ...
  };
 }
  }

三種循環的訪問方式:
  for(int i=0;i<list.size();i++){
   System.out.println(list.get(i));
  }
  Iterator it=list.iterator();
  while(it.hasNext()){
   System.out.println(it.next());
  }
  for--each 循環:
  for(Object obj:list){
   System.out.println(obj);
  }
      只有實現了Iterable接口的才能用第三種;能用第二種的也一定能用第三種;
     
      數組:優:訪問快,操作效率高,
            缺:插入刪除效率低,長度不能變;
      鏈表:跟數組相反

      ArrayList:自動擴容,是數組照搬過來的;
========
HashSet:
========
      構造方法:
 HashSet(int initialCapacity)
      通過Hash散列存儲;希望元素均勻的分布在存儲空間內;
      Hash散列擴容并不是所有的空間都放滿才申請新的空間;一般是75%的容量后就去擴容;
      可以自己指定;10%就去擴容,保證了效率,浪費了空間;
    
      Set放進去的順序和取出來的順序不一致;不允許有重復的元素;覆蓋hashcode()方法;
      Iterator it=set.iterator();
  while(it.hasNext()){
   System.out.println(it.next());
  }
      for(Object o:set){
  System.out.println(o);
  }
=================
ArrayList/LinkedList
=================
   1、 用List實現一個棧;
   2、 set是怎么實現的?
       set.add("hello"); hash函數運算,()%16 -----0~15之間的值;
       obj.hashcode();//Object對象的

   HashSet,放到Hash散列里,有輸入: 得到哈希碼,obj.hashcode(),對16求余,有輸出,放到相應的位置;
   如果發生沖突,先判斷要加進去的對象的equals(已經放進去的對象);是否相等;
   如果obj1.equals(obj2)=true;那么舍棄obj2;
   否則,調用沖突處理機制,將obj2放到另外一個位置;
  
   兩個Student對象的equals 相等;但是哈希碼不相等,所以沒有覆蓋;
  
   hs.add(obj);--->obj.hashcode();得到哈希碼--->做運算得到下標--->看是否沖突:如果不沖突直接加
   ----> 如果沖突,調用equals方法,如果返回真,那么不加obj,否則找某個空位加進來;    
  
   Object里的hashcode()方法默認返回的是兩個對象的地址;  
   String 類覆蓋了hashcode()方法,人為制造沖突,它認為相同的串返回相同的hashcode;

   只有要放到hash散列時才用到hashcode方法;
   放到set里能保證對象不重復,自定義類要 覆蓋hashcode方法;
   覆蓋hashcode方法原則:
       1)、一定要讓那些我們認為相同的對象返回相同的hashcode值;equals()相等;
 public int hashcode(){ return 1; } //能達到要求,意味著把取舍權利完全交給equals;
 能達到效果,但是效率太低;
       2)、考慮效率,盡量讓那些我們認為不相同的對象返回不同的hashcode值;
        public int hashcode(){ return this.name.hashcode()+this.age; }
        //只有name和age都相等才會返回相同的哈希碼;避免了不必要的沖突;
        減少了通過equals比較的次數,提高了效率;
       3)、盡量的讓對象的hashcode值散列開;即隨機分布,均勻分布;
           this.age+this.id;//并沒有散列開;21~140
         用屬性(如果是整數直接用,否則取屬性的hashcode())做 ^ 異或;相同為0,不同為1;比21~140范圍要大;

       toString方法默認返回的是 類名@地址 (如果覆蓋了hashcode方法,那么輸出的是hashcode方法的返回值)
       day07.Student@1;


   注:只覆蓋hashcode不覆蓋equals是無意義的;發生沖突后,
   比equals時比的仍然是地址;hashcode是為hash散列服務的;
       只覆蓋equals我們要比較的是兩個對象是否相等;并不放到hash散列中去;

===============
SortedSet:TreeSet
===============
   有序:加載的順序跟放的順序一致
   無序:加載的順序跟放的順序不一致

   排好序:按照集合中值的大小排列;不需要手工寫排序的代碼;
   原則:
 
    1) 往TreeSet:中放的對象必須是同類型的;
    2) 能夠比較大小;定義比較規則;TreeSet 自己有比較的方法;
    java.lang.Comparable //可比較的;
        int compareTo(T o) //小的話返回負整數,相等返回0;大的話返回正整數;

 public int compareTo(Object o){
            Student s=(Student)o;
            return this.age-s.age;
        }
    TreeSet中不允許出現CompareTo結果為0的兩個對象;
    String 覆蓋了CompareTo方法,是 按字典順序排列的;
   
    Comparetor :java.util包下的;
    java.lang包:
   
    Iterable:可迭代的     
    Comparable:可比較的  compareTo()方法怎么覆蓋

    java.util包:

    Iterator:迭代器
    Comparetor:比較器  
     java.util包里的;

  public class MyComparator implements Comparator{
    public int compare(Object o1,Object o2){
    Student s1=(Student)o1;
          Student s2=(Student)o2;
          return s2.getAge()-s1.getAge();//按從大到小排列;
    }
  }
    在構造TreeSet時構造進去:
    TreeSet  ts=new TreeSet(new MyComparator());
  
    如果在TreeSet中構造了比較器就用比較器的比較規則;
    如果沒有構造比較器就直接用自定義類中的CompareTo的比較規則;
=====
Map:
=====   
    HashMap:鍵值對,key不能重復,但是value可以重復;key的實現就是HashSet;value對應著放;
            HashSet 的后臺有一個HashMap;初始化后臺容量;只不過生成一個HashSet的話,系統
            只提供key的訪問;
            如果有兩個Key重復,那么會覆蓋之前的;
 
    HashTable:線程安全的
          Properties:java.util.Properties; key和value都是String類型,用來讀配置文件;
    
    兩者區別:HashMap線程不安全的,允許null作為key或value;
                     HashTable線程安全的,不允許null作為key或value;
    TreeMap: 對key排好序的Map;  key 就是TreeSet, value對應每個key;
             key要實現Comparable接口或TreeMap有自己的構造器;
    HashSet:remove(Object o)的原則看這個對象O的Hashcode和equals是否相等,并不是看是不是一個對象;
        定義一個Map; key是課程名稱,value是Integer表示選課人數;
        map.put(cou,map.get(cou)+new Integer(1));
        (int)(Math.random()*cou.length);從0到要選的課程數減-1     

本章學習方向:熟練使用API,記住常用的幾個容器及其特點
===================================
擴展:容器中裝容器
每個Collecton 都有一個addAll()方法,可以把一個集合完全裝載到另外一個集合里面:例如:
    Set set=new Set();
    List ls=new List();
    Ls.addAll(set);//把Set裝載在list里面。
====================================
面試經驗(知識點):
java.util.stack(stack即為堆棧)的父類為Vector。可是stack的父類是最不應該為Vector的。因為Vector的底層是數組,且Vector有get方法(意味著它可能訪問到并不屬于最后一個位置元素的其他元素,很不安全)。
對于堆棧和隊列只能用push類和get類。
Stack類以后不要輕易使用。
!!!實現堆棧一定要用LinkedList。
(在JAVA1.5中,collection有queue來實現隊列。)
====================================
注:HashMap底層也是用數組,HashSet底層實際上也是HashMap,HashSet類中有HashMap屬性(我們如何在API中查屬性)。HashSet實際上為(key.null)類型的HashMap。有key值而沒有value值。

正因為以上的原因,TreeSet和TreeMap的實現也有些類似的關系。
注意:TreeSet和TreeMap非常的消耗時間,因此很少使用。
我們應該熟悉各種實現類的選擇——非常體現你的功底。

HashSet VS TreeSet:HashSet非常的消耗空間,TreeSet因為有排序功能,因此資源消耗非常的高,我們應該盡量少使用,而且最好不要重復使用。
基于以上原因,我們盡可能的運用HashSet而不用TreeSet,除非必須排序。
同理:HashMap  VS  TreeMap:一般使用HashMap,排序的時候使用TreeMap。
HashMap VS Hashtable(注意在這里table的第一個字母小寫)之間的區別有些類似于ArrayList和Vector,Hashtable是重量級的組件,在考慮并發的情況,對安全性要求比較高的時候使用。

Map的運用非常的多。
==========================================
組合復用原則:
 *白盒復用和黑盒復用
      1.白盒復用:又叫繼承復用,從某種程度上說白盒復用破壞了封裝。
 例:class Zhangsw{
  public void teachCpp(){
   System.out.println("Teach Cpp");
  }
  public void chimogu(){

  }
     }
     class Xiaozr extends Zhangsw{

            }
      2.黑盒復用:又叫組合復用。
 例:class Zhangsw{
  public void teachCpp(){
   System.out.println("Teach Cpp");
  }
  public void chimogu(){
         }
     }
     class Xiaozr {
  private Zhangsw zhangsw = new Zhangsw();
  public void teachCpp(){
   zhangsw.teachCpp();
         }
     }
      3.原則:組合復用取代繼承復用。



柴油發電機
發電機
柴油機
柴油發電機
13636374743(上海)
13291526067(嘉興)