day16_集合_Set

一、Set

1.1介绍

  • Set是Collection的子接口
  • 规定所存储的元素是不允许重复,且无序
    • HashSet的无序是将存储的元素随机排序
    • TreeSet的无序是指将存储的元素给排序了
  • Set接口一般常用两个实现类
    • HashSet,存储的元素是无序且去重
    • TreeSet,存储的元素是去重且排序

二、HashSet

是接口的实现类,存储的元素是无序且去重,不保证线程安全

2.1方法演示

HashSet() 空参构造,创建空集合

HashSet(Collection c)创建带元素的集合,里面的初始值就是传入的集合


方法都是常规方法,没有关于下标的操作

  • boolean add();添加时返回值是boolean型,判断里面是否有,有就返回false
  • 同样List有的Set也有,如:size、isEmpty、contains、clear
  • 加入的元素没有顺序

2.2底层实现原理

  • HashSet底层是HasnMap,而HashMap底层是哈希表
    • 创建HashSet时就会创建HashMap
    • 添加元素到HashSet也会put到Map中
  • HashSet或者HashMap创建时,默认容量16,加载因子0.75
    • 容量就是存储的个数
    • 加载因子的作用是控制扩容的时机

什么时候触发扩容?

  • 当存储的元素达到初始容量*加载因子时,即达到16×0.75 = 12,就会扩容,扩容成原来的2倍

可以通过调整初始容量和加载因子改变性能,建议不要修改

2.3去重原理

  • 先调用存储的元素hashcode方法,获得地址值
  • 然后与集合中的元素的地址值判断,如果不一样直接存储
  • 如果存储的元素地址值与集合中存在的元素的地址值一样,再比较equals方法,判断对象属性是否相同
  • 如果equals也判断相同,即认为重复,不存储
  • 如果equals也判断相同,即认为不重复,存储
  • HashSet会去重,想要去重记得重写hashCode和equals方法即可,至于原理,面试的时候讲出来就行了

三、TreeSet

是Set集合的实现类,也是不允许重复元素,但存储的元素有序会对存储的元素默认按照自然顺手排序,也不保证线程安全


TreeSet底层是TreeMap

  • compareTo()方法的返回值决定了元素的顺序以及是否去重

    • 返回值为0,直接去重
    • 返回值为负数,放根节点左侧
    • 返回值为正数,放根节点右侧
    • 存储完,树按照中序排序遍历元素

    o是二叉树结构上以前存储过的元素

    • this是当前的元素

3.2排序原理

  1. 要利用TreeSet排序,存储的元素必须实现Comparable接口,重写从mparTo方法
  2. 当调用add方法存储元素时,会调用元素ComparTo进行运算
    1. 返回值为0,直接去重
    2. 返回值为负数,放根节点左侧
    3. 返回值为正数,放根节点右侧

总结:使用TreeSet进行排序去重一定要实现Comparable接口,重写comparTo方法根据情况可以去写算法,用法不太多

3.3自然排序&比较器排序

自然排序其实就是指实现Comparble接口,创建TreeSet集合时不指定排序规则,默认就是这种自然排序,(实现Comparable接口,重写compareTo方法)

比较器排序,在创建集合时传入自定义的比较器对象,存储元素时就会使用自定义的方法实现排序,(子自定义比较器类时,实现的是Imparator重写的是compare方法)

//自定义比较器类

public class MyIntegerCompare implements Comparator<Integer>{
    @Override
    public int compare(Integer o1, Integer o2) {
        return 1;
    }
}

//定义测试类

 public static void main(String[] args) {
        TreeSet<Integer> integers = new TreeSet<Integer>(new MyIntegerCompare());
        integers.add(1);
        integers.add(4);
        integers.add(4);
        integers.add(2);
        integers.add(54);
        for (Integer i : integers) {
            System.out.println(i);
        }
    }

总结:

  • 自然排序简单,且jdk中默认使用这种,一般从小到大
  • 比较器排序,更灵活,可以自定义规则
    • 自然排序需要类实现Comparable接口的,但是如果说源码无法改动,即无法实现Comparable接口完成排序时,就可以使用比较器排序

四、Map

4.1介绍

Map是一种映射关系的集合,能从键映射到值,是一种特殊集合,一次存储一对元素(键值对),即Map是双列集合

ps:映射理解就是查找

  • Map中不能有键重复,值能重复,一个键只能有一个值(键找值)
  • Map中无法通过值找键
  • Map接口体重三种集合试图,允许以

Map一般常用的两个实现子类:HashMap、TreeMap

4.2HashMap[重点]

HashMap是Map实现

  • 底层是基于Hash表(jdk1.8之后底层是数组+红黑树+链表)
  • 允许存储空值空键
  • HashMap不保证线程安全
  • Hashtable是线程安全的,不允许null值null键

4.3方法

  • map.put(); 添加元素,有返回值是此键所对应的之前的value,之前没有就返回null,输出元素是无序的
 public static void main(String[] args) {
        //创建空的map集合
        HashMap<Integer, String> map = new HashMap<>();
        //添加元素(键不允许重复,值可以重复
        String v1 = map.put(2, "二");
        System.out.println(v1);
        String v2 = map.put(2, "贰");
        System.out.println(v2);
        String v3 = map.put(1, "一");
        System.out.println(v3);
		  //输出结果
        System.out.println(map);

    }

在这里插入图片描述

  • v get(Object key) 通过键找值,返回是值

  • map.containsKey(Key k) 判断是否包含某个键

  • map.containsKey(Value v) 判断是否包含某个值

  • map.size() 集合大小(尺寸),元素个数

  • map.clear() 清空集合

  • v remove(Object k) 根据键删除整个键值对,返回值是键对应的值

4.3迭代遍历

Map集合没有提供直接的遍历Map集合的方法,但是提供了

  • 键集 Set keySet(),专门遍历键

            /**
             * 通过键来遍历
             * 首先通过键来将所有键来存储到Set集合中,因为Set是去重的,而键也是不重复的
             * 其次用遍历来输出所有的键
             */
            Set<Integer> keySet = map.keySet();
            for (Integer key:keySet){
                System.out.println(key);
            }
    
  • 值集Collection value,专门遍历值

		  /**
         * 通过值来遍历
         * 先将所有值存储到Collection中,因为值能重复,如果放到Set中就会去重
         * 最后同样也要遍历输出
         */
        Collection<String> values = map.values();
        for (String v:values){
            System.out.println(v);
        }
  • 键值映射集Set<Map.Entry<K,V>>entrySet,专门遍历键值对
         /**
         * 通过键值对来一起输出
         * 将得到键值对来放进Set的映射集Map.Entry<K,V>就是用来存储一对键值对的
         * 最后同样也是遍历
         */
       Set<Map.Entry<Integer,String>> entrySet =  map.entrySet();
       for (Map.Entry<Integer,String>  entry:entrySet){
           Integer key = entry.getKey();
           String value = entry.getValue();
           System.out.println(key+"="+value);
       }
  • 38
    点赞
  • 32
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值