JavaSE基礎知識是附上代碼實現2

###13.01_常見對象(StringBuffer類的概述)
* A:StringBuffer類概述
    * 通過JDK提供的API,查看StringBuffer類的說明
    * 線程安全的可變字符序列 
* B:StringBuffer和String的區別
    * String是一個不可變的字符序列
    * StringBuffer是一個可變的字符序列 

###13.02_常見對象(StringBuffer類的構造方法)
* A:StringBuffer的構造方法:
    * public StringBuffer():無參構造方法
    * public StringBuffer(int capacity):指定容量的字符串緩衝區對象
    * public StringBuffer(String str):指定字符串內容的字符串緩衝區對象
* B:StringBuffer的方法:
    * public int capacity():返回當前容量。    理論值(不掌握)
    * public int length():返回長度(字符數)。 實際值
* C:案例演示
    * 構造方法和長度方法的使用

###13.03_常見對象(StringBuffer的添加功能)
* A:StringBuffer的添加功能
    * public StringBuffer append(String str):
        * 可以把任意類型數據添加到字符串緩衝區裏面,並返回字符串緩衝區本身
    * public StringBuffer insert(int offset,String str):
        * 在指定位置把任意類型的數據插入到字符串緩衝區裏面,並返回字符串緩衝區本身

###13.04_常見對象(StringBuffer的刪除功能)
* A:StringBuffer的刪除功能
    * public StringBuffer deleteCharAt(int index):
        * 刪除指定位置的字符,並返回本身
    * public StringBuffer delete(int start,int end):
        * 刪除從指定位置開始指定位置結束的內容,並返回本身

###13.05_常見對象(StringBuffer的替換和反轉功能)
* A:StringBuffer的替換功能
    * public StringBuffer replace(int start,int end,String str):
        * 從start開始到end用str替換
* B:StringBuffer的反轉功能
    * public StringBuffer reverse():
        * 字符串反轉

###13.06_常見對象(StringBuffer的截取功能及注意事項)
* A:StringBuffer的截取功能
    * public String substring(int start):
        * 從指定位置截取到末尾
    * public String substring(int start,int end):
        * 截取從指定位置開始到結束位置,包括開始位置,不包括結束位置
* B:注意事項
    * 注意:返回值類型不再是StringBuffer本身

###13.07_常見對象(StringBuffer和String的相互轉換)
* A:String -- StringBuffer
    * a:通過構造方法
    * b:通過append()方法
* B:StringBuffer -- String
    * a:通過構造方法
    * b:通過toString()方法
    * c:通過subString(0,length);

###13.08_常見對象(把數組轉成字符串)
* A:案例演示
    * 需求:把數組中的數據按照指定個格式拼接成一個字符串
    * 
            舉例:
                int[] arr = {1,2,3};    
            輸出結果:
                "[1, 2, 3]"
                
            用StringBuffer的功能實現

###13.09_常見對象(字符串反轉)
* A:案例演示

        需求:把字符串反轉
            舉例:鍵盤錄入"abc"        
            輸出結果:"cba"
            
        用StringBuffer的功能實現    

###13.10_常見對象(StringBuffer和StringBuilder的區別)
* A:StringBuilder的概述
    * 通過查看API瞭解一下StringBuilder類
* B:面試題
    * String,StringBuffer,StringBuilder的區別
    * StringBuffer和StringBuilder的區別
    * StringBuffer是jdk1.0版本的,是線程安全的,效率低
    * StringBuilder是jdk1.5版本的,是線程不安全的,效率高

    * String和StringBuffer,StringBuilder的區別
    * String是一個不可變的字符序列
    * StringBuffer,StringBuilder是可變的字符序列

###13.11_常見對象(String和StringBuffer分別作爲參數傳遞)
* A:形式參數問題
    * String作爲參數傳遞
    * StringBuffer作爲參數傳遞 
* B:案例演示
    * String和StringBuffer分別作爲參數傳遞問題

###13.12_常見對象(數組高級冒泡排序原理圖解)
* A:畫圖演示

        需求:
            數組元素:{24, 69, 80, 57, 13}
            請對數組元素進行排序。
            
            冒泡排序
                相鄰元素兩兩比較,大的往後放,第一次完畢,最大值出現在了最大索引處


###13.13_常見對象(數組高級冒泡排序代碼實現)
* A:案例演示
    * 數組高級冒泡排序代碼

###13.14_常見對象(數組高級選擇排序原理圖解)
* A:畫圖演示
    * 需求:
        * 數組元素:{24, 69, 80, 57, 13}
        * 請對數組元素進行排序。
        
        * 選擇排序
            * 從0索引開始,依次和後面元素比較,小的往前放,第一次完畢,最小值出現在了最小索引處


###13.15_常見對象(數組高級選擇排序代碼實現)
* A:案例演示
    * 數組高級選擇排序代碼

###13.16_常見對象(數組高級二分查找原理圖解)
* A:畫圖演示
    * 二分查找  
    * 前提:數組元素有序

###13.17_常見對象(數組高級二分查找代碼實現及注意事項)
* A:案例演示
    * 數組高級二分查找代碼
* B:注意事項
    * 如果數組無序,就不能使用二分查找。
        * 因爲如果你排序了,但是你排序的時候已經改變了我最原始的元素索引。

###13.18_常見對象(Arrays類的概述和方法使用)
* A:Arrays類概述
    * 針對數組進行操作的工具類。
    * 提供了排序,查找等功能。
* B:成員方法
    * public static String toString(int[] a)
    * public static void sort(int[] a)
    * public static int binarySearch(int[] a,int key)

###13.19_常見對象(基本類型包裝類的概述)
* A:爲什麼會有基本類型包裝類
    * 將基本數據類型封裝成對象的好處在於可以在對象中定義更多的功能方法操作該數據。
* B:常用操作
    * 常用的操作之一:用於基本數據類型與字符串之間的轉換。
* C:基本類型和包裝類的對應

        byte             Byte
        short            Short
        int                Integer
        long            Long
        float            Float
        double            Double
        char            Character
        boolean            Boolean

###13.20_常見對象(Integer類的概述和構造方法)
* A:Integer類概述
    * 通過JDK提供的API,查看Integer類的說明

    * Integer 類在對象中包裝了一個基本類型 int 的值,
    * 該類提供了多個方法,能在 int 類型和 String 類型之間互相轉換,
    * 還提供了處理 int 類型時非常有用的其他一些常量和方法
* B:構造方法
    * public Integer(int value)
    * public Integer(String s)
* C:案例演示
    * 使用構造方法創建對象

###13.21_常見對象(String和int類型的相互轉換)
* A:int -- String
    * a:和""進行拼接
    * b:public static String valueOf(int i)
    * c:int -- Integer -- String(Integer類的toString方法())
    * d:public static String toString(int i)(Integer類的靜態方法)
* B:String -- int
    * a:String -- Integer -- int
    * public static int parseInt(String s)

###13.22_常見對象(JDK5的新特性自動裝箱和拆箱)
* A:JDK5的新特性
    * 自動裝箱:把基本類型轉換爲包裝類類型
    * 自動拆箱:把包裝類類型轉換爲基本類型
* B:案例演示
    * JDK5的新特性自動裝箱和拆箱
    
    * Integer ii = 100;
    * ii += 200;
* C:注意事項
    * 在使用時,Integer  x = null;代碼就會出現NullPointerException。
    * 建議先判斷是否爲null,然後再使用。

###13.23_常見對象(Integer的面試題)
* A:Integer的面試題

        看程序寫結果
        
        Integer i1 = new Integer(97);
        Integer i2 = new Integer(97);
        System.out.println(i1 == i2);
        System.out.println(i1.equals(i2));
        System.out.println("-----------");
    
        Integer i3 = new Integer(197);
        Integer i4 = new Integer(197);
        System.out.println(i3 == i4);
        System.out.println(i3.equals(i4));
        System.out.println("-----------");
    
        Integer i5 = 97;
        Integer i6 = 97;
        System.out.println(i5 == i6);
        System.out.println(i5.equals(i6));
        System.out.println("-----------");
    
        Integer i7 = 197;
        Integer i8 = 197;
        System.out.println(i7 == i8);
        System.out.println(i7.equals(i8));

###13.24_day13總結
* 把今天的知識點總結一遍。

###14.01_常見對象(正則表達式的概述和簡單使用)
* A:正則表達式
    * 是指一個用來描述或者匹配一系列符合某個語法規則的字符串的單個字符串。其實就是一種規則。有自己特殊的應用。
    * 作用:比如註冊郵箱,郵箱有用戶名和密碼,一般會對其限制長度,這個限制長度的事情就是正則表達式做的
* B:案例演示
    * 需求:校驗qq號碼.
        * 1:要求必須是5-15位數字
        * 2:0不能開頭
        * 3:必須都是數字
        
    * a:非正則表達式實現
    * b:正則表達式實現

###14.02_常見對象(字符類演示)
* A:字符類
    * [abc] a、b 或 c(簡單類) 
    * [^abc] 任何字符,除了 a、b 或 c(否定) 
    * [a-zA-Z] a到 z 或 A到 Z,兩頭的字母包括在內(範圍) 
    * [0-9] 0到9的字符都包括
###14.03_常見對象(預定義字符類演示)
* A:預定義字符類
    * . 任何字符。
    * \d 數字:[0-9]
    * \w 單詞字符:[a-zA-Z_0-9]
