Java集合(2)

一、Set接口介紹
Set接口繼承Collection接口,而且它不允許集合存在重複項,每個具體的Set實現類依賴添加對象的equlas()和hashCode()方法來檢查獨一性。Set接口沒有引入別的方法,所以Set就是一個Collection,只不過其行爲不同。
二、具體的Set接口的實現
2.1HashSet
HashSet把數據存儲在哈希表中 。哈希表是一種數據結構,用來查找對象。Hash表爲每一個元素計算一個整數,稱爲HashCode(哈希碼)。
Hash底層給個數組,
如將自定義類用 hashSet 來添加對象,一定要覆蓋 hashcode()和 equals(),覆蓋的原則是保證當兩個對象 hashcode 返回相同的整數,而且 equals()返回值爲 True。
重點內容
使用 hashSet 的優點:
hashSet 的底層是數組,其查詢效率非常高。而且在增加和刪除的時候由於運用的 hashCode 的比較開確
定添加元素的位置,所以不存在元素的偏移,所以效率也非常高。因爲 hashSet 查詢和刪除和增加元素
的效率都非常高。
但是 hashSet 增刪的高效率是通過花費大量的空間換來的:因爲空間越大,取餘數相同的情況就越小。
HashSet 這種算法會建立許多無用的空間。
使用 hashSet 接口時要注意,如果發生衝突,就會出現遍歷整個數組的情況,這樣就使得效率非常的

public void test2(){
        Set<Integer> set1 = new HashSet<Integer>();
        for(int i=0; i<20; ++i){
            set1.add(i);
        }

        Iterator<Integer> it = set1.iterator();
        while(it.hasNext()){
            System.out.print(it.next() + " ");
        }
        System.out.println();
    }
注意:1.打印set和你插入的數據的順序不一樣!
 * 2.set裏面放自定義類型的對象,一定要重寫兩個函數(equals()  hashCode())!否則會出現違背Set中不允許元素重複的原則的情況。  

2.2TreeSet
TreeSet是SortedSet的子類,它不同於HashSet的根本就是TreeSet是有序的,是通過SortedMap來實現的。TreeSet放入其中的元素按序存放,這就要求你放入其中的對象是可排序的,一個類是可排序的,它就是實現了Comparable接口。

練習代碼:重寫了Compare方法。使其按從大到小存儲;
public void test5(){
        SortedSet<Number> set1 = new TreeSet<Number>(new Comparator<Number>(){
            public int compare(Number o1,Number o2){
                int res=o1.getValue()-o2.getValue();
                return res>0?-1:(res==0?0:1);   
            }   
        });
        for(int i=20; i>0; --i){
            set1.add(new Number(i));
        }

        Iterator<Number> it = set1.iterator();
        while(it.hasNext()){
            System.out.print(it.next() + " ");
        }
        System.out.println();
    }

重點內容
HashSet VS TreeSet: HashSet 非常的消耗空間, TreeSet 因爲有排序功能,因此資源消耗非常的高,我們應該儘量少使用,而且最好不要重複使用。
基於以上原因,我們儘可能的運用 HashSet 而不用 TreeSet,除非必須排序。
2.3LinkedHashSet
LinkedHashSet是一個鏈式哈希集合,LinkedHashSet存儲的元素順序和元素插入的順序是一樣的!

練習代碼:
public void test3(){
        System.out.println("test3:");
        Set<Integer> set1 = new LinkedHashSet<Integer>();
        for(int i=0; i<20; ++i){
            set1.add(i);
        }

        Iterator<Integer> it = set1.iterator();
        while(it.hasNext()){
            System.out.print(it.next() + " ");
        }
        System.out.println();
    }

三、Map接口
Map接口不是Collection接口的繼承。Map接口用於維護鍵/值對,該接口描述了從不重複的到值的映射。
重點內容
注: HashMap 底層也是用數組, HashSet 底層實際上也是HashMap, HashSet 類中有 HashMap 屬性(我們如何在 API 中查屬性)。 HashSet 實際上爲(key.null)類型的 HashMap。有 key 值而沒有 value 值。
HashMap應用

舉例:
請隨機10000個整數,放在LinkedList的裏面  0-200之間的隨機數
請問:如何快速的找出重複次數最多的一個?重複了幾次
請問:如何快速的找出重複次數最多的n個?分別重複了幾次
//測試用例一:重複次數最多的一個
public class TestHashMapDemo {
    @Test
    public void testHashMap(){
        LinkedList<Integer> list=new LinkedList<Integer>();
        for(int i=0;i<10000;i++){
            list.add((int)(Math.random()*200)); 
        }
        LinkedHashMap<Integer, Integer> hashMap = new LinkedHashMap<Integer, Integer>();

        for(Integer key:list){
            Integer value=hashMap.get(key);
            if(value==null){
                hashMap.put(key, 1);
            }
            else{
                hashMap.put(key, value+1);  
            }
        }   
        Integer max=0;
        Integer key=null;
        Iterator<Entry<Integer, Integer>> it = 
                hashMap.entrySet().iterator();
        while(it.hasNext()){
            Entry<Integer,Integer> entry = it.next();
            Integer max1 =entry.getValue();
            Integer key1= entry.getKey();
            if(max1.compareTo(max)>0){
                max=max1;
                key=key1;       
            }   
        }
        System.out.println("重複次數最多的是"+key+"重複了多少次:"+max);

     }


    //測試用例二:重複次數最多的10個
    @Test
    public void testHashMapMaxTen(){
        LinkedList <Integer> list=new LinkedList<Integer>();
        for(int i=0;i<10000;i++){
            list.add((int)(Math.random()*200));
        }
        LinkedHashMap<Integer, Integer> hashMap = new LinkedHashMap<Integer, Integer>();  
        for(Integer key:list){
            Integer value=hashMap.get(key);
            if(value==null){
                hashMap.put(key, 1);
            }
            else{
                hashMap.put(key, value+1);  
            }
        }
//自定義類要排序,利用Compartor接口,實現compareTo方法;
        PriorityQueue<Entry<Integer,Integer>> queue=new PriorityQueue<Entry<Integer,Integer>>(10, new Comparator<Entry<Integer,Integer>>(){
            public int compare(Entry<Integer,Integer> q1,Entry<Integer,Integer> q2){
                return (q1.getValue().compareTo(q2.getValue())>0)?1:(q1.getValue().compareTo(q2.getValue())==0?0:-1);

            }   
        });
        Iterator<Entry<Integer, Integer>> it = 
                hashMap.entrySet().iterator();
        int count=0;
        while(it.hasNext()){
            //int count=0;
            Entry<Integer,Integer> entry = it.next();
            count++;
            if(count<=10){
                queue.add(entry);
            }
            else{
                Integer data=queue.peek().getValue();  //peek返回頭部元素
                if(entry.getValue().compareTo(data)>=0){
                    queue.remove();
                    queue.add(entry);
                }
            }
       }
        while(!queue.isEmpty()){
            Entry<Integer, Integer> data= queue.peek();
            System.out.print("key:"+data.getKey()+" "+"value:"+data.getValue());

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

發佈了33 篇原創文章 · 獲贊 8 · 訪問量 8818
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章