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();
            }       
      }
}

猜你喜欢

转载自blog.csdn.net/xd_fybdw/article/details/78685929