Map集合和List集合总结

Map集合和List集合总结Map集合和List集合哪个效率更高List接口List集合是一个元素有序(存储有序)、可重复的集合,集合中的每个元素都有对应的索引,以便于查询和修改,List集合是允许存储null值的。List集合可重复原因,请看源码:publicbooleanadd(Ee){ ensureCapacityInternal(size+1);//IncrementsmodCount!…

大家好,又见面了,我是你们的朋友全栈君。

Map集合和List集合哪个效率更高

List接口

List集合是一个元素有序(存储有序)、可重复的集合,集合中的每个元素都有对应的索引,以便于查询和修改,List集合是允许存储null值的。

List集合可重复原因,请看源码:

public boolean add(E e) { 
   
	ensureCapacityInternal(size + 1);  // Increments modCount!!
	elementData[size++] = e;
	return true;
}

结论:无论添加重复还是不重复的元素,结果都是返回true.

ArrayList集合

ArrayList集合是List接口的实现类,有以下特点:

1.有序,有索引
2.元素可以重复
3.可以存储null值
4.随机访问速度快,修改快,增加/插入或者移除/删除的效率慢
5.线程不安全

注意:List集合的实现类想要实现去重复的话:
思想:
  1、首先要创建一个新的集合。
  2、然后使用选择排序思想进行去除重复元素。

Vector集合

  Vector集合也是List接口一个实现类,底层数据结构是数组,插入和移除性能较差,线程安全,效率低。

总结:

ArrayList集合和Vector集合
  ArrayList和Vector都是基于数组实现的list类,所以ArrayList和Vector封装了一个动态的,允许再分配的Object[]数组,不指定的话长度默认为10。ArrayList和Vector对象使用initialCapacity参数来设置该数组的长度,当向集合添加大量元素时,可以使用ensureCapac(int minCapacity)方法一次性的增加initialCapacity。

  ArrayList和Vector在用法上几乎完全相同,但Vector比较古老,方法名比较长,最好是不使用。ArrayList是线程不安全的,Vector是线程安全的,但这个完全可以手动将一个ArrayList变成线程安全的。

ArrayList部分源码分析:

1、首先我们先看一下ArrayList集合的构造器:
  无参构造器:创建一个默认长度为10的集合
  有参构造器:创建一个初始化长度的集合。

/** * Constructs an empty list with an initial capacity of ten. */
public ArrayList() { 
   
    this.elementData = DEFAULTCAPACITY_EMPTY_ELEMENTDATA;
}

public ArrayList(int initialCapacity) { 
   
    if (initialCapacity > 0) { 
   
        this.elementData = new Object[initialCapacity];
    } else if (initialCapacity == 0) { 
   
        this.elementData = EMPTY_ELEMENTDATA;
    } else { 
   
        throw new IllegalArgumentException("Illegal Capacity: "+
                                           initialCapacity);
    }
}

2、分析get方法
  我们调用get方法,获取数据时,底层会调用 rangeCheck(index)方法,然后对传入的索引进行判断,在 rangeCheck(int index)方法中如果传入的索引不存在,那么会抛出异常,如果传入的索引没有问题,那么会调用elementData(index)方法,返回传入该索引的值。

public E get(int index) { 
   
    rangeCheck(index);

    return elementData(index);
}

private void rangeCheck(int index) { 
   
    if (index >= size)
        throw new IndexOutOfBoundsException(outOfBoundsMsg(index));
}

E elementData(int index) { 
   
    return (E) elementData[index];
}

3、add方法分析:
  我们使用add方法,向集合中添加一个元素时,首先,我们要调用ensureCapacityInternal()方法判断集合的长度是否够用,那么经过层层判断,如果集合长度不够,那么,将会对旧的集合使用集合的工具类的copyOf()方法进行拷贝创建新的集合,如果集合长度够用,那么返回true。

public boolean add(E e) { 
   
    ensureCapacityInternal(size + 1);  // Increments modCount!!
    elementData[size++] = e;
    return true;
}

private void grow(int minCapacity) { 
   
    // overflow-conscious code
    int oldCapacity = elementData.length;
    int newCapacity = oldCapacity + (oldCapacity >> 1);
    if (newCapacity - minCapacity < 0)
        newCapacity = minCapacity;
    if (newCapacity - MAX_ARRAY_SIZE > 0)
        newCapacity = hugeCapacity(minCapacity);
    // minCapacity is usually close to size, so this is a win:
    elementData = Arrays.copyOf(elementData, newCapacity);
}

4、remove方法分析
  实现的逻辑和add方法大致一样,也是进行集合的拷贝。因此添加和移除的效率低。

    rangeCheck(index);

    modCount++;
    E oldValue = elementData(index);

    int numMoved = size - index - 1;
    if (numMoved > 0)
        System.arraycopy(elementData, index+1, elementData, index,
                         numMoved);
    elementData[--size] = null; // clear to let GC do its work

    return oldValue;
}

