集合与遍历 Debug (Collection工具类,HashSet,Map)

一。比较器
    作用:比较大小的

    Collections.sort(List<?> list)
    如果调用该功能,那么我们需要注意,
    这个功能 采用默认的比较规则进行对象之间的比较排序。
    什么是默认的规则呢,这就要求集合中的元素类型
    去实现一个叫做Comparable接口,其实是为了实现里面
    compareTo()功能,这个功能中就定义了比较的规则。

    那么反过来 如果集合中元素类型 没有实现Comparable比较器,那么就不能这样去用
    如果这样去用 会编译报错,这个一会存储自定义类的时候来演示。

    比较器有两种 
      内比较器 Comparable 
         他是让对象自身具备比较的功能

      外比较器 Comparator
         可以理解为一个工具,是用来对对象比较的工具。
         
      
      如果你同时可以使用内比较器和外比较器,会将内比较器给屏蔽,我们使用的是外比较器。
      

    如果我们要进行对象间的比较,那么就需要实现比较器接口,内比较器,外比较器

    java提供了两种  比较规则  的实现
       一种 在定义类的时候,进行对java.lang.Comparable接口进行实现,并且完成对compareTo方法的实现
            比较的规则就定义在compareTo方法中,比如String,Integer等类
       
       另外一种比较灵活,你可以在定义类的时候不去实现内比较器接口,在需要比较的地方,直接去实现比较
       的规则就可以,怎么实现比较规则呢,其实JDK中方法,它会需要一个参数 Comparator接口,我们一般写
       匿名内部类完成,其实关注的不是接口不是对象,而是比较的规则,这个接口中就需要你重写一个规则方法
       compare方法


    区别  
       内比较器 Comparable 
           比较方法 
             compareTo(T t)
          以比较数字类型来说 
            当前的-传进来的的  升序
            传进来的-当前的    降序
           
           什么时候用的呢? 一个类定义的时候实现内比较器。
              当一个类定义的时候就已经产生了比较的规则,实现了Comparable即可并完成conpareTo方法的定义
              实现这个接口的类 天生就具备了比较的规则 但是这种定义比较固定 不灵活
          适用于永远不改变的规则


       外比较器 Comparator
           比较方法
            compare(T t1,T t2)
          以数字为例
             t1数字值-t2数字值  升序
             t2数字值-t1数字值  降序

           1:它适用于原来我的类没有比较的规则,而现在我需要进行比较,想要进行比较,只能利用这个外比较器接口
            进行比较 Collections.sort(List<T> list,new 匿名内部类 )重点是完成比较的规则

           2:原有的比较规则,不喜欢了,或者不适用当前的场景了,而有不能改源码,那么在使用的地方临时修改成
              最新的规则 那么可以采用外比较器的方式。


        内比较器和外比较器实现的功能都是一样的。只不过实现的方式不一样。    
        
        无论是内比较器或者外比较器,实现的方法都是int类型的值:
            有三个情况:
                >  0 :是一个对象的属性值大于了另外一个对象的属性值。
                    如果是正序:在后面
                    如果是倒序:在前面
                    
                == 0 :两个比较的结果是相等的, 正常添加
                
                <  0 :是一个对象的属性值小于了另外一个对象的属性值。
                    如果是正序:在前面
                    如果是倒序:在后面
            

        public class Demo03Sort {

            public static void main(String[] args) {
                ArrayList<Student> list = new ArrayList<>();

                list.add(new Student("马尔扎哈",17));
                list.add(new Student("a尔扎哈",17));
                list.add(new Student("古力娜扎",16));
                list.add(new Student("迪丽热巴",18));

                System.out.println("排序前:"+list);

                //排序规则是 按照年龄降序排列

                Collections.sort(list, new Comparator<Student>() {
                    @Override
                    public int compare(Student o1, Student o2) {
                        int temp = o2.getAge()-o1.getAge();//按照年龄进行降序排列
                        //按照姓名进行升序排列
                        temp = (temp == 0) ? o1.getName().compareTo(o2.getName()) : temp;
                        return temp;
                    }
                });

                System.out.println("排序后:"+list);
            }
        }

        
