JAVA學習第三篇:集合框架

1,集合框架是java提供的方便用戶存儲數據工具,通過使用集合框架,開發者可以省去大量的時間在基礎的數據結構設計上,從而提高開發效率

2,集合框架分爲Collection 和 Map,其中Collection包括Set,List,Queue。並且所以的Collection類都可以通過Iterator進行迭代。Map保存的是key-value,在Map中key是不能重複的,value是可重複的。所以利用代碼的重用性,Map將所有的value置爲空就是Set, key不能重用,但value可以重複,這就是List。Map實現的子類有HashMap

3,Set詳解

Set中不能包含相同元素,在此處的相同元素通過equals()方法判斷。所以在元素重寫equals()方法時,開發者需要特別的小心。

3.1 HashSet是Set的實現類,HashSet判斷元素的相等是通過equals()和hashCode()判斷,既equals()相等且hashCode()相等,則元素相等。當元素相等時,HashSet將拒絕加入該元素。在HashSet中元素的排列順序是根據hashCode()返回值決定的。如

class A {
    @Override
    public boolean equals(Object obj) {
        return true;
    }
}

class B {
    @Override
    public int hashCode() {
        return 100;
    }
}

class C{
    @Override
    public int hashCode() {
        return 2000;
    }
    @Override
    public boolean equals(Object obj) {
        return true;
    }
}


public static void main(String[] args) {

        A a1=new A();
        A a2=new A();
        B b1=new B();
        B b2=new B();
        C c1=new C();
        C c2=new C();
        
        HashSet books=new HashSet<>();
        books.add(a1);
        books.add(a2);
        books.add(b1);
        books.add(b2);
        books.add(c1);
        books.add(c2);
        System.out.println(books);

}

在main方法中,books集合增加了多個元素,其中A重載了equals()方法,因爲HashSet判斷兩個元素相等是通過equals()和hashCode()判斷,所以,一個equals()返回true不會導致下一個元素不能加入。從而,兩個A都被加入books。同理B只重載了hashCode()方法而沒有重載equals()方法,所以兩個B 都加入進來了。而C類因爲重載了兩個方法,並且返回值固定,equals()返回true,hashCode()返回2000,所以HashSet認爲這兩個C相同,只能加入一個C,最後結果是

[com.collection.A@7852e922, com.collection.C@7d0, com.collection.B@64, com.collection.B@64, com.collection.A@4e25154f]

3.2  LinkedHashSet繼承自HashSet,同樣,LinkedHashSet判斷兩個元素相等需要equals()和hashCode()兩個方法,但是元素排序時是根據插入順序決定的,先插入的在前,後插入的在後。如

       LinkedHashSet notes=new LinkedHashSet<>();
        notes.add(a1);
        notes.add(a2);
        notes.add(b1);
        notes.add(b2);
        notes.add(c1);
        notes.add(c2);
        System.out.println(notes);

同HashSet一樣,notes將加入兩個A,兩個B,一個C,它加入的順序如下

[com.collection.A@7852e922, com.collection.A@4e25154f, com.collection.B@64, com.collection.B@64, com.collection.C@7d0]

對比HashSet,a2插入在第二個。由此可見,LinkedHashSet的順序就是插入順序。

3.3 TreeSet 繼承Set,在TreeSet中的所有元素都將被排好序,從大到小升序排列,是一棵紅黑樹。如

        TreeSet trees=new TreeSet<>();
        trees.add(2);
        trees.add(6);
        trees.add(1);
        trees.add(4);
        trees.add(4);
        trees.add(10);
        System.out.println(trees);

將輸出

[1, 2, 4, 6, 10]

其中重複的4被忽略。在TreeSet中有幾實用方法,first()返回第一個元素,last()返回最後一個元素,headSet(5)返回小於5的元素且不包括5,tailSet(5) 返回大於5的元素幷包括5,subSet(1,3)返回[1,3)的元素。

3.4 EnumSet直接繼承Set,但是無法直接new出來,他的初始化方法包括以下幾個

        enum e{
                 a,b,c,d
        }

        EnumSet seasons=EnumSet.allOf(e.class);
        System.out.println(seasons);
        seasons=EnumSet.noneOf(e.class);
        seasons.add(e.b);
        seasons.add(e.c);
        System.out.println(seasons);
        seasons=EnumSet.of(e.a,e.a);
        System.out.println(seasons);

4. List詳解

在List中,允許重複元素,在元素插入的過程中,List會給每個插入的元素設置索引,通過該索引List可以很快的找到該元素

4.1 ArrayList 繼承List,他通過動態的分配內存而增加元素。如下

        ArrayList books=new ArrayList<>();
        books.add("b1");
        books.add("b2");
        books.add("b3");
        books.add("b4");
        books.add("b5");
        books.add("b6");
        books.add("b7");
        System.out.println(books);

最終的結果是

[b1, b2, b3, b4, b5, b6, b7]