LinkedList集合

特点:
1.底层数据结构是链表
2.链表的特点有序,查询和修改效率低,增加和删除效率高
3.可以存储null值
4.线程不安全
5.允许重复
6.不可排序

LinkedList与ArrayList集合比较
  LinkedList与ArrayList的实现机制完全不同,ArrayList内部以数组的形式来保存集合中的元素,因此随机访问集合元素时有较好的性能;而LinkedList内部以链表的形式来保存集合中的元素,因此随机访问性能较差,但是插入、删除元素时非常快。

Map接口

  Map 未继承 Collection,而是独立的接口,Map 是一种把键对象和值对象进行映射的集合,它的每一个元素都包含了一对键对象和值对象,Map 中存储的数据是没有顺序的, 其 key 是不能重复的,它的值是可以有重复的。

Map集合的特点:

1.能够存储唯一的列的数据(唯一,不可重复)
2.能够存储可以重复的数据(可重复)
3.值的顺序取决于键的顺序
4.键和值都是可以存储null元素的

Map 接口常见的四个实现类:Hashtable,HashMap,TreeMap,LinkedHashMap;

HashTable集合

内部存储的键值对是无序的是按照哈希算法进行排序,与 HashMap 最大的区别就是线程安全。键或者值不能为 null,为 null 就会抛出空指针异常。

特点:
不允许null键和null值
线程安全,效率低

HashMap集合

基于哈希表的 Map 接口的实现。此实现提供所有可选的映射操作,并允许使用 null 值和 null 键。(除了非同步和允许使用 null 之外,HashMap 类与 Hashtable 大致相同。)
此类不保证映射的顺序,特别是它不保证该顺序恒久不变。
HashMap如何运行的:
  HashMap在Map.Entry静态内部类实现中存储key-value对。HashMap使用哈希算法,在put和get方法中,它使用hashCode()和equals()方法。当我们通过传递key-value对调用put方法的时候,HashMap使用Key hashCode()和哈希算法来找出存储key-value对的索引。Entry存储在LinkedList中,所以如果存在entry,它使用equals()方法来检查传递的key是否已经存在,如果存在,它会覆盖value,如果不存在,它会创建一个新的entry然后保存。当我们通过传递key调用get方法时,它再次使用hashCode()来找到数组中的索引,然后使用equals()方法找出正确的Entry,然后返回它的值。

特点:
键无序,唯一,类似于Set集合
值有序,可重复,类似于List
底层数据结构是哈希表,保证键唯一
允许键为null,值为null

HashMap和Hashtable的区别

HashMap是不安全的不同步的效率高的  允许null键和null值
Hashtable是安全的同步的效率低的 不允许null键和null值
底层都是哈希表结构

LinkedHashMap集合

Map 接口的哈希表和链接列表实现,具有可预知的迭代顺序,相当于一个栈,先 put 进去的最后出来,先进后出。

特点:
键有序,唯一,
值有序,可重复,类似于List
底层数据结构是哈希表和链表,哈希表保证键唯一,链表保证键有序

TreeMap集合

基于红黑树 (red-black tree) 数据结构实现,按 key 排序,默认的排序方式是升序。

