1. 程式人生 > >java高級⑴

java高級⑴

object tex junit ont style import keys lec ransient

1.
之前我們學過 數組: 數組的特點: 01. 長度一旦被定義,不允許被改變 02. 在內存中開辟一連串連續的空間! 那麽現在有一個需求: 讓我們定義一個數組 來 保存 新聞信息!!! 問題: 01.如果定義一個數組 長度為50 今天的新聞數量只有10條! 那麽有40個空間被浪費掉了! 02.今天的新聞數量只有100條! 那麽無法存放多余的50條信息! 在程序的運行過程中,我們不知道需要多少個對象的時候,我們首選集合!!! 集合框架! Vector 線程安全的,但是性能低! List Set Map java中的集合框架是 jdk給我們提供好的一些列接口或者類的集合! 他們都存在於 java.util包中! public interface List<E> extends Collection<E> public interface Set<E> extends Collection<E> public interface Map<K,V> 通過觀看底層代碼 得知: List Set 接口都 繼承了Collection接口! Collection接口中存儲的都是不唯一(可以重復),無序的對象! List接口中存儲的都是不唯一(可以重復),有序(插入順序)的對象! 常用的實現類 ArrayList LinkedList Set接口中存儲的都是唯一(不可以重復),無序的對象! 常用的實現類 HashSet TreeSet Map是單獨的接口! Map接口存儲的是一組鍵值對(key , value)!key是不允許重復的! 常用的實現類 HashMap TreeMap 接口不能被實例化! 所以我們剛才看到的 List Set Map 都應該有對應的實現類! 我們使用的時候肯定是使用實現類!或者使用多態! 父類引用指向子類的對象! 學數組的時候有沒有工具類??? Arrays 現在集合中 也有工具類 Collections /** * ArrayList和LinkedList的區別 * ArrayList:采用數組的形式來保存數據!這些數據被放在內存中開辟連續的空間! * 每個數據的位置都有下標! * 比如說: * 現在集合長度為50! 現在想刪除下標為2的元素! * 刪除之後,底層還要做什麽操作? * 下標為2之後的元素都要前移?? * * 現在想在下標為3的位置 新增 元素! * 下標3的元素之後的數據全部後移?? * 所以 新增,刪除效率慢! * 因為是數組結構,所以遍歷,查詢效率高! * * LinkedList:鏈表式結構!存儲在集合中的每個對象都存放在相互獨立的空間! * 比如說: * 現在集合長度為50! * 第1個元素記錄第2個元素的位置 * 第2個元素記錄第3個元素的位置 * 。。。。 * 第49個元素記錄第50個元素的位置 * 我們想刪除第3個元素! * 只需要讓 第2個元素記錄第4個元素的位置! * 之後的元素有影響嗎? 沒有 * * 在第2個元素和第3個元素之間新增一個元素x * 這時候只需要 第2個元素 記錄x的位置 * x記錄第三個元素的位置 * 新增,刪除效率高! * 因為沒有下標,所以查詢遍歷的效率低! * */

2.ArrayList
技術分享
public class ArrayTest {

