集合:容器,用一个对象管理多个对象;
  集合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(嘉兴)