二.Map<K,V> :双列集合的根接口
    K:键 -> 是唯一的
    Va:值 -> 可以重复
    
    键和值得关系是映射,一个键映射一个值。
    
        
    HashMap<K,V> :
        底层是使用哈希表结构,Map集合是以键为主,键是唯一的,而且存储元素是无序。
        
        底层算法和HashSet集合是同一套算法。实现方式也是一样。包装Map集合中的键唯一:
            需要去重新hashCode和equals方法。
        
        
    特点:
         1:键唯一 值可以重复
         2:键和值一一映射 也就是一个键对应一个值
         3:通过键找到值  (通过键维护关系)

      常见的子类
       HashMap<K,V>
       LinkedHashMap<K,V>:可以保证存和取得顺序是一致的

      常见的方法
        public V put(K key,V value) :将指定的键与对应的值 存储到Map集合中
            如果key在集合中没有,那么添加一个新的键
            如果key代表的键在集合中已经存在,那么会将原有的值给覆盖掉。
            
            V:被替换的值。如果是第一次添加返回的是null

        public V remove(Object key) : 通过指定的键 删除其在Map中的映射关系 返回被删除的映射关系中的值
                返回的是被删除键映射的值
                
        public int size() 获取 Map集合中 存储的 映射关系  有几个

        public Set<K> keySet() : 获取键集 (就是所有键的集合 Set)

        public Collection<V> values : 获取值集

        public V get(Object key) :根据键找对应的值
                返回的是,键对应的值。
                
        public boolean containsKey(Object obj):判断指定键是否存在
        
    面试题:
    
        HashMap 和 Hashtable :
            HashMap可以存储null键和null值
                线程不安全的,效率高
                
            Hashtable 不可以存储null键和null值
                线程安全的,效率低。
            
            
        eg:
            Map<String,String> map = new HashMap<>();
            map.put(null,null);
            map.put("aaa",null);
            System.out.println(map);

            Hashtable<String,String> table = new Hashtable<String,String>();
            table.put(null,null);  //NullPointerException异常
            table.put("aaaa",null);  //NullPointerException异常
            System.out.println(table);
            
            
    a> Map集合的遍历方式:
        1.通过Map中的 Set<K> keySet();获取所有的键
            通过对Set集合进行遍历,拿到每一个键,通过Map集合中 V get(Object k);
            
        
        
    b> 接口 Map.Entry<K,V>    
    
         K getKey() 
              返回与此项对应的键。 
              
         V getValue() 
                  返回与此项对应的值。

    c> 如何获取Map集合中的Entry对象。
        在Map集合中有个方法可以获取: Set<Map.Entry<K,V>> entrySet();

        Map集合遍历方式二
         通过键值对对象方式遍历
           思路
             1:通过entrySet方法,获取所有的Entry(键值对)对象,存放在Set集合中
             2:遍历Set集合 得到每一个Entry对象
             3:根据对应方法 获取每一个Entry中对应的键与对应的值
        
        
        
        
    d>  Java 9,添加了几种集合工厂方法,更方便创建少量元素的集合、map实例。
        新的List、Set、Map的静态工厂方法可以更方便地创建集合的不可变实例。
          of(...)方法 重载方法

          1:of()方法只是Map,List,Set这三个接口的静态方法,
             其父类接口和子类实现并没有这类方法,比如    HashSet,ArrayList等;

          2: 返回的集合是不可变的;    
            
            
    e>   Debug调试
          1:加断点
          2:debug模式执行
          3:追踪

         左侧 是 正在运行的方法
            代码向下执行一行 快捷键F8
            进入要调用的方法中 快捷键 F7
            运行完所有程序  快捷键F9
            停止Debug模式 快捷键 ctrl+F2
            切换控制台Console 查看运行操作结果

         右侧
             变量值 显示区域    
        
    f>  将set转换成list集合进行遍历(两种方法)
            A:  ArrayList<Integer> list = new ArrayList<>();
                list.add(setName);
            B:  ArrayList<Integer> list = new ArrayList<>(setName);

猜你喜欢

转载自blog.csdn.net/snack_TC_dora/article/details/81089131