JAVA基础知识点18-List 与 Set之间的区别、TreeSet、HashSet、Map<K,V> 接口、HashMap、Hashtable、TreeMap、内外部比较器

List 与 Set之间的区别:
    都是Collection接口的子接口,可以存储多个数据,但是每个数据只能为一个值
    都继承了Collection的能力
    List 有序可重复,拥有一些可以根据索引操作的方法
    Set  无序不可重复
        去重逻辑: e1.equals(e2)的返回值决定,和最多一个null元素。

    HashSet     --> HashMap
    TreeSet     --> TreeMap  -->TreeSet是由TreeMap维护的,是Map的key
        底层结构: 红黑树结构
        特点: 数据会升序排序,去重
Set<String> set = new HashSet<>();

 

TreeSet 存储数据是默认升序排序
    但是要求: 数据是能够比较大小的
    存储数据,可以指定当前使用哪种比较规则(外部比较器),如果没有指定默认使用找内部比较规则(内部比较器),如果内部外部都没有就抛出异常
    ClassCastException : 类型转换异常
    去重和排序都是根据比较负责决定
    Set遍历方式都与Collection方式相同

排序方式:
1.Comparable 自然排序|内部比较器|自然比较器|默认比较规则:
        此接口对实现它的每个类的对象强加一个总排序。 这种排序被称为类的自然顺序 ,类的compareTo方法被称为其自然比较方法 。
        使用方式:一个自定义的引用数据类型实现Comparable接口,重写compareTo,在重写方法中指定当前类型数据的比较规则

  注意: 内部比较器属于硬编码编程习惯,每次要修改都要修改javabean类的源码,不够灵活,没办法在不同的业务员下根据不同的规则比较
2.外部比较器|定制排序
    比较规则定义值javabean类的外部
    实现方式: 实现类实现Compatator接口,重写int compare(T o1, T o2) 比较它的两个参数的顺序。定制比较规则
    推荐使用: 软编码习惯
TreeSet<String> set = new TreeSet<>();

System.out.println("--------------------------------------------");
        //遍历
        for(Employee employee:set2){
            System.out.println(employee);
        }

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

        //迭代器
        Iterator<Employee> it = set2.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

 

外部比较器: 通过Comparator接口的实现类重写compare方法定义比较规则,这个实现类没有类原本自己的作用,可以选择使用匿名内部类简化

lambda可以用来简化匿名内部类:
    前提: 接口为函数式接口@FunctionalInterface
    (参数列表)->{重写的方法体}
注意: 要对自定义引用数据类型进行 排序的位置,都需要指定比较规则|比较器问题
    Arrays.sort()
    TreeSet
    TreeMap
    Coolections.sort()
//匿名内部类
        Comparator<Employee> com = new Comparator<Employee>() {
            @Override
            public int compare(Employee o1, Employee o2) {
                return o1.getAge()-o2.getAge();
            }
        };
//lambda
        com = (Employee o1, Employee o2)->{
            return o1.getAge()-o2.getAge();
        };
        com = (o1,o2)->{
            return o1.getAge()-o2.getAge();
        };
        com = (o1,o2)-> o1.getAge()-o2.getAge();


        //构建集合,指定使用参数比较规则排序去重
        //参数为匿名内部类对象
        //TreeSet<Employee> tree = new TreeSet<Employee>(com);

        /*TreeSet<Employee> tree = new TreeSet<Employee>(new Comparator<Employee>() {
            @Override
            public int compare(Employee o1, Employee o2) {
                return o2.getAge()-o1.getAge();
            }
        });*/
        //方法的形参为函数式接口类型,方法的实参就可以使用lambda传递
        TreeSet<Employee> tree = new TreeSet<Employee>((o1,o2)-> o1.getAge()-o2.getAge());


//外部比较器


class Demo implements Comparator<Employee>{
    @Override
    public int compare(Employee o1, Employee o2) {
        return o2.getName().compareTo(o1.getName());
    }
}

 

HashSet ->是由HashMap维护的
    多个数据每个数据是单个值, 无序,去重
    底层: 哈希表(数组+链表+红黑树)
    优点: 查询,增删效率高
    缺点: 无序
    去重: 需要类型中重写hashcode和equals方法,根据对象的内容计算,而非地址计算hashcode和equals
    hashcode和equals之间的规律特点:
        equals相等的hashcode肯定相等
        hashcode相等的equals不一定相等
Map<K,V> 接口
    存储键值对类型的数据
    K-V 之间存在映射关系

    K : 唯一的,无序的  --> Set
    V : 可重复,无序的  --> Collection
    K,V 都可以为任意数据类型

注意:
    Map的去重,根据key做去重的
    添加数据,如果key相同,value会覆盖
    key,与 valuedo都可以赋值为null
    一个key只能对应一个value,但是可以把多个value值放入集合中,一个key对应一个集合

遍历方式:
    1.keySet()  返回当前map集合中的所有键值对的key
    2.values()  获取当前集合中所有键值对的value值
    3.entrySet() 把map中的每一个键值对返回成为一个Map.Entry类型的数据放入set集合

 

System.out.println("-----------keySet---------------");
        Set<String> set =  map.keySet();
        for(String key:set){
            System.out.println("key = "+key+",value = "+map.get(key));
        }

System.out.println("-----------values---------------");
        Collection<Integer> col = map.values();
        Iterator<Integer> it = col.iterator();
        while(it.hasNext()){
            System.out.println(it.next());
        }

        //Set<Map.Entry<K,V>> entrySet() 返回此映射中包含的映射的Set视图。
System.out.println("-----------entrySet---------------");
        Set<Map.Entry<String,Integer>> set2 = map.entrySet();
        for(Map.Entry<String,Integer> entry:set2){
            System.out.println(entry.getKey()+"-->"+entry.getValue());
        }
HashMap:
    底层实现: 哈希表
    特点: 查询,增删效率高
    初始容量: 内部位桶数组的大小  16
    加载因子loadFactor : 0.75
    threshold :临界值(阀值) = 容量*加载因子
    size: 集合中存储键值对的个数
    扩容: 每次扩容原容量2倍    newCap = oldCap << 1
    构造器:
        HashMap() 使用默认初始容量(16)和默认加载因子(0.75)构造一个空 HashMap 。
        HashMap(int initialCapacity) 使用指定的初始容量和默认加载因子(0.75)构造一个空 HashMap 。
        HashMap(int initialCapacity, float loadFactor) 使用指定的初始容量和加载因子构造一个空 HashMap 。
        HashMap(Map<? extends K,? extends V> m)

   可以存储null值作为key和value
   线程不安全,不同步

Hashtable
    线程安全的Hash表,与HashMap非常像
    Hashtable是同步的|线程安全的。 如果不需要线程安全实现,建议使用HashMap代替Hashtable 。 如果需要线程安全的高度并发实现,则建议使用ConcurrentHashMap代替Hashtable 。
    不能存储null值作为key和value
    初始容量为11 ,加载因子0.75, 每次扩容原容量的2倍+1
TreeMap --> TreeSet是由TreeMap的key维护的
 底层: 红黑树

 特点: 自动根据key做升序排序
 去重存储: 如果存储的是java提供的引用类型,java提供比较规则,不用管直接用
           如果存储的是自定义提供的引用类型,自己实现比较规则


注意:Map的去重..都是根据键值对的key操作

比较规则:
 内部比较器 Comparable
 外部比较器 Comparator

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值