map、list、set的区别

一、List

list和下面要将的set共同实现Collection接口
并且list和set本身也是两个接口
list常用的实现类有 ArrayList 、LinkedList以及Vector

Arraylist和LinkedList

从实现原理上来说 ArrayList是由数组实现的,而LinkedList是基于双链表实现的。所以说,对于查询ArrayList快,时间复杂度为O(1),增删慢,最坏的情况下时间复杂度为O(n);LinkedList反之,增删快,O(1),查询慢。

ArrayList和Vector

Vector也是有数组实现的,但是里面很多的方法都用synchronized来修饰,也就是说,它是线程安全的,那么与之相比,ArrayList就是线程不安全的。所以Vector的效率要比ArrayList的效率低。
扩容:两者的初始大小均为默认值10。
ArrayList:容量不够时,会将旧的容量值用移位运算

    int newCapacity = oldCapacity + (oldCapacity >> 1);

扩容,即增加到原来的1.5倍,如果1.5倍还不够,那么将直接扩容到我们所需要的容量

if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;

Vector:Vector扩容则是直接用原容量加原容量,就是扩容到原来的2倍

  int newCapacity = oldCapacity 
  + ((capacityIncrement > 0) ?capacityIncrement : oldCapacity);

那么如果2倍还不够,则跟ArrayList相同,直接扩容到我们所需要的容量

 if (newCapacity - minCapacity < 0)
            newCapacity = minCapacity;

二、Set

Set跟上面的List都实现了Collection接口,与List相比,set是无序的,list是有序的;set不允许重复,list可以重复。
Set也是一个接口,TreeSet和HashSet是它最常用的实现类。

1.TreeSet和HashSet的区别

Treeset中的数据是排好序的,不允许放入null,而HashSet并没有排序,且可以只有一个null;
TreeSet是通过TreeMap实现的,HashSet是通过HashMap实现的,我们可以看源码:

    //treeset的无参构造
    public TreeSet() {
        this(new TreeMap<E,Object>());
    }
    //hashset的无参构造
     public HashSet() {
        map = new HashMap<>();
    }

Set怎么去重

Set与ArrayList的区别之一就是Set不能有重复的元素
那么set怎么去重?
Treeset:Treeset与HashSet的区别有一条就是排序,TreeSet有两种排序方法,一种是实现Comparable接口,去重写接口中的CompareTo()方法(也是这个接口唯一的方法),即自然排序;另一个是创建一个比较器;
main:

        Set<User> s=new TreeSet<>();
        //name sex money
        s.add(new User("a","a",2));
        s.add(new User("a","a",1));
        s.add(new User("c","c",3));

自然排序:
根据money的大小排序

public class User implements Comparable {
@Override
public void compareTo(Object o){
         User user=(User)o;
         if(this.money>user.money)
         return 1;//放在红黑树左边
         if(this.money<user.money)
         return -1;//放在右边
         return 0;//相等即查重,覆盖
     }
}

比较器:

 Set<User> s=new TreeSet<User>(new Comparator<User>() {//匿名内部类
            @Override
            public int compare(User o1, User o2) {
                if( o1.getMoney()>o2.getMoney())
                    return 1;
                if( o1.getMoney()<o2.getMoney())
                   return -1;
                return 0;
            }
        });
        s.add(new User("a","a",2));
        s.add(new User("a","a",1));
        s.add(new User("c","c",3));
        System.out.println(s);

这是TreeSet的去重方法,即在排序的过程中相同的会被覆盖掉,注意这里的排序规则是比较money的大小,money若有重复,则整个user对象就会被覆盖,但是name、sex相同,则不会被覆盖,即以那个属性为排序规则,则那个属性不能相同,其他属性可以相同。
HashSet:HashSet与Treeset的区别之一就是没有排序。
首先,HashSet会计算出传入的值的hashcode,会首先比较hashcode是否相同,如果相同,再调用equals,若还相同,则重复,若不同,则不重复;若hashcode不同,则不执行equals,直接判定为不相同元素。如果要根据某个实例下的某个属性来判度是否重复,一定要重写hashcode和equals方法。(如果不重写,则会调用object的hashcode和equals)。

三、map

map是通过键值对的形式存储数据,它也是一个接口,常用的实现类有HashMap,TreeMap。上面说到,HashSet是基于HashMap实现的,TreeSet是基于TreeMap实现的。其实HashSet的查重就是基于HashMap的。
HashMap:
Map<String,String> map=new HashMap<>();
可以看到,HashMap是由键值对的形式保存的,要注意:键对象必须是唯一的 值对象可以重复,上面说的HashSet查重,就是将HashSet传入的值当作键对象来查重。所以说,HashSet和HashMap的查重是一样的方式。
HashMap介绍:
HashMap是由数组、链表结合组成。每个数组中都有一个节点来存放链表。这个数组的默认长度为16。
HashMap存储过程:
1 首先会根据key来得到hashcode
2 根据hashcode得到这个值对应的数组的下标
3 判断是否到了阈值
4 将当前对应的 hash,key,value封装成一个 Entry,去数组中查找当前位置有没有元素,如果没有,放在这个位置上;如果此位置上已经存在链表,那么遍历链表,当前key与每个key 进行 equals ,如果相同则把覆盖value,如果没有找到key 与当前 key equals相同,就把它放在链表的头部。
HashMap扩容:
HashMap的初始数组长度为默认值16,加载因子为0.75,也就是说,当前数组有(16*0.75)被占用时,数组长度就会扩大2倍,即32。
那么为什么时0.75呢?
如果我们的数组长度有100,
如果加载因子比0.75小,比如0.5,当我们存数据到50时,数组长度就会翻倍,浪费空间;如果是0.8比0.75大,则可能会出现hash冲突。
当然,当一个数组的链表过长时,达到默认值8的时候,就会生成红黑树,即TreeMap,这样做是因为链表的查询能力很差,当链表很长时,效率会很低,事件复杂度为O(n),所以生成红黑树,有效提高查询能力,时间复杂度为O(logn);

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

还不错的派大星

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值