###14.04_常見對象(數量詞)
* A:Greedy 數量詞 
    * X? X,一次或一次也沒有
    * X* X,零次或多次
    * X+ X,一次或多次
    * X{n} X,恰好 n 次 
    * X{n,} X,至少 n 次 
    * X{n,m} X,至少 n 次,但是不超過 m 次 

###14.05_常見對象(正則表達式的分割功能)
* A:正則表達式的分割功能
    * String類的功能:public String[] split(String regex)
* B:案例演示
    * 正則表達式的分割功能

###14.06_常見對象(把給定字符串中的數字排序)
* A:案例演示
    * 需求:我有如下一個字符串:”91 27 46 38 50”,請寫代碼實現最終輸出結果是:”27 38 46 50 91”

###14.07_常見對象(正則表達式的替換功能)
* A:正則表達式的替換功能
    * String類的功能:public String replaceAll(String regex,String replacement)
* B:案例演示
    * 正則表達式的替換功能

###14.08_常見對象(正則表達式的分組功能)
* A:正則表達式的分組功能
    * 捕獲組可以通過從左到右計算其開括號來編號。例如,在表達式 ((A)(B(C))) 中,存在四個這樣的組: 

        1     ((A)(B(C))) 
        2     (A 
        3     (B(C)) 
        4     (C) 
    
        組零始終代表整個表達式。
B:案例演示
    a:切割
        需求:請按照疊詞切割: "sdqqfgkkkhjppppkl";
    b:替換
        需求:我我....我...我.要...要要...要學....學學..學.編..編編.編.程.程.程..程
        將字符串還原成:“我要學編程”。
###14.09_常見對象(Pattern和Matcher的概述)
* A:Pattern和Matcher的概述
* B:模式和匹配器的典型調用順序
    * 通過JDK提供的API,查看Pattern類的說明

    * 典型的調用順序是 
    * Pattern p = Pattern.compile("a*b");
    * Matcher m = p.matcher("aaaaab");
    * boolean b = m.matches();

###14.10_常見對象(正則表達式的獲取功能)
* A:正則表達式的獲取功能
    * Pattern和Matcher的結合使用
* B:案例演示
    * 需求:把一個字符串中的手機號碼獲取出來


###14.11_常見對象(Math類概述和方法使用)
* A:Math類概述
    * Math 類包含用於執行基本數學運算的方法,如初等指數、對數、平方根和三角函數。 
* B:成員方法
    * public static int abs(int a)
    * public static double ceil(double a)
    * public static double floor(double a)
    * public static int max(int a,int b) min自學
    * public static double pow(double a,double b)
    * public static double random()
    * public static int round(float a) 參數爲double的自學
    * public static double sqrt(double a)

###14.12_常見對象(Random類的概述和方法使用)
* A:Random類的概述
    * 此類用於產生隨機數如果用相同的種子創建兩個 Random 實例,
    * 則對每個實例進行相同的方法調用序列,它們將生成並返回相同的數字序列。
* B:構造方法
    * public Random()
    * public Random(long seed)
* C:成員方法
    * public int nextInt()
    * public int nextInt(int n)(重點掌握)

###14.13_常見對象(System類的概述和方法使用)
* A:System類的概述
    * System 類包含一些有用的類字段和方法。它不能被實例化。 
* B:成員方法
    * public static void gc()
    * public static void exit(int status)
    * public static long currentTimeMillis()
    * pubiic static void arraycopy(Object src, int srcPos, Object dest, int destPos, int length) 
* C:案例演示
    * System類的成員方法使用

###14.14_常見對象(BigInteger類的概述和方法使用)
* A:BigInteger的概述
    * 可以讓超過Integer範圍內的數據進行運算
* B:構造方法
    * public BigInteger(String val)
* C:成員方法
    * public BigInteger add(BigInteger val)
    * public BigInteger subtract(BigInteger val)
    * public BigInteger multiply(BigInteger val)
    * public BigInteger divide(BigInteger val)
    * public BigInteger[] divideAndRemainder(BigInteger val)

###14.15_常見對象(BigDecimal類的概述和方法使用)
* A:BigDecimal的概述
    * 由於在運算的時候,float類型和double很容易丟失精度,演示案例。
    * 所以,爲了能精確的表示、計算浮點數,Java提供了BigDecimal

    * 不可變的、任意精度的有符號十進制數。
* B:構造方法
    * public BigDecimal(String val)
* C:成員方法
    * public BigDecimal add(BigDecimal augend)
    * public BigDecimal subtract(BigDecimal subtrahend)
    * public BigDecimal multiply(BigDecimal multiplicand)
    * public BigDecimal divide(BigDecimal divisor)
* D:案例演示
    * BigDecimal類的構造方法和成員方法使用

###14.16_常見對象(Date類的概述和方法使用)(掌握)
* A:Date類的概述
    * 類 Date 表示特定的瞬間,精確到毫秒。 
* B:構造方法
    * public Date()
    * public Date(long date)
* C:成員方法
    * public long getTime()
    * public void setTime(long time)

###14.17_常見對象(SimpleDateFormat類實現日期和字符串的相互轉換)(掌握)
* A:DateFormat類的概述
    * DateFormat 是日期/時間格式化子類的抽象類,它以與語言無關的方式格式化並解析日期或時間。是抽象類,所以使用其子類SimpleDateFormat
* B:SimpleDateFormat構造方法
    * public SimpleDateFormat()
    * public SimpleDateFormat(String pattern)
* C:成員方法
    * public final String format(Date date)
    * public Date parse(String source)


###14.18_常見對象(你來到這個世界多少天案例)(掌握)
* A:案例演示
    * 需求:算一下你來到這個世界多少天?

###14.19_常見對象(Calendar類的概述和獲取日期的方法)(掌握)
* A:Calendar類的概述
    * Calendar 類是一個抽象類,它爲特定瞬間與一組諸如 YEAR、MONTH、DAY_OF_MONTH、HOUR 等日曆字段之間的轉換提供了一些方法,併爲操作日曆字段(例如獲得下星期的日期)提供了一些方法。
* B:成員方法
    * public static Calendar getInstance()
    * public int get(int field)


###14.20_常見對象(Calendar類的add()和set()方法)(掌握)
* A:成員方法
    * public void add(int field,int amount)
    * public final void set(int year,int month,int date)
* B:案例演示
    * Calendar類的成員方法使用

###14.21_常見對象(如何獲取任意年份是平年還是閏年)(掌握)
* A:案例演示
    * 需求:鍵盤錄入任意一個年份,判斷該年是閏年還是平年

###14.22_day14總結
* 把今天的知識點總結一遍。

###15.01_集合框架(對象數組的概述和使用)
* A:案例演示
    * 需求:我有5個學生,請把這個5個學生的信息存儲到數組中,並遍歷數組,獲取得到每一個學生信息。

        Student[] arr = new Student[5];                    //存儲學生對象
        arr[0] = new Student("張三", 23);
        arr[1] = new Student("李四", 24);
        arr[2] = new Student("王五", 25);
        arr[3] = new Student("趙六", 26);
        arr[4] = new Student("馬哥", 20);
        
        for (int i = 0; i < arr.length; i++) {
            System.out.println(arr[i]);
        }
        
* B:畫圖演示
    * 把學生數組的案例畫圖講解
    * 數組和集合存儲引用數據類型,存的都是地址值

###15.02_集合框架(集合的由來及集合繼承體系圖)
* A:集合的由來
    * 數組長度是固定,當添加的元素超過了數組的長度時需要對數組重新定義,太麻煩,java內部給我們提供了集合類,能存儲任意對象,長度是可以改變的,隨着元素的增加而增加,隨着元素的減少而減少 
* B:數組和集合的區別
    * 區別1 : 
        * 數組既可以存儲基本數據類型,又可以存儲引用數據類型,基本數據類型存儲的是值,引用數據類型存儲的是地址值
        * 集合只能存儲引用數據類型(對象)集合中也可以存儲基本數據類型,但是在存儲的時候會自動裝箱變成對象
    * 區別2:
        * 數組長度是固定的,不能自動增長
        * 集合的長度的是可變的,可以根據元素的增加而增長
* C:數組和集合什麼時候用
        * 1,如果元素個數是固定的推薦用數組
        * 2,如果元素個數不是固定的推薦用集合
* D:集合繼承體系圖

###15.03_集合框架(Collection集合的基本功能測試)
* A:案例演示    

        基本功能演示
        
        boolean add(E e)
        boolean remove(Object o)
        void clear()
        boolean contains(Object o)
        boolean isEmpty()
        int size()

* B:注意:

        collectionXxx.java使用了未經檢查或不安全的操作.
        注意:要了解詳細信息,請使用 -Xlint:unchecked重新編譯.
        java編譯器認爲該程序存在安全隱患
        溫馨提示:這不是編譯失敗,所以先不用理會,等學了泛型你就知道了
      
###15.04_集合框架(集合的遍歷之集合轉數組遍歷)
* A:集合的遍歷
    * 其實就是依次獲取集合中的每一個元素。
* B:案例演示
    * 把集合轉成數組,可以實現集合的遍歷
    * toArray()
    *
        
            Collection coll = new ArrayList();
            coll.add(new Student("張三",23));        //Object obj = new Student("張三",23);
            coll.add(new Student("李四",24));
            coll.add(new Student("王五",25));
            coll.add(new Student("趙六",26));
            
            Object[] arr = coll.toArray();                //將集合轉換成數組
            for (int i = 0; i < arr.length; i++) {
                Student s = (Student)arr[i];            //強轉成Student
                System.out.println(s.getName() + "," + s.getAge());
            }

###15.05_集合框架(Collection集合的帶All功能測試)
* A:案例演示

        帶All的功能演示
        
        boolean addAll(Collection c)
        boolean removeAll(Collection c)
        boolean containsAll(Collection c)
        boolean retainAll(Collection c)


###15.06_集合框架(集合的遍歷之迭代器遍歷)
* A:迭代器概述
    * 集合是用來存儲元素,存儲的元素需要查看,那麼就需要迭代(遍歷) 
* B:案例演示
    * 迭代器的使用
        
            Collection c = new ArrayList();
            c.add("a");
            c.add("b");
            c.add("c");
            c.add("d");
            
            Iterator it = c.iterator();                        //獲取迭代器的引用
            while(it.hasNext()) {                            //集合中的迭代方法(遍歷)
                System.out.println(it.next());
            }
    
            
###15.07_集合框架(Collection存儲自定義對象並遍歷)
* A:案例演示
    * Collection存儲自定義對象並用迭代器遍歷
    * 
            Collection c = new ArrayList();
            
            c.add(new Student("張三",23));
            c.add(new Student("李四",24));
            c.add(new Student("王五",25));
            c.add(new Student("趙六",26));
            c.add(new Student("趙六",26));
            
            for(Iterator it = c.iterator();it.hasNext();) {
                Student s = (Student)it.next();                        //向下轉型
                System.out.println(s.getName() + "," + s.getAge());    //獲取對象中的姓名和年齡
            }
            System.out.println("------------------------------");
            Iterator it = c.iterator();                                //獲取迭代器
            while(it.hasNext()) {                                    //判斷集合中是否有元素
                //System.out.println(((Student)(it.next())).getName() + "," + ((Student)(it.next())).getAge());
                Student s = (Student)it.next();                        //向下轉型
                System.out.println(s.getName() + "," + s.getAge());    //獲取對象中的姓名和年齡
            }
        

###15.08_集合框架(迭代器的原理及源碼解析)(瞭解)
* A:迭代器原理
    * 迭代器原理:迭代器是對集合進行遍歷,而每一個集合內部的存儲結構都是不同的,所以每一個集合存和取都是不一樣,那麼就需要在每一個類中定義hasNext()和next()方法,這樣做是可以的,但是會讓整個集合體系過於臃腫,迭代器是將這樣的方法向上抽取出接口,然後在每個類的內部,定義自己迭代方式,這樣做的好處有二,第一規定了整個集合體系的遍歷方式都是hasNext()和next()方法,第二,代碼有底層內部實現,使用者不用管怎麼實現的,會用即可 
* B:迭代器源碼解析
    * 1,在eclipse中ctrl + shift + t找到ArrayList類
    * 2,ctrl+o查找iterator()方法
    * 3,查看返回值類型是new Itr(),說明Itr這個類實現Iterator接口
    * 4,查找Itr這個內部類,發現重寫了Iterator中的所有抽象方法 

###15.09_集合框架(List集合的特有功能概述和測試)
* A:List集合的特有功能概述
    * void add(int index,E element)
    * E remove(int index)
    * E get(int index)
    * E set(int index,E element)

###15.10_集合框架(List集合存儲學生對象並遍歷)
* A:案例演示
    * 通過size()和get()方法結合使用遍歷。

            List list = new ArrayList();
            list.add(new Student("張三", 18));
            list.add(new Student("李四", 18));
            list.add(new Student("王五", 18));
            list.add(new Student("趙六", 18));
            
            for(int i = 0; i < list.size(); i++) {
                Student s = (Student)list.get(i);
                System.out.println(s.getName() + "," + s.getAge());
            }

###15.11_集合框架(併發修改異常產生的原因及解決方案)
* A:案例演示
    * 需求:我有一個集合,請問,我想判斷裏面有沒有"world"這個元素,如果有,我就添加一個"javaee"元素,請寫代碼實現。

            List list = new ArrayList();
            list.add("a");
            list.add("b");
            list.add("world");
            list.add("d");
            list.add("e");
            
            /*Iterator it = list.iterator();
            while(it.hasNext()) {
                String str = (String)it.next();
                if(str.equals("world")) {
                    list.add("javaee");            //這裏會拋出ConcurrentModificationException併發修改異常
                }
            }*/
            
            
* B:ConcurrentModificationException出現
    * 迭代器遍歷,集合修改集合
* C:解決方案
    * a:迭代器迭代元素,迭代器修改元素(ListIterator的特有功能add)
    * b:集合遍歷元素,集合修改元素

            ListIterator lit = list.listIterator();        //如果想在遍歷的過程中添加元素,可以用ListIterator中的add方法
            while(lit.hasNext()) {
                String str = (String)lit.next();
                if(str.equals("world")) {
                    lit.add("javaee");    
                    //list.add("javaee");
                }
            }

###15.12_集合框架(ListIterator)(瞭解)
* boolean hasNext()是否有下一個
* boolean hasPrevious()是否有前一個
* Object next()返回下一個元素
* Object previous();返回上一個元素

###15.13_集合框架(Vector的特有功能)
* A:Vector類概述
* B:Vector類特有功能
    * public void addElement(E obj)
    * public E elementAt(int index)
    * public Enumeration elements()
* C:案例演示    
    * Vector的迭代

            Vector v = new Vector();                //創建集合對象,List的子類
            v.addElement("a");
            v.addElement("b");
            v.addElement("c");
            v.addElement("d");
            
            //Vector迭代
            Enumeration en = v.elements();            //獲取枚舉
            while(en.hasMoreElements()) {            //判斷集合中是否有元素
                System.out.println(en.nextElement());//獲取集合中的元素
            }

###15.14_集合框架(數據結構之數組和鏈表)
* A:數組
    * 查詢快修改也快
    * 增刪慢
* B:鏈表
    * 查詢慢,修改也慢
    * 增刪快

###15.15_集合框架(List的三個子類的特點)
* A:List的三個子類的特點

        ArrayList:
            底層數據結構是數組,查詢快,增刪慢。
            線程不安全,效率高。
        Vector:
            底層數據結構是數組,查詢快,增刪慢。
            線程安全,效率低。
        Vector相對ArrayList查詢慢(線程安全的)
        Vector相對LinkedList增刪慢(數組結構)
        LinkedList:
            底層數據結構是鏈表,查詢慢,增刪快。
            線程不安全,效率高。

        Vector和ArrayList的區別
            Vector是線程安全的,效率低
            ArrayList是線程不安全的,效率高
        共同點:都是數組實現的
        ArrayList和LinkedList的區別
            ArrayList底層是數組結果,查詢和修改快
            LinkedList底層是鏈表結構的,增和刪比較快,查詢和修改比較慢
        共同點:都是線程不安全的
* B:List有三個兒子,我們到底使用誰呢?
        查詢多用ArrayList
        增刪多用LinkedList
        如果都多ArrayList
###15.16_day15總結
把今天的知識點總結一遍。

###16.01_集合框架(去除ArrayList中重複字符串元素方式)(掌握)
* A:案例演示
    * 需求:ArrayList去除集合中字符串的重複值(字符串的內容相同)
    * 思路:創建新集合方式

            /**
             *  A:案例演示
             * 需求:ArrayList去除集合中字符串的重複值(字符串的內容相同)
             * 思路:創建新集合方式
             */
            public static void main(String[] args) {
                ArrayList list = new ArrayList();
                list.add("a");
                list.add("a");
                list.add("b");
                list.add("b");
                list.add("b");
                list.add("c");
                list.add("c");
                list.add("c");
                list.add("c");
                
                System.out.println(list);
                ArrayList newList = getSingle(list);
                System.out.println(newList);
            }
        
            /*
             * 去除重複
             * 1,返回ArrayList
             * 2,參數列表ArrayList
             */
            public static ArrayList getSingle(ArrayList list) {
                ArrayList newList = new ArrayList();            //創建一個新集合
                Iterator it = list.iterator();                    //獲取迭代器
                while(it.hasNext()) {                            //判斷老集合中是否有元素
                    String temp = (String)it.next();            //將每一個元素臨時記錄住
                    if(!newList.contains(temp)) {                //如果新集合中不包含該元素
                        newList.add(temp);                        //將該元素添加到新集合中
                    }
                }
                return newList;                                    //將新集合返回
            }
###16.02_集合框架(去除ArrayList中重複自定義對象元素)(掌握)
* A:案例演示
    * 需求:ArrayList去除集合中自定義對象元素的重複值(對象的成員變量值相同)
* B:注意事項
    * 重寫equals()方法的

###16.03_集合框架(LinkedList的特有功能)(掌握)
* A:LinkedList類概述
* B:LinkedList類特有功能
    * public void addFirst(E e)及addLast(E e)
    * public E getFirst()及getLast()
    * public E removeFirst()及public E removeLast()
    * public E get(int index);

###16.04_集合框架(棧和隊列數據結構)(掌握)
* 棧
    * 先進後出 
* 隊列
    * 先進先出

###16.05_集合框架(用LinkedList模擬棧數據結構的集合並測試)(掌握)
* A:案例演示
    * 需求:請用LinkedList模擬棧數據結構的集合,並測試
    * 創建一個類將Linked中的方法封裝
    * 
            public class Stack {
                private LinkedList list = new LinkedList();        //創建LinkedList對象
                
                public void in(Object obj) {
                    list.addLast(obj);                            //封裝addLast()方法
                }
                
                public Object out() {
                    return list.removeLast();                    //封裝removeLast()方法
                }
                
                public boolean isEmpty() {
                    return list.isEmpty();                        //封裝isEmpty()方法
                }
            }
    

###16.06_集合框架(泛型概述和基本使用)(掌握)
* A:泛型概述
* B:泛型好處
    * 提高安全性(將運行期的錯誤轉換到編譯期) 
    * 省去強轉的麻煩
* C:泛型基本使用
    * <>中放的必須是引用數據類型 
* D:泛型使用注意事項
    * 前後的泛型必須一致,或者後面的泛型可以省略不寫(1.7的新特性菱形泛型)  

###16.07_集合框架(ArrayList存儲字符串和自定義對象並遍歷泛型版)(掌握)
* A:案例演示
    * ArrayList存儲字符串並遍歷泛型版

###16.08_集合框架(泛型的由來)(瞭解)
* A:案例演示
    * 泛型的由來:通過Object轉型問題引入
    * 早期的Object類型可以接收任意的對象類型,但是在實際的使用中,會有類型轉換的問題。也就存在這隱患,所以Java提供了泛型來解決這個安全問題。

###16.09_集合框架(泛型類的概述及使用)(瞭解)
* A:泛型類概述<T>
    * 把泛型定義在類上
* B:定義格式
    * public class 類名<泛型類型1,…>
* C:注意事項    
    * 泛型類型必須是引用類型
* D:案例演示
    * 泛型類的使用

###16.10_集合框架(泛型方法的概述和使用)(瞭解)
* A:泛型方法概述
    * 把泛型定義在方法上
* B:定義格式    
    * public <泛型類型> 返回類型 方法名(泛型類型 變量名)
* C:案例演示
    * 泛型方法的使用

###16.11_集合框架(泛型接口的概述和使用)(瞭解)
* A:泛型接口概述
    * 把泛型定義在接口上
* B:定義格式    
    * public interface 接口名<泛型類型>
* C:案例演示
    * 泛型接口的使用

###16.12_集合框架(泛型高級之通配符)(瞭解)
* A:泛型通配符<?>
    * 任意類型,如果沒有明確,那麼就是Object以及任意的Java類了
* B:? extends E
    * 向下限定,E及其子類
* C:? super E
    * 向上限定,E及其父類


###16.13_集合框架(增強for的概述和使用)(掌握)
* A:增強for概述
    * 簡化數組和Collection集合的遍歷
* B:格式:

        for(元素數據類型 變量 : 數組或者Collection集合) {
            使用變量即可,該變量就是元素
        }
* C:案例演示
    * 數組,集合存儲元素用增強for遍歷
* D:好處
    * 簡化遍歷


###16.14_集合框架(ArrayList存儲字符串和自定義對象並遍歷增強for版)(掌握)
* A:案例演示
    * ArrayList存儲字符串並遍歷增強for版
    * 
            ArrayList<String> list = new ArrayList<>();
            list.add("a");
            list.add("b");
            list.add("c");
            list.add("d");
            
            for(String s : list) {
                System.out.println(s);
            }
###16.15_集合框架(三種迭代的能否刪除)(掌握)
* 普通for循環,可以刪除,但是索引要--
* 迭代器,可以刪除,但是必須使用迭代器自身的remove方法,否則會出現併發修改異常
* 增強for循環不能刪除

###16.16_集合框架(靜態導入的概述和使用)(掌握)
* A:靜態導入概述
* B:格式:
    * import static 包名….類名.方法名;
    * 可以直接導入到方法的級別
* C:注意事項
    * 方法必須是靜態的,如果有多個同名的靜態方法,容易不知道使用誰?這個時候要使用,必須加前綴。由此可見,意義不大,所以一般不用,但是要能看懂。

###16.17_集合框架(可變參數的概述和使用)(掌握)
* A:可變參數概述
    * 定義方法的時候不知道該定義多少個參數
* B:格式
    * 修飾符 返回值類型 方法名(數據類型…  變量名){}
* C:注意事項:
    * 這裏的變量其實是一個數組
    * 如果一個方法有可變參數,並且有多個參數,那麼,可變參數肯定是最後一個

###16.18_集合框架(Arrays工具類的asList()方法的使用)(掌握)
* A:案例演示
    * Arrays工具類的asList()方法的使用
    * Collection中toArray(T[] a)泛型版的集合轉數組

###16.19_集合框架(集合嵌套之ArrayList嵌套ArrayList)(掌握)
* A:案例演示
    * 集合嵌套之ArrayList嵌套ArrayList

###16.20_day16總結
* 把今天的知識點總結一遍。

###17.01_集合框架(HashSet存儲字符串並遍歷)
* A:Set集合概述及特點
    * 通過API查看即可
* B:案例演示
    * HashSet存儲字符串並遍歷
    * 
             HashSet<String> hs = new HashSet<>();
            boolean b1 = hs.add("a");
            boolean b2 = hs.add("a");            //當存儲不成功的時候,返回false
            
            System.out.println(b1);
            System.out.println(b2);
            for(String s : hs) {
                System.out.println(s);
            }

###17.02_集合框架(HashSet存儲自定義對象保證元素唯一性)
* A:案例演示
    * 存儲自定義對象,並保證元素唯一性。

            HashSet<Person> hs = new HashSet<>();
            hs.add(new Person("張三", 23));
            hs.add(new Person("張三", 23));
            hs.add(new Person("李四", 23));
            hs.add(new Person("李四", 23));
            hs.add(new Person("王五", 23));
            hs.add(new Person("趙六", 23));
* 重寫hashCode()和equals()方法
###17.03_集合框架(HashSet存儲自定義對象保證元素唯一性圖解及代碼優化)
* A:畫圖演示
    * 畫圖說明比較過程
* B:代碼優化
    * 爲了減少比較,優化hashCode()代碼寫法。
    * 最終版就是自動生成即可。

###17.04_集合框架(HashSet如何保證元素唯一性的原理)
* 1.HashSet原理
    * 我們使用Set集合都是需要去掉重複元素的, 如果在存儲的時候逐個equals()比較, 效率較低,哈希算法提高了去重複的效率, 降低了使用equals()方法的次數
    * 當HashSet調用add()方法存儲對象的時候, 先調用對象的hashCode()方法得到一個哈希值, 然後在集合中查找是否有哈希值相同的對象
        * 如果沒有哈希值相同的對象就直接存入集合
        * 如果有哈希值相同的對象, 就和哈希值相同的對象逐個進行equals()比較,比較結果爲false就存入, true則不存
* 2.將自定義類的對象存入HashSet去重複
    * 類中必須重寫hashCode()和equals()方法
    * hashCode(): 屬性相同的對象返回值必須相同, 屬性不同的返回值儘量不同(提高效率)
    * equals(): 屬性相同返回true, 屬性不同返回false,返回false的時候存儲

###17.05_集合框架(LinkedHashSet的概述和使用)
* A:LinkedHashSet的特點
* B:案例演示
    * LinkedHashSet的特點
        * 可以保證怎麼存就怎麼取 

###17.06_集合框架(產生10個1-20之間的隨機數要求隨機數不能重複)
* A:案例演示
    * 需求:編寫一個程序,獲取10個1至20的隨機數,要求隨機數不能重複。並把最終的隨機數輸出到控制檯。
    * 
            HashSet<Integer> hs = new HashSet<>();        //創建集合對象
            Random r = new Random();                    //創建隨機數對象
            
            while(hs.size() < 10) {
                int num = r.nextInt(20) + 1;            //生成1到20的隨機數
                hs.add(num);
            }
            
            for (Integer integer : hs) {                //遍歷集合
                System.out.println(integer);            //打印每一個元素
            }

###17.07_集合框架(練習)
* 使用Scanner從鍵盤讀取一行輸入,去掉其中重複字符, 打印出不同的那些字符
    * aaaabbbcccddd

            Scanner sc = new Scanner(System.in);            //創建鍵盤錄入對象
            System.out.println("請輸入一行字符串:");
            String line = sc.nextLine();                    //將鍵盤錄入的字符串存儲在line中
            char[] arr = line.toCharArray();                //將字符串轉換成字符數組
            HashSet<Character> hs = new HashSet<>();        //創建HashSet集合對象
            
            for(char c : arr) {                                //遍歷字符數組
                hs.add(c);                                    //將字符數組中的字符添加到集合中
            }
            
            for (Character ch : hs) {                        //遍歷集合
                System.out.println(ch);
            }
###17.08_集合框架(練習)
* 將集合中的重複元素去掉

            public static void main(String[] args) {
                ArrayList<String> list = new ArrayList<>();
                list.add("a");
                list.add("a");
                list.add("a");
                list.add("b");
                list.add("b");
                list.add("b");
                list.add("b");
                list.add("c");
                list.add("c");
                list.add("c");
                list.add("c");
                
                System.out.println(list);
                System.out.println("去除重複後:");
                getSingle(list);
                System.out.println(list);
            }
            
            /*
             * 將集合中的重複元素去掉
             * 1,void
             * 2,List<String> list
             */
            
            public static void getSingle(List<String> list) {
                LinkedHashSet<String> lhs = new LinkedHashSet<>();
                lhs.addAll(list);                                    //將list集合中的所有元素添加到lhs
                list.clear();                                        //清空原集合
                list.addAll(lhs);                                    //將去除重複的元素添回到list中
            }

###17.09_集合框架(TreeSet存儲Integer類型的元素並遍歷)
* A:案例演示
    * TreeSet存儲Integer類型的元素並遍歷

###17.10_集合框架(TreeSet存儲自定義對象)
* A:案例演示
    * 存儲Person對象

###17.11_集合框架(TreeSet保證元素唯一和自然排序的原理和圖解)
* A:畫圖演示
    * TreeSet保證元素唯一和自然排序的原理和圖解

###17.12_集合框架(TreeSet存儲自定義對象並遍歷練習1)
* A:案例演示
    * TreeSet存儲自定義對象並遍歷練習1(按照姓名排序)

###17.13_集合框架(TreeSet存儲自定義對象並遍歷練習2)
* A:案例演示
    * TreeSet存儲自定義對象並遍歷練習2(按照姓名的長度排序)

###17.14_集合框架(TreeSet保證元素唯一和比較器排序的原理及代碼實現)
* A:案例演示
    * TreeSet保證元素唯一和比較器排序的原理及代碼實現

###17.15_集合框架(TreeSet原理)
* 1.特點
    * TreeSet是用來排序的, 可以指定一個順序, 對象存入之後會按照指定的順序排列
* 2.使用方式
    * a.自然順序(Comparable)
        * TreeSet類的add()方法中會把存入的對象提升爲Comparable類型
        * 調用對象的compareTo()方法和集合中的對象比較
        * 根據compareTo()方法返回的結果進行存儲
    * b.比較器順序(Comparator)
        * 創建TreeSet的時候可以制定 一個Comparator
        * 如果傳入了Comparator的子類對象, 那麼TreeSet就會按照比較器中的順序排序
        * add()方法內部會自動調用Comparator接口中compare()方法排序
        * 調用的對象是compare方法的第一個參數,集合中的對象是compare方法的第二個參數
    * c.兩種方式的區別
        * TreeSet構造函數什麼都不傳, 默認按照類中Comparable的順序(沒有就報錯ClassCastException)
        * TreeSet如果傳入Comparator, 就優先按照Comparator

###17.16_集合框架(練習)
* 在一個集合中存儲了無序並且重複的字符串,定義一個方法,讓其有序(字典順序),而且還不能去除重複

            public static void main(String[] args) {
                ArrayList<String> list = new ArrayList<>();
                list.add("ccc");
                list.add("ccc");
                list.add("aaa");
                list.add("aaa");
                list.add("bbb");
                list.add("ddd");
                list.add("ddd");
                
                sort(list);
                System.out.println(list);
            }
            
            /*
             * 對集合中的元素排序,並保留重複
             * 1,void
             * 2,List<String> list
             */
            public static void sort(List<String> list) {
                TreeSet<String> ts = new TreeSet<>(new Comparator<String>() {        //定義比較器(new Comparator(){}是Comparator的子類對象)
        
                    @Override
                    public int compare(String s1, String s2) {                        //重寫compare方法
                        int num = s1.compareTo(s2);                                    //比較內容
                        return num == 0 ? 1 : num;                                    //如果內容一樣返回一個不爲0的數字即可
                    }
                });
                
                ts.addAll(list);                                                    //將list集合中的所有元素添加到ts中
                list.clear();                                                        //清空list
                list.addAll(ts);                                                    //將ts中排序並保留重複的結果在添加到list中
            }

###17.17_集合框架(練習)
* 從鍵盤接收一個字符串, 程序對其中所有字符進行排序,例如鍵盤輸入: helloitcast程序打印:acehillostt

        Scanner sc = new Scanner(System.in);            //創建鍵盤錄入對象
        System.out.println("請輸入一行字符串:");
        String line = sc.nextLine();                    //將鍵盤錄入的字符串存儲在line中
        char[] arr = line.toCharArray();                //將字符串轉換成字符數組
        TreeSet<Character> ts = new TreeSet<>(new Comparator<Character>() {

            @Override
            public int compare(Character c1, Character c2) {
                //int num = c1.compareTo(c2);
                int num = c1 - c2;                    //自動拆箱
                return num == 0 ? 1 : num;
            }
        });
        
        for(char c : arr) {
            ts.add(c);
        }
        
        for(Character ch : ts) {
            System.out.print(ch);
        }
###17.18_集合框架(練習)
* 程序啓動後, 可以從鍵盤輸入接收多個整數, 直到輸入quit時結束輸入. 把所有輸入的整數倒序排列打印.
            Scanner sc = new Scanner(System.in);        //創建鍵盤錄入對象
            System.out.println("請輸入:");
            TreeSet<Integer> ts = new TreeSet<>(new Comparator<Integer>() {//將比較器傳給TreeSet的構造方法
    
                @Override
                public int compare(Integer i1, Integer i2) {
                    //int num = i2 - i1;                    //自動拆箱
                    int num = i2.compareTo(i1);
                    return num == 0 ? 1 : num;
                }
            });
            
            while(true) {
                String line = sc.nextLine();            //將鍵盤錄入的字符串存儲在line中
                if("quit".equals(line))                    //如果字符串常量和變量比較,常量放前面,這樣不會出現空指針異常,變量裏面可能存儲null
                    break;
                try {
                    int num = Integer.parseInt(line);        //將數字字符串轉換成數字
                    ts.add(num);
                } catch (Exception e) {
                    System.out.println("您錄入的數據有誤,請輸入一個整數");
                }
                
            }
            
            for (Integer i : ts) {                        //遍歷TreeSet集合
                System.out.println(i);
            }
###17.19_集合框架(鍵盤錄入學生信息按照總分排序後輸出在控制檯)
* A:案例演示
    * 需求:鍵盤錄入5個學生信息(姓名,語文成績,數學成績,英語成績),按照總分從高到低輸出到控制檯。
            Scanner sc = new Scanner(System.in);
            System.out.println("請輸入5個學生成績格式是:(姓名,語文成績,數學成績,英語成績)");
            TreeSet<Student> ts = new TreeSet<>(new Comparator<Student>() {
                @Override
                public int compare(Student s1, Student s2) {
                    int num = s2.getSum() - s1.getSum();            //根據學生的總成績降序排列
                    return num == 0 ? 1 : num;
                }
            });
            
            while(ts.size() < 5) {
                String line = sc.nextLine();
                try {
                    String[] arr = line.split(",");
                    int chinese = Integer.parseInt(arr[1]);                //轉換語文成績
                    int math = Integer.parseInt(arr[2]);                //轉換數學成績
                    int english = Integer.parseInt(arr[3]);                //轉換英語成績
                    ts.add(new Student(arr[0], chinese, math, english));
                } catch (Exception e) {
                    System.out.println("錄入格式有誤,輸入5個學生成績格式是:(姓名,語文成績,數學成績,英語成績");
                }
                
            }
            
            System.out.println("排序後的學生成績是:");
            for (Student s : ts) {
                System.out.println(s);
            }

###17.20_day17總結
* 1.List
    * a.普通for循環, 使用get()逐個獲取
    * b.調用iterator()方法得到Iterator, 使用hasNext()和next()方法
    * c.增強for循環, 只要可以使用Iterator的類都可以用
    * d.Vector集合可以使用Enumeration的hasMoreElements()和nextElement()方法
* 2.Set
    * a.調用iterator()方法得到Iterator, 使用hasNext()和next()方法
    * b.增強for循環, 只要可以使用Iterator的類都可以用
* 3.普通for循環,迭代器,增強for循環是否可以在遍歷的過程中刪除 

###18.01_集合框架(Map集合概述和特點)
* A:Map接口概述
    * 查看API可以知道:
        * 將鍵映射到值的對象
        * 一個映射不能包含重複的鍵
        * 每個鍵最多隻能映射到一個值
* B:Map接口和Collection接口的不同
    * Map是雙列的,Collection是單列的
    * Map的鍵唯一,Collection的子體系Set是唯一的
    * Map集合的數據結構值針對鍵有效,跟值無關;Collection集合的數據結構是針對元素有效
    
###18.02_集合框架(Map集合的功能概述)
* A:Map集合的功能概述
    * a:添加功能
        * V put(K key,V value):添加元素。
            * 如果鍵是第一次存儲,就直接存儲元素,返回null
            * 如果鍵不是第一次存在,就用值把以前的值替換掉,返回以前的值
    * b:刪除功能
        * void clear():移除所有的鍵值對元素
        * V remove(Object key):根據鍵刪除鍵值對元素,並把值返回
    * c:判斷功能
        * boolean containsKey(Object key):判斷集合是否包含指定的鍵
        * boolean containsValue(Object value):判斷集合是否包含指定的值
        * boolean isEmpty():判斷集合是否爲空
    * d:獲取功能
        * Set<Map.Entry<K,V>> entrySet():
        * V get(Object key):根據鍵獲取值
        * Set<K> keySet():獲取集合中所有鍵的集合
        * Collection<V> values():獲取集合中所有值的集合
    * e:長度功能
        * int size():返回集合中的鍵值對的個數


###18.03_集合框架(Map集合的遍歷之鍵找值)
* A:鍵找值思路:
    * 獲取所有鍵的集合
    * 遍歷鍵的集合,獲取到每一個鍵
    * 根據鍵找值
* B:案例演示
    * Map集合的遍歷之鍵找值

            HashMap<String, Integer> hm = new HashMap<>();
            hm.put("張三", 23);
            hm.put("李四", 24);
            hm.put("王五", 25);
            hm.put("趙六", 26);
            
            /*Set<String> keySet = hm.keySet();            //獲取集合中所有的鍵
            Iterator<String> it = keySet.iterator();    //獲取迭代器
            while(it.hasNext()) {                        //判斷單列集合中是否有元素
                String key = it.next();                    //獲取集合中的每一個元素,其實就是雙列集合中的鍵
                Integer value = hm.get(key);            //根據鍵獲取值
                System.out.println(key + "=" + value);    //打印鍵值對
            }*/
            
            for(String key : hm.keySet()) {                //增強for循環迭代雙列集合第一種方式
                System.out.println(key + "=" + hm.get(key));
            }
    
###18.04_集合框架(Map集合的遍歷之鍵值對對象找鍵和值)
* A:鍵值對對象找鍵和值思路:
    * 獲取所有鍵值對對象的集合
    * 遍歷鍵值對對象的集合,獲取到每一個鍵值對對象
    * 根據鍵值對對象找鍵和值
* B:案例演示
    * Map集合的遍歷之鍵值對對象找鍵和值
    
            HashMap<String, Integer> hm = new HashMap<>();
            hm.put("張三", 23);
            hm.put("李四", 24);
            hm.put("王五", 25);
            hm.put("趙六", 26);
            /*Set<Map.Entry<String, Integer>> entrySet = hm.entrySet();    //獲取所有的鍵值對象的集合
            Iterator<Entry<String, Integer>> it = entrySet.iterator();//獲取迭代器
            while(it.hasNext()) {
                Entry<String, Integer> en = it.next();                //獲取鍵值對對象
                String key = en.getKey();                                //根據鍵值對對象獲取鍵
                Integer value = en.getValue();                            //根據鍵值對對象獲取值
                System.out.println(key + "=" + value);
            }*/
            
            for(Entry<String,Integer> en : hm.entrySet()) {
                System.out.println(en.getKey() + "=" + en.getValue());
            }
        
C:源碼分析

###18.05_集合框架(HashMap集合鍵是Student值是String的案例)
* A:案例演示
    * HashMap集合鍵是Student值是String的案例

###18.06_集合框架(LinkedHashMap的概述和使用)
* A:案例演示
    * LinkedHashMap的特點
        * 底層是鏈表實現的可以保證怎麼存就怎麼取

###18.07_集合框架(TreeMap集合鍵是Student值是String的案例)
* A:案例演示
    * TreeMap集合鍵是Student值是String的案例

###18.08_集合框架(統計字符串中每個字符出現的次數)
* A:案例演示
    * 需求:統計字符串中每個字符出現的次數
            String str = "aaaabbbcccccccccc";
            char[] arr = str.toCharArray();                        //將字符串轉換成字符數組
            HashMap<Character, Integer> hm = new HashMap<>();    //創建雙列集合存儲鍵和值
            
            for(char c : arr) {                                    //遍歷字符數組
                /*if(!hm.containsKey(c)) {                        //如果不包含這個鍵
                    hm.put(c, 1);                                //就將鍵和值爲1添加
                }else {                                            //如果包含這個鍵
                    hm.put(c, hm.get(c) + 1);                    //就將鍵和值再加1添加進來
                }
                
                //hm.put(c, !hm.containsKey(c) ? 1 : hm.get(c) + 1);
                Integer i = !hm.containsKey(c) ? hm.put(c, 1) : hm.put(c, hm.get(c) + 1);
                        }
            
            for (Character key : hm.keySet()) {                    //遍歷雙列集合
                System.out.println(key + "=" + hm.get(key));
            }


###18.09_集合框架(集合嵌套之HashMap嵌套HashMap)
* A:案例演示
    * 集合嵌套之HashMap嵌套HashMap

###18.10_集合框架(HashMap和Hashtable的區別)
* A:面試題
    * HashMap和Hashtable的區別
        * Hashtable是JDK1.0版本出現的,是線程安全的,效率低,HashMap是JDK1.2版本出現的,是線程不安全的,效率高
        * Hashtable不可以存儲null鍵和null值,HashMap可以存儲null鍵和null值
* B:案例演示    
    * HashMap和Hashtable的區別

###18.11_集合框架(Collections工具類的概述和常見方法講解)
* A:Collections類概述
    * 針對集合操作 的工具類
* B:Collections成員方法

        public static <T> void sort(List<T> list)
        public static <T> int binarySearch(List<?> list,T key)
        public static <T> T max(Collection<?> coll)
        public static void reverse(List<?> list)
        public static void shuffle(List<?> list)

###18.12_集合框架(模擬鬥地主洗牌和發牌)
* A:案例演示
    * 模擬鬥地主洗牌和發牌,牌沒有排序

            //買一副撲克
            String[] num = {"A","2","3","4","5","6","7","8","9","10","J","Q","K"};
            String[] color = {"方片","梅花","紅桃","黑桃"};
            ArrayList<String> poker = new ArrayList<>();
            
            for(String s1 : color) {
                for(String s2 : num) {
                    poker.add(s1.concat(s2));
                }
            }
            
            poker.add("小王");
            poker.add("大王");
            //洗牌
            Collections.shuffle(poker);
            //發牌
            ArrayList<String> gaojin = new ArrayList<>();
            ArrayList<String> longwu = new ArrayList<>();
            ArrayList<String> me = new ArrayList<>();
            ArrayList<String> dipai = new ArrayList<>();
            
            for(int i = 0; i < poker.size(); i++) {
                if(i >= poker.size() - 3) {
                    dipai.add(poker.get(i));
                }else if(i % 3 == 0) {
                    gaojin.add(poker.get(i));
                }else if(i % 3 == 1) {
                    longwu.add(poker.get(i));
                }else {
                    me.add(poker.get(i));
                }
            }
            
            //看牌
            
            System.out.println(gaojin);
            System.out.println(longwu);
            System.out.println(me);
            System.out.println(dipai);

###18.13_集合框架(模擬鬥地主洗牌和發牌並對牌進行排序的原理圖解)
* A:畫圖演示
    * 畫圖說明排序原理

###18.14_集合框架(模擬鬥地主洗牌和發牌並對牌進行排序的代碼實現)
* A:案例演示
    * 模擬鬥地主洗牌和發牌並對牌進行排序的代碼實現

            //買一副牌
            String[] num = {"3","4","5","6","7","8","9","10","J","Q","K","A","2"};
            String[] color = {"方片","梅花","紅桃","黑桃"};
            HashMap<Integer, String> hm = new HashMap<>();            //存儲索引和撲克牌
            ArrayList<Integer> list = new ArrayList<>();            //存儲索引
            int index = 0;                                            //索引的開始值
            for(String s1 : num) {
                for(String s2 : color) {
                    hm.put(index, s2.concat(s1));                    //將索引和撲克牌添加到HashMap中
                    list.add(index);                                //將索引添加到ArrayList集合中
                    index++;
                }
            }
            hm.put(index, "小王");
            list.add(index);
            index++;
            hm.put(index, "大王");
            list.add(index);
            //洗牌
            Collections.shuffle(list);
            //發牌
            TreeSet<Integer> gaojin = new TreeSet<>();
            TreeSet<Integer> longwu = new TreeSet<>();
            TreeSet<Integer> me = new TreeSet<>();
            TreeSet<Integer> dipai = new TreeSet<>();
            
            for(int i = 0; i < list.size(); i++) {
                if(i >= list.size() - 3) {
                    dipai.add(list.get(i));                         //將list集合中的索引添加到TreeSet集合中會自動排序
                }else if(i % 3 == 0) {
                    gaojin.add(list.get(i));
                }else if(i % 3 == 1) {
                    longwu.add(list.get(i));
                }else {
                    me.add(list.get(i));
                }
            }
            
            //看牌
            lookPoker("高進", gaojin, hm);
            lookPoker("龍五", longwu, hm);
            lookPoker("馮佳", me, hm);
            lookPoker("底牌", dipai, hm);
            
        }
        
        public static void lookPoker(String name,TreeSet<Integer> ts,HashMap<Integer, String> hm) {
            System.out.print(name + "的牌是:");
            for (Integer index : ts) {
                System.out.print(hm.get(index) + " ");
            }
            
            System.out.println();
        }
###18.15_集合框架(泛型固定下邊界)
* ? super E

###18.16_day18總結
* 把今天的知識點總結一遍。

###19.01_異常(異常的概述和分類)
* A:異常的概述
    * 異常就是Java程序在運行過程中出現的錯誤。
* B:異常的分類
    * 通過API查看Throwable
    * Error
        * 服務器宕機,數據庫崩潰等
    * Exception
C:異常的繼承體系
    * Throwable
        * Error    
        * Exception
            * RuntimeException

###19.02_異常(JVM默認是如何處理異常的)
* A:JVM默認是如何處理異常的
    * main函數收到這個問題時,有兩種處理方式:
    * a:自己將該問題處理,然後繼續運行
    * b:自己沒有針對的處理方式,只有交給調用main的jvm來處理
    * jvm有一個默認的異常處理機制,就將該異常進行處理.
    * 並將該異常的名稱,異常的信息.異常出現的位置打印在了控制檯上,同時將程序停止運行
* B:案例演示
    * JVM默認如何處理異常

###19.03_異常(try...catch的方式處理異常1)
* A:異常處理的兩種方式
    * a:try…catch…finally
        * try catch
        * try catch finally
        * try finally 
    * b:throws
* B:try...catch處理異常的基本格式
    * try…catch…finally
* C:案例演示
    * try...catch的方式處理1個異常

###19.04_異常(try...catch的方式處理異常2)
* A:案例演示
    * try...catch的方式處理多個異常
    * JDK7以後處理多個異常的方式及注意事項

###19.05_異常(編譯期異常和運行期異常的區別)
* A:編譯期異常和運行期異常的區別
    * Java中的異常被分爲兩大類:編譯時異常和運行時異常。
    * 所有的RuntimeException類及其子類的實例被稱爲運行時異常,其他的異常就是編譯時異常
    
    * 編譯時異常
        * Java程序必須顯示處理,否則程序就會發生錯誤,無法通過編譯
    * 運行時異常
        * 無需顯示處理,也可以和編譯時異常一樣處理
* B:案例演示
    * 編譯期異常和運行期異常的區別

###19.06_異常(Throwable的幾個常見方法)
* A:Throwable的幾個常見方法
    * a:getMessage()
        * 獲取異常信息,返回字符串。
    * b:toString()
        * 獲取異常類名和異常信息,返回字符串。
    * c:printStackTrace()
        * 獲取異常類名和異常信息,以及異常出現在程序中的位置。返回值void。
* B:案例演示
    * Throwable的幾個常見方法的基本使用

###19.07_異常(throws的方式處理異常)
* A:throws的方式處理異常
    * 定義功能方法時,需要把出現的問題暴露出來讓調用者去處理。
    * 那麼就通過throws在方法上標識。
* B:案例演示
    * 舉例分別演示編譯時異常和運行時異常的拋出

###19.08_異常(throw的概述以及和throws的區別)
* A:throw的概述
    * 在功能方法內部出現某種情況,程序不能繼續運行,需要進行跳轉時,就用throw把異常對象拋出。
* B:案例演示    
    * 分別演示編譯時異常對象和運行時異常對象的拋出
* C:throws和throw的區別
    * a:throws
        * 用在方法聲明後面,跟的是異常類名
        * 可以跟多個異常類名,用逗號隔開
        * 表示拋出異常,由該方法的調用者來處理
    * b:throw
        * 用在方法體內,跟的是異常對象名
        * 只能拋出一個異常對象名
        * 表示拋出異常,由方法體內的語句處理

###19.09_異常(finally關鍵字的特點及作用)
* A:finally的特點
    * 被finally控制的語句體一定會執行
    * 特殊情況:在執行到finally之前jvm退出了(比如System.exit(0))
* B:finally的作用
    * 用於釋放資源,在IO流操作和數據庫操作中會見到
* C:案例演示
    * finally關鍵字的特點及作用

###19.10_異常(finally關鍵字的面試題)
* A:面試題1
    * final,finally和finalize的區別
* B:面試題2
    * 如果catch裏面有return語句,請問finally的代碼還會執行嗎?如果會,請問是在return前還是return後。
    
###19.11_異常(自定義異常概述和基本使用)
* A:爲什麼需要自定義異常
    * 舉例:人的年齡
* B:自定義異常概述
    * 繼承自Exception
    * 繼承自RuntimeException
* C:案例演示
    * 自定義異常的基本使用

###19.12_異常(異常的注意事項及如何使用異常處理)
* A:異常注意事項
    * a:子類重寫父類方法時,子類的方法必須拋出相同的異常或父類異常的子類。(父親壞了,兒子不能比父親更壞)
    * b:如果父類拋出了多個異常,子類重寫父類時,只能拋出相同的異常或者是他的子集,子類不能拋出父類沒有的異常
    * c:如果被重寫的方法沒有異常拋出,那麼子類的方法絕對不可以拋出異常,如果子類方法內有異常發生,那麼子類只能try,不能throws
* B:如何使用異常處理
    * 原則:如果該功能內部可以將問題處理,用try,如果處理不了,交由調用者處理,這是用throws
    * 區別:
        * 後續程序需要繼續運行就try
        * 後續程序不需要繼續運行就throws
        
    * 如果JDK沒有提供對應的異常,需要自定義異常。

###19.13_異常(練習)
* 鍵盤錄入一個int類型的整數,對其求二進制表現形式
     * 如果錄入的整數過大,給予提示,錄入的整數過大請重新錄入一個整數BigInteger
     * 如果錄入的是小數,給予提示,錄入的是小數,請重新錄入一個整數
     * 如果錄入的是其他字符,給予提示,錄入的是非法字符,請重新錄入一個整數

###19.14_File類(File類的概述和構造方法)
* A:File類的概述
    * File更應該叫做一個路徑
        * 文件路徑或者文件夾路徑  
        * 路徑分爲絕對路徑和相對路徑
        * 絕對路徑是一個固定的路徑,從盤符開始
        * 相對路徑相對於某個位置,在eclipse下是指當前項目下,在dos下
    * 查看API指的是當前路徑
    * 文件和目錄路徑名的抽象表示形式
* B:構造方法
    * File(String pathname):根據一個路徑得到File對象
    * File(String parent, String child):根據一個目錄和一個子文件/目錄得到File對象
    * File(File parent, String child):根據一個父File對象和一個子文件/目錄得到File對象
* C:案例演示
    * File類的構造方法

###19.15_File類(File類的創建功能)
* A:創建功能
    * public boolean createNewFile():創建文件 如果存在這樣的文件,就不創建了
    * public boolean mkdir():創建文件夾 如果存在這樣的文件夾,就不創建了
    * public boolean mkdirs():創建文件夾,如果父文件夾不存在,會幫你創建出來
* B:案例演示
    * File類的創建功能

    * 注意事項:
        * 如果你創建文件或者文件夾忘了寫盤符路徑,那麼,默認在項目路徑下。
        
###19.16_File類(File類的重命名和刪除功能)
* A:重命名和刪除功能
    * public boolean renameTo(File dest):把文件重命名爲指定的文件路徑
    * public boolean delete():刪除文件或者文件夾
* B:重命名注意事項
    * 如果路徑名相同,就是改名。
    * 如果路徑名不同,就是改名並剪切。
* C:刪除注意事項:
    * Java中的刪除不走回收站。
    * 要刪除一個文件夾,請注意該文件夾內不能包含文件或者文件夾


###19.17_File類(File類的判斷功能)
* A:判斷功能
    * public boolean isDirectory():判斷是否是目錄
    * public boolean isFile():判斷是否是文件
    * public boolean exists():判斷是否存在
    * public boolean canRead():判斷是否可讀
    * public boolean canWrite():判斷是否可寫
    * public boolean isHidden():判斷是否隱藏
* B:案例演示
    * File類的判斷功能
    
###19.18_File類(File類的獲取功能)
* A:獲取功能
    * public String getAbsolutePath():獲取絕對路徑
    * public String getPath():獲取路徑
    * public String getName():獲取名稱
    * public long length():獲取長度。字節數
    * public long lastModified():獲取最後一次的修改時間,毫秒值
    * public String[] list():獲取指定目錄下的所有文件或者文件夾的名稱數組
    * public File[] listFiles():獲取指定目錄下的所有文件或者文件夾的File數組 
* B:案例演示
    * File類的獲取功能

###19.19_File類(輸出指定目錄下指定後綴的文件名)
* A:案例演示
    * 需求:判斷E盤目錄下是否有後綴名爲.jpg的文件,如果有,就輸出該文件名稱

###19.20_File類(文件名稱過濾器的概述及使用)
* A:文件名稱過濾器的概述
    * public String[] list(FilenameFilter filter)
    * public File[] listFiles(FileFilter filter)
* B:文件名稱過濾器的使用
    * 需求:判斷E盤目錄下是否有後綴名爲.jpg的文件,如果有,就輸出該文件名稱
* C:源碼分析
    * 帶文件名稱過濾器的list()方法的源碼

###19.21_File類(遞歸)
* 5的階乘        

###19.22_day19總結
把今天的知識點總結一遍。

###20.01_IO流(IO流概述及其分類)
* 1.概念
    * IO流用來處理設備之間的數據傳輸
    * Java對數據的操作是通過流的方式
    * Java用於操作流的類都在IO包中
    * 流按流向分爲兩種:輸入流,輸出流。
    * 流按操作類型分爲兩種:
        * 字節流 : 字節流可以操作任何數據,因爲在計算機中任何數據都是以字節的形式存儲的
        * 字符流 : 字符流只能操作純字符數據,比較方便。
* 2.IO流常用父類
    * 字節流的抽象父類:
        * InputStream 
        * OutputStream
    * 字符流的抽象父類:
        * Reader 
        * Writer        
* 3.IO程序書寫
    * 使用前,導入IO包中的類
    * 使用時,進行IO異常處理
    * 使用後,釋放資源

###20.02_IO流(FileInputStream)
* read()一次讀取一個字節

        FileInputStream fis = new FileInputStream("aaa.txt");    //創建一個文件輸入流對象,並關聯aaa.txt
        int b;                                                    //定義變量,記錄每次讀到的字節
        while((b = fis.read()) != -1) {                            //將每次讀到的字節賦值給b並判斷是否是-1
            System.out.println(b);                                //打印每一個字節
        }
        
        fis.close();                                            //關閉流釋放資源
###20.03_IO流(read()方法返回值爲什麼是int)
* read()方法讀取的是一個字節,爲什麼返回是int,而不是byte

        因爲字節輸入流可以操作任意類型的文件,比如圖片音頻等,這些文件底層都是以二進制形式的存儲的,如果每次讀取都返回byte,有可能在讀到中間的時候遇到111111111
        那麼這11111111是byte類型的-1,我們的程序是遇到-1就會停止不讀了,後面的數據就讀不到了,所以在讀取的時候用int類型接收,如果11111111會在其前面補上
        24個0湊足4個字節,那麼byte類型的-1就變成int類型的255了這樣可以保證整個數據讀完,而結束標記的-1就是int類型
###20.04_IO流(FileOutputStream)
* write()一次寫出一個字節

        FileOutputStream fos = new FileOutputStream("bbb.txt");    //如果沒有bbb.txt,會創建出一個
        //fos.write(97);                        //雖然寫出的是一個int數,但是在寫出的時候會將前面的24個0去掉,所以寫出的一個byte
        fos.write(98);
        fos.write(99);
        fos.close();
###20.05_IO流(FileOutputStream追加)
* A:案例演示
    * FileOutputStream的構造方法寫出數據如何實現數據的追加寫入

        FileOutputStream fos = new FileOutputStream("bbb.txt",true);    //如果沒有bbb.txt,會創建出一個
        //fos.write(97);                        //雖然寫出的是一個int數,但是在寫出的時候會將前面的24個0去掉,所以寫出的一個byte
        fos.write(98);
        fos.write(99);
        fos.close();

###20.06_IO流(拷貝圖片)
* FileInputStream讀取
* FileOutputStream寫出

        FileInputStream fis = new FileInputStream("致青春.mp3");    //創建輸入流對象,關聯致青春.mp3
        FileOutputStream fos = new FileOutputStream("copy.mp3");//創建輸出流對象,關聯copy.mp3
        
        int b;
        while((b = fis.read()) != -1) {
            fos.write(b);
        }
        
        fis.close();
        fos.close();
        

###20.07_IO流(拷貝音頻文件畫原理圖)
* A:案例演示
    * 字節流一次讀寫一個字節複製音頻
* 弊端:效率太低

###20.08_IO流(字節數組拷貝之available()方法)
* A:案例演示
    * int read(byte[] b):一次讀取一個字節數組
    * write(byte[] b):一次寫出一個字節數組
    * available()獲取讀的文件所有的字節個數
* 弊端:有可能會內存溢出 
    
        FileInputStream fis = new FileInputStream("致青春.mp3");
        FileOutputStream fos = new FileOutputStream("copy.mp3");
        byte[] arr = new byte[fis.available()];                    //根據文件大小做一個字節數組
        fis.read(arr);                                            //將文件上的所有字節讀取到數組中
        fos.write(arr);                                            //將數組中的所有字節一次寫到了文件上
        fis.close();
        fos.close();
        
###20.09_IO流(定義小數組)
* write(byte[] b)
* write(byte[] b, int off, int len)寫出有效的字節個數

        
###20.10_IO流(定義小數組的標準格式)
* A:案例演示
    * 字節流一次讀寫一個字節數組複製圖片和視頻
        FileInputStream fis = new FileInputStream("致青春.mp3");
        FileOutputStream fos = new FileOutputStream("copy.mp3");
        int len;
        byte[] arr = new byte[1024 * 8];                    //自定義字節數組
        
        while((len = fis.read(arr)) != -1) {
            //fos.write(arr);
            fos.write(arr, 0, len);                            //寫出字節數組寫出有效個字節個數
        }
        
        fis.close();
        fos.close();
###20.11_IO流(BufferedInputStream和BufferOutputStream拷貝)
* A:緩衝思想
    * 字節流一次讀寫一個數組的速度明顯比一次讀寫一個字節的速度快很多,
    * 這是加入了數組這樣的緩衝區效果,java本身在設計的時候,
    * 也考慮到了這樣的設計思想(裝飾設計模式後面講解),所以提供了字節緩衝區流
* B.BufferedInputStream
    * BufferedInputStream內置了一個緩衝區(數組)
    * 從BufferedInputStream中讀取一個字節時
    * BufferedInputStream會一次性從文件中讀取8192個, 存在緩衝區中, 返回給程序一個
    * 程序再次讀取時, 就不用找文件了, 直接從緩衝區中獲取
    * 直到緩衝區中所有的都被使用過, 才重新從文件中讀取8192個
* C.BufferedOutputStream
    * BufferedOutputStream也內置了一個緩衝區(數組)
    * 程序向流中寫出字節時, 不會直接寫到文件, 先寫到緩衝區中
    * 直到緩衝區寫滿, BufferedOutputStream纔會把緩衝區中的數據一次性寫到文件裏
* D.拷貝的代碼 

        FileInputStream fis = new FileInputStream("致青春.mp3");            //創建文件輸入流對象,關聯致青春.mp3
        BufferedInputStream bis = new BufferedInputStream(fis);            //創建緩衝區對fis裝飾
        FileOutputStream fos = new FileOutputStream("copy.mp3");        //創建輸出流對象,關聯copy.mp3
        BufferedOutputStream bos = new BufferedOutputStream(fos);        //創建緩衝區對fos裝飾
        
        int b;
        while((b = bis.read()) != -1) {        
            bos.write(b);
        }
        
        bis.close();                        //只關裝飾後的對象即可
        bos.close();
     
* E.小數組的讀寫和帶Buffered的讀取哪個更快?
    * 定義小數組如果是8192個字節大小和Buffered比較的話
    * 定義小數組會略勝一籌,因爲讀和寫操作的是同一個數組
    * 而Buffered操作的是兩個數組

###20.12_IO流(flush和close方法的區別)
* flush()方法
    * 用來刷新緩衝區的,刷新後可以再次寫出 
* close()方法
    * 用來關閉流釋放資源的的,如果是帶緩衝區的流對象的close()方法,不但會關閉流,還會再關閉流之前刷新緩衝區,關閉後不能再寫出 
###20.13_IO流(字節流讀寫中文) 
* 字節流讀取中文的問題
    * 字節流在讀中文的時候有可能會讀到半個中文,造成亂碼 
* 字節流寫出中文的問題
    * 字節流直接操作的字節,所以寫出中文必須將字符串轉換成字節數組 
    * 寫出回車換行 write("\r\n".getBytes());

###20.14_IO流(流的標準處理異常代碼1.6版本及其以前)
* try finally嵌套

        FileInputStream fis = null;
        FileOutputStream fos = null;
        try {
            fis = new FileInputStream("aaa.txt");
            fos = new FileOutputStream("bbb.txt");
            int b;
            while((b = fis.read()) != -1) {
                fos.write(b);
            }
        } finally {
            try {
                if(fis != null)
                    fis.close();
            }finally {
                if(fos != null)
                    fos.close();
            }
        }

###20.15_IO流(流的標準處理異常代碼1.7版本)
* try close

        try(
            FileInputStream fis = new FileInputStream("aaa.txt");
            FileOutputStream fos = new FileOutputStream("bbb.txt");
            MyClose mc = new MyClose();
        ){
            int b;
            while((b = fis.read()) != -1) {
                fos.write(b);
            }
        }
* 原理
    * 在try()中創建的流對象必須實現了AutoCloseable這個接口,如果實現了,在try後面的{}(讀寫代碼)執行後就會自動調用,流對象的close方法將流關掉 

###20.16_IO流(圖片加密)
* 給圖片加密

        BufferedInputStream bis = new BufferedInputStream(new FileInputStream("a.jpg"));
        BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream("b.jpg"));
        
        int b;
        while((b = bis.read()) != -1) {
            bos.write(b ^ 123);
        }
        
        bis.close();
        bos.close();

###20.17_IO流(拷貝文件)
* 在控制檯錄入文件的路徑,將文件拷貝到當前項目下

        Scanner sc = new Scanner(System.in);
        System.out.println("請輸入一個文件路徑");
        String line = sc.nextLine();                //將鍵盤錄入的文件路徑存儲在line中
        File file = new File(line);                    //封裝成File對象
        FileInputStream fis = new FileInputStream(file);
        FileOutputStream fos = new FileOutputStream(file.getName());
        
        int len;
        byte[] arr = new byte[8192];                //定義緩衝區
        while((len = fis.read(arr)) != -1) {
            fos.write(arr,0,len);
        }
        
        fis.close();
        fos.close();

###20.18_IO流(錄入數據拷貝到文件)
* 將鍵盤錄入的數據拷貝到當前項目下的text.txt文件中,鍵盤錄入數據當遇到quit時就退出

        Scanner sc = new Scanner(System.in);
        FileOutputStream fos = new FileOutputStream("text.txt");
        System.out.println("請輸入:");
        while(true) {
            String line = sc.nextLine();
            if("quit".equals(line))
                break;
            fos.write(line.getBytes());
            fos.write("\r\n".getBytes());
        }
        
        fos.close();
###20.19_day20總結
* 把今天的知識點總結一遍。

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