該打印順序與插入順序一致。同時ArrayList提供了一些可用的方法,如

        books.add(1,"insert before b2");
        System.out.println(books);

        //  [b1, insert before b2, b2, b3, b4, b5, b6, b7]

        books.remove(2);
        System.out.println(books);

        // [b1, insert before b2, b3, b4, b5, b6, b7]

       
        books.set(4, "replace b5");
        System.out.println(books);

        //  [b1, insert before b2, b3, b4, replace b5, b6, b7]


        System.out.println(books.subList(0, 4));

        //  [b1, insert before b2, b3, b4]

4.2 Stack繼承Vector,而Vector繼承List,在Stack中,元素遵循後進先出的原則,具體如下

        Stack stack=new Stack<>();
        stack.push("s1");
        stack.push("s2");
        stack.push("s3");
        stack.push("s4");
        System.out.println(stack);

        //  [s1, s2, s3, s4]

      
        System.out.println(stack.peek());

        // s4

        System.out.println(stack);

        // [s1, s2, s3, s4]

       
        System.out.println(stack.pop());

        // s4

        System.out.println(stack);

       //[s1, s2, s3]

peek()方法返回棧頂元素,但並不彈出。而pop()方法返回並彈出棧頂元素。

4.3 LinkedList是繼承List,是一個雙向的隊列。初始化如下;

        LinkedList dequeue = new LinkedList<>();
        dequeue.offer("d1");
        dequeue.push("d2");
        dequeue.offerFirst("d0");
        dequeue.offerLast("d3");
        System.out.println(dequeue);

輸出

[d0, d2, d1, d3]

在目前的研究中發現,offerFirst()和push()實現同樣功能,offerLast()和offer()實現相同功能。

5 Queue詳解

隊列是一種先進先出的數據結構,不允許隨機訪問元素

5.1 PriorityQueue繼承Queue。具體使用如下

        PriorityQueue queue=new PriorityQueue<>();
        queue.add("q1");
        queue.add("q2");
        queue.add("q3");
        queue.add("q4");
        queue.add("q5");
        System.out.println(queue);

        // [q1, q2, q3, q4, q5]

       
        System.out.println(queue.poll());

        //q1

        System.out.println(queue);

        //[q2, q4, q3, q5]

poll()方法將隊首元素出隊列,並且在隊列中刪除該元素。

5.2 ArrayQueue基於數組的隊列,所以隨機訪問快,具體如下

        ArrayDeque stack=new ArrayDeque<>();
        stack.push(1);
        stack.push(2);
        stack.push(4);
        stack.push(3);
        System.out.println(stack);

        // [3, 4, 2, 1]

       
        System.out.println(stack.peek());

       //3

        System.out.println(stack);

        //[3, 4, 2, 1]       
        System.out.println(stack.pop());

        //3

        System.out.println(stack);

        //[4, 2, 1]

6 迭代Collection

每一種Collection的實現類都有iterator()方法,通過該方法可以迭代該集合,如;

        ArrayList a=new ArrayList<>();
        a.add(1);
        a.add(2);
        Iterator iterator= a.iterator();
        while(iterator.hasNext()) {
            System.out.println(iterator.next());
        }

最終輸出1,2

7 Map實現的子類

7.1 HashMap 和HashTable,這兩個子類通過equals()和hashCode()方法一起判斷元素是否相等。

class MapA {
    int count;

    public MapA(int count) {
        this.count = count;
    }

    @Override
    public int hashCode() {
        // TODO Auto-generated method stub
        return count;
    }

    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
        return true;
    }

}

class MapB{

    @Override
    public boolean equals(Object obj) {
        // TODO Auto-generated method stub
        return true;
    }
    
}
       

main方法如下;

        MapA a = new MapA(100);
        MapA a2 = new MapA(100);
        HashMap map = new HashMap<>();
        map.put(a, "1");
        map.put(a2, "2");
        System.out.println(map);
        
        MapB b=new MapB();
        MapB b2=new MapB();
        Hashtable taHashtable=new Hashtable<>();
        taHashtable.put(b, "1");
        taHashtable.put(b2, "2");
        System.out.println(taHashtable);

輸出

{com.collection.MapA@64=2}
{com.collection.MapB@4e25154f=2, com.collection.MapB@7852e922=1}

此處原理和HashSet一樣。

7.2 LinkedHashMap是Map的鏈式存儲方式。能夠快速的增加和刪除元素。

        LinkedHashMap linkedHashMap=new LinkedHashMap<>();
        linkedHashMap.put("a", 100);
        linkedHashMap.put("b", 89);
        for(Object key:linkedHashMap.keySet()) {
            System.out.println(key+"-->"+linkedHashMap.get(key));
        }

輸出如下

a-->100
b-->89

7.3 Properties,該對象可以用來讀寫配置文件,如

        Properties properties=new Properties();
        properties.setProperty("username", "wudi");
        properties.setProperty("password", "123456");
        System.out.println(properties);
        try {
            properties.store(new FileOutputStream("test.txt"), "suit yourself");
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

控制檯輸出

{password=123456, username=wudi}

刷新工程項目後,在src下會多一個test.txt文件。如下圖



其中test.txt文件如下

一般我們看見的xml文件,也可以直接使用Properties進行讀寫


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