    public static void main(String[] args) {

        int nums[] = new int[5];
        nums[0] = 1;
        nums[1] = 1;
        nums[2] = 1;
        nums[3] = 1;
        nums[4] = 1;
        nums[5] = 1; // ArrayIndexOutOfBoundsException

    }

}
ArrayList 技術分享
import
java.util.ArrayList; public class ArrayListTest { public static void main(String[] args) { /** * 在程序運行過程中,不確定有多少個對象 加入到 集合中! * 使用集合框架! * 現在 我們想 新增 LinkedList * 現在 我們想 查詢 ArrayList * 上述的兩個類 都是 List接口的 實現類! * * 01. ArrayList 底層是實現了一個可變長度(自動擴容)的數組! * 在內存中也是分配連續的空間! * 遍歷元素和隨機訪問元素的時候 性能高! 因為有下標!
*/ // 01創建一個ArrayList集合 ArrayList list = new ArrayList(); /** * 02. 向集合中增加元素 * 為什麽可以存放這麽多數據類型 * 因為底層就是一個Object[]數組 默認的初始長度=10 * Object 所有類的父類,所以可以存放任何類型! * */ list.add(1); list.add("2"); list.add(12.5); list.add(‘5‘); list.add(‘1‘); list.add(null); list.add(7); list.add(8); list.add(9); list.add(10); list.add(11); // 自動擴充 原來長度的1.5倍 // 03.輸出集合的長度 實際使用的位置個數 System.out.println(list.size()); // 04. 查詢集合中下標是3 的元素 System.out.println("集合中下標是3 的元素:" + list.get(3)); // 05. 刪除下標為5的元素 list.remove(5); System.out.println("刪除元素之後的長度:" + list.size()); // 06.查詢集合中是否包含某個元素 System.out.println("集合中是否包含12.5:" + list.contains(12.5)); } }
ArrayListTest

3.LinkedList

技術分享
import java.util.LinkedList;

public class LinkedListTest {

    public static void main(String[] args) {
        /**
         * 02.LinkedList :采用的是鏈表式存儲結構!  插入和刪除的效率高!
         *    
         *    誰能告訴我???
         *    為什麽不使用 
         *   List list = new LinkedList();   父類的引用指向了子類的對象!
         *    
         *   LinkedList list=  new LinkedList();  使用這種方式!
         *   
         *    List  和 LinkedList 什麽關系?
         *      001.LinkedList繼承了List!
         *    List接口中有的方法LinkedList有嗎?  
         *      002. 有
         *    LinkedList中有特有的方法,  List接口中有嗎?  !!!!
         *      003. 沒有!
         *     
         */
        // 創建集合
        LinkedList list = new LinkedList();
        // 創建新聞對象
        News news1 = new News(1, "新聞1");
        News news2 = new News(2, "新聞2");
        News news3 = new News(3, "新聞3");
        News news4 = new News(4, "新聞4");

        // 集合中保存新聞信息
        list.add(news1);
        list.addFirst(news2);
        list.add(news3);
        list.addFirst(news4);

        for (Object object : list) {
            News news = (News) object;
            System.out.println(news);
        }

        // 刪除最後一個對象
        list.removeLast();
        System.out.println("*********************");
        for (Object object : list) {
            News news = (News) object;
            System.out.println(news);
        }
        // 查詢某個元素在集合中的位置
        System.out.println("news4在集合中的位置:" + list.indexOf(news4));

    }
}
LinkedListTest

4.Iterator

技術分享
import java.util.ArrayList;
import java.util.Iterator;

/*
 * 新聞實體類
 */
public class News {

    private int id; // 新聞編號
    private String title; // 新聞標題

    public int getId() {
        return id;
    }

    public void setId(int id) {
        this.id = id;
    }

    public String getTitle() {
        return title;
    }

    public void setTitle(String title) {
        this.title = title;
    }

    public News(int id, String title) {
        super();
        this.id = id;
        this.title = title;
    }

    public News() {
        super();
    }

    @Override
    public String toString() {
        return "News [id=" + id + ", title=" + title + "]";
    }

    public static void main(String[] args) {
        // 創建一個集合
        ArrayList list = new ArrayList();
        // 創建新聞對象
        News news1 = new News(1, "新聞1");
        News news2 = new News(2, "新聞2");
        News news3 = new News(3, "新聞3");
        News news4 = new News(4, "新聞4");

        // 集合中保存新聞信息
        list.add(news1);
        list.add(news2);
        list.add(news3);
        list.add(news4);
        // list.add("aaaaaa");ClassCastException 類型轉換

        // 01.第1種方式 遍歷 for循環
        for (int i = 0; i < list.size(); i++) {
            News news = (News) list.get(i); // 必須向下轉型
            System.out.println(news);
        }
        System.out.println("*****************************");
        // 02.第2種方式 遍歷 for增強循環
        for (Object n : list) {
            News news = (News) n; // 必須向下轉型
            System.out.println(news);
        }
        System.out.println("*****************************");
        /**
         *  03.第3種方式 遍歷 iterator 叠代器循環
         *  
         *  001.hasNext() :判斷我們的集合中是否還有元素
         *  002.next():獲取集合中的下一個元素
         *  003.remove():刪除元素
         */
        // 清空整個集合
        list.clear(); // 底層的數組 長度還是之前的長度!
        // 判斷集合是否為空
        System.out.println("集合是否為空:" + list.isEmpty());
        Iterator it = list.iterator();
        while (it.hasNext()) {
            News news = (News) it.next();// 獲取元素
            System.out.println(news);
        }

    }

}
Iterator

5.Set

技術分享
import java.util.HashSet;
import java.util.Set;

public class SetTest {

    public static void main(String[] args) {
        /**
         * Set :
         *   01.存儲的是唯一(不能重復) 無序的數據!
         *   02.HashSet是常用的實現類
         *   03.存放的是對象的引用
         */

        Set set = new HashSet();
        set.add(1);
        set.add("1");
        set.add(‘1‘);
        set.add(null);
        System.out.println(set.size()); // 輸出集合的大小 4

        Set set2 = new HashSet();
        set2.add(1);
        set2.add(1);
        set2.add(1);
        System.out.println(set2.size()); // 輸出集合的大小 1

        /**
         *  通過觀看底層代碼得知:                                        
            private transient HashMap<E,Object> map; 
             public boolean add(E e) {               
                  return map.put(e, PRESENT)==null;  
              }  
         01.HashSet    類中 有一個屬性是 map  ,值類型是 HashMap
         02.我們在使用add(e) ,其實是調用了map.put(e,PRESENT)
              把e當成了map的key值!
              因為Map的key是唯一的! 所以我們的hashSet存儲的也是唯一的!
         03.那麽怎麽知道    map中的key是唯一的呢? 看hashMap的put()  
         
           String的底層 是 char類型的數組!
           怎麽比較兩個值是否一致?  把char數組中的每一個元素都比較,全相等  才相等!
           
           所以hashMap在添加數據的時候
           01.先進行hash運算
           02.把計算的值當成數組中的下標
           03.判斷下標指向的數組元素是否為空,如果為空 直接 添加數據
           04.如果不為空
                   依次查詢entry中的所有元素
           05.判斷key是否相等
                001.e.hash == hash
                002.(k = e.key) == key || key.equals(k)
              如果相等  直接覆蓋
           不相等 通過next的變量 將值 新增到entry!  
           
           
           
           
           HashSet 和 TreeSet的區別
           
          01. HashSet底層是哈希表實現的!
              TreeSet底層是二叉樹實現的!
          02. HashSet存放的數據是無序的!
              TreeSet存放的數據是有序的!
          03. HashSet可以存放 null!但是只能是一個null!
              TreeSet不可以存放null!
          04. HashSet底層是由HashMap實現! 
              TreeSet底層是由TreeMap實現! 
          05. HashSet是線程不安全的! 單線程是安全!
              TreeSet是線程安全的!   
           
         */

    }

}
set 技術分享
import java.util.HashSet;
import java.util.Set;

import org.junit.Test;

public class StringTest {

    public static void main(String[] args) {

        Set set = new HashSet();
        set.add("1");
        set.add(new String("1"));
        set.add(new String("1"));
        System.out.println(set.size());

        // 疑問? 為什麽 兩次new 確是一樣的
        String a = new String("1");
        String b = new String("1");
        String c = "1";
        System.out.println(a == b);
        System.out.println(a == c);
        // 內容相同的String對象 hashCode是一致的!
        System.out.println(a.hashCode() == b.hashCode());
        System.out.println(a.hashCode() == c.hashCode());
    }

    @Test
    public void test1() {
        String a = new String("1");
        /**
         * 01.首先在棧中開辟空間存儲a
         * 02.去常量池中查詢有沒有 字符串1 沒有就在常量池中創建字符串1
         * 03.再去堆中創建一個字符串1
         * 04.a指向堆中的字符串1
         */
        String b = "1";
        /**
         * 01.首先在棧中開辟空間存儲b
         * 02.去常量池中查詢有沒有 字符串1   有
         * 03.b指向常量池中的字符串1
         */
        System.out.println(a == b); // false
    }

    @Test
    public void test2() {
        String a = "abc";
        String b = "abc";
        System.out.println(a == b); // true
        System.out.println(a == "abc"); // true
    }

    @Test
    public void test3() {
        String a = "abc";
        String b = "a";
        String c = "bc";
        System.out.println(a == ("a" + "bc")); // true
        /**
         * b  和  c  都是變量!!!!!!
         * 在運行期間可以改變的量!
         */
        System.out.println(a == (b + c)); // false
    }

    @Test
    public void test4() {
        String a = "abc";
        final String b = "a";
        final String c = "bc";
        System.out.println(a == ("a" + "bc")); // true
        /**
         * 在編譯期間因為b  和  c  都是常量
         * 所以就把b+c="abc"
         */
        System.out.println(a == (b + c)); // true
    }
}
HashSet

6.Map

技術分享
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.apache.log4j.Logger;
import org.junit.Test;

import cn.bdqn.listtest.News;

public class MapTest {

    public static void main(String[] args) {

        /**
         * Map: 是一個key  value 鍵值對的集合!
         *       key是唯一的!
         * 
         * 存放值:
         *  put(key,value)
         *  
         * 取值
         *   get(key)    根據key獲取value
         */

        Map map = new HashMap();
        map.put(1, "haha1");
        map.put("1", "haha2");
        map.put(new String("1"), "haha3");
        System.out.println(map.size());
    }

    @Test
    public void test1() {
        Map map = new HashMap();
        map.put("news1", new News(1, "新聞標題1"));
        map.put("news2", new News(2, "新聞標題2"));
        map.put("news3", new News(3, "新聞標題3"));
        /**
         * 我們想獲取value的值   只能通過key
         * key是一個集合 就是set
         */
        Set keySet = map.keySet();
        for (Object o : keySet) {
            System.out.println(o); // key
        }
        /**
         * 獲取所有value的集合
         */
        Collection values = map.values();
        for (Object o : values) {
            System.out.println(o); // value
        }

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

        // 直接使用一個循環 獲取value
        for (Object key : keySet) {
            News news = (News) map.get(key); // 根據key獲取value
            System.out.println(news);
        }
        System.out.println("****************************");
        Iterator it = keySet.iterator();
        while (it.hasNext()) {
            News news = (News) map.get(it.next());
            System.out.println(news);
        }

        System.out.println("************ EntrySet()****************");

        /**
         * 強烈推薦使用 EntrySet()
         * 可以在獲取key的同時獲取value!不需要兩次查詢
         */
        Iterator it1 = map.entrySet().iterator();
        while (it1.hasNext()) {
            Entry entry = (Entry) it1.next();
            System.out.println("map中的key:" + entry.getKey());
            System.out.println("map中的value:" + entry.getValue());
        }
    }

    Logger log = Logger.getLogger(MapTest.class);

    @Test
    public void test2() {
        Map map = new HashMap();
        for (int i = 1; i <= 200000; i++) {
            map.put(i, "" + i);
        }
        System.out.println("map的大小:" + map.size());

        // 獲取當前的毫秒數 從1970年1月1日到現在的毫秒
        long start = System.currentTimeMillis();
        Set keySet = map.keySet();
        for (Object key : keySet) {
            System.out.println(map.get(key));
        }
        long end = System.currentTimeMillis();
        log.debug("使用for循環的用時:" + (end - start));

        start = System.currentTimeMillis();
        Iterator iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Entry entry = (Entry) iterator.next();
            System.out.println(entry.getValue());
        }
        end = System.currentTimeMillis();
        log.debug("使用Iterator循環的用時:" + (end - start));
    }

    /***
     * 
     *  HashMap 和  HashTable 的區別
     *   01.HashMap    線程不安全 但是性能高
     *      HashTable  線程   安全 但是性能低
     *   02.HashMap 底層是哈希表實現的,每一個元素一個key -value鍵值對!
     *        key和value都可以為null!
     *      HashTable的key和value都不可以為null!
     *   03.歷史版本不同
     *      HashMap    1.2
     *      HashTable  1.0
     */
}
MapTest

7.泛型

技術分享
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import org.junit.Test;

import cn.bdqn.listtest.News;

public class MyTest {

    @Test
    public void test01() {
        ArrayList list = new ArrayList();
        // list中可以存放什麽類型! Object 所有類型
        list.add(1);
        list.add("1");
        list.add(new Date());
        /**
         *  我們怎麽去遍歷這些類型的數據
         *  01.集合中的數據不是相同類型
         *  02.不能按照一種方式去遍歷
         */

        Set set = new HashSet();
        set.add(1);
        set.add("1");
        set.add(new Date());

        Map map = new HashMap();
        map.put(1, "1");
        map.put("1", "haha");
        map.put("2", new Date());

        /**
         * 上面三個 集合 
         * 01.因為我們沒有在創建集合的同時 規定集合中可以存放什麽類型的數據
         * 02.所以集合中可以存放Object類型的數據
         * 03.導致後續操作很麻煩
         * 04.如果我們想獲取集合中的某個元素,需要使用get()
         * 05.但是get()返回值是 object類型
         * 06.需要向下轉型,轉換成指定的類型,之後才能操作!
         * 
         * 
         * 有沒有一種方式,
         * 01.可以在創建集合的時候,規定集合中只能存放什麽類型
         * 02.能不能在get()不進行向下轉型!!!
         * 
         * 能!
         * 使用泛型!
         * 泛型集合:  創建集合的時候,規定集合中存放數據的類型!
         * 
         */

    }

    /**
     *  使用泛型集合   方便+安全
     *  <> 就是集合中指定的元素類型!
     *  
     *  泛型集合中 不允許 存放基本數據類型的元素!
     *  如果想存放基本數據類型!
     *  必須使用基本數據類型對應的 包裝類
     *  
     *  java中有8種基本數據類型,使用ctrl+鼠標左鍵   點不進去! 說明不是類
     *   
     *  那就有8個對應的包裝類!
     *  byte    Byte
     *  short   Short
     *  int     Integer        
     *  long    Long
     *  float   Float
     *  double  Double
     *  
     *  boolean  Boolean
     *  char     Character
     *  
     */
    @Test
    public void test02() {
        ArrayList<String> list = new ArrayList<String>();
        // 說明list集合中只能存放String類型的數據
        // list.add(new Date()); 編譯報錯
        ArrayList<News> list2 = new ArrayList<News>();
        // list2集合中 只能存放 News 對象!
        ArrayList<Double> list3 = new ArrayList<Double>();
        list3.add(2.0);

        double a = 2;
        // Double b = 2; 編譯報錯
    }

    @Test
    public void test03() {
        /**
         * 創建了一個map泛型集合!
         * 集合的key只能是String類型
         * value只能是News類型!
         * 
         * map.put(1,"1"); 錯誤
         * map.put("1","1"); 錯誤
         * map.put("1",new News());
         */
        Map<String, News> map = new HashMap<>();
        News news1 = new News(1, "新聞1");
        News news2 = new News(2, "新聞2");
        News news3 = new News(3, "新聞3");
        map.put("a", news1);
        map.put("b", news2);
        map.put("c", news3);

        // 遍歷出來所有的新聞信息
        Iterator<Entry<String, News>> iterator = map.entrySet().iterator();
        while (iterator.hasNext()) {
            Entry<String, News> entry = iterator.next();
            // System.out.println(entry.getKey()); 獲取所有的key
            News news = entry.getValue(); // 獲取所有的value
            System.out.println(news);
        }

    }
}
泛型

java高級⑴