总结:

  如果List 和Map存储的元素都比较多。那么在取元素方面,List要慢很多。 但是这也不是绝对的,因为List底层基于数组,如果你明确的知道你要取的元素在哪个下标上,那么List也是相当的快。但是如果你不清楚,只能通过迭代内部全部元素然后进行条件判断查找,那么List就要慢的多,因为他要从头到尾一个个的元素去查,直到找到满足你的要求的那个元素,而Map则不需要迭代,因为Map有键,直接取键对应的值。 对于添加元素,List是在数组的结尾追加,当容量不够时,创建一个新的更长的数组然后将旧的全部拷贝过来。Map和他的方式差不多,也是容量不足的时候需要重新创建新的然后拷贝,但是当发生删除元素时,List简直就是灾难。假设你有10000个元素,你删除首个元素,在删除完毕以后 List中的所有元素都必须进行一次移动操作,向前位移。。。而Map则不需要。

  大概就是这样,如果你考虑一个长度比较可预测的保存元素的集合,并且很少有删除操作,大部分是进行全部迭代的操作,那么用List会比较合适。
  如果你的List还要经常增删,那么用LinkedList比较合适。
  如果你要快速查找,取值,用HashMap比较合适。
  如果同时要保证,元素放进去的顺序和取出来的顺序一致用LinkedHashMap。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/142801.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • hashlib加密「建议收藏」

    hashlib加密「建议收藏」加密算法介绍HASHHash,一般翻译做“散列”,也有直接音译为”哈希”的,就是把任意长度的输入(又叫做预映射,pre-image),通过散列算法,变换成固定长度的输出,该输出就是散列值。这种转换是一种压缩映射,也就是,散列值的空间通常远小于输入的空间,不同的输入可能会散列成相同的输出,而不可能从散列值来唯一的确定输入值。简单的说就是一种将任意长度的消息压缩到某一固定长度的消息摘要的函数。…

    2022年4月30日
    53
  • 地形——高度图

    地形——高度图在游戏中,我们将采用高度图来模拟现实生活中的丘陵和山谷。高度图其实就是一个数组,而该数组的每个元素都指定了地形方格中某一个顶点的高度值。线框模式普通地形模式在高度图中,通常为其每一个元素只分配一个字节的存储空间,以至于高度能在区间[0,255]内取值。但在实际应用中,为了匹配3D世界的尺度,可能要对高度值进行比例变换,就很可能超出上述区间范围。因此,可以分配一个整型或浮点型数组来存储这些高…

    2022年5月9日
    96
  • 微信聊天记录迁移(Android到IOS)「建议收藏」

    微信聊天记录迁移1.原设备登录微信我的–>设置–>通用–>聊天记录备份与迁移选择“迁移聊天记录到另一台设备”选择“迁移全部聊天记录”,会生成一个二维码用新的设备登录该微信号并扫描此二维码,即可迁移数据…

    2022年4月15日
    211
  • 数据库 分区表详解

    数据库 分区表详解如果你的数据库中某一个表中的数据满足以下几个条件,那么你就要考虑创建分区表了。1、数据库中某个表中的数据很多。很多是什么概念?一万条?两万条?还是十万条、一百万条?这个,我觉得是仁者见仁、智者见智的问题。当然数据表中的数据多到查询时明显感觉到数据很慢了,那么,你就可以考虑使用分区表了。如果非要我说一个数值的话,我认为是100万条。2、但是,数据多了并不是创建分区表的惟一条件,哪怕你有一千万条记录,但

    2022年6月6日
    35
  • 【 Linux学习】SSH连接时出现Host key verification failed的原因及解决方法以及ssh-keygen命令的用法

    【 Linux学习】SSH连接时出现Host key verification failed的原因及解决方法以及ssh-keygen命令的用法一、问题描述今天下午使用ssh连接其他服务器进行scp操作的时候,提示失败,如下所示:[root@localhostbackups]#scproot@172.xxx.xxx.xxx:/data/gitlabData/backups/1539717714_2018_10_17_9.4.3_gitlab_backup.tar.@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@……

    2022年10月21日
    0
  • springboot启动原理 通俗面试_spring高级面试题

    springboot启动原理 通俗面试_spring高级面试题importorg.springframework.boot.SpringApplication;importorg.springframework.boot.autoconfigure.SpringBootApplication;/***Helloworld!**/@SpringBootApplicationpublicclassApp{publicstaticvoidmain(String[]args){Syst.

    2022年8月20日
    20

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号