Java集合

 1  数组Vs链表

1.链表是什么

链表是一种上一个元素的引用指向下一个元素的存储结构,链表通过指针来连接元素与元素

链表是线性表的一种,所谓的线性表包含顺序线性表和链表,顺序线性表是用数组实现的,在内存中有顺序排列,通过改变数组大小实现。而链表不是用顺序实现的,用指针实现在内存中不连续。意思就是说,链表就是将一系列不连续的内存联系起来,将那种碎片内存进行合理的利用,解决空间的问题。

所以,链表允许插入和删除表上任意位置上的节点,但是不允许随即存取。链表有很多种不同的类型:单向链表、双向链表及循环链表。

2.单向链表 单向链表包含两个域,一个是信息域,一个是指针域,第一部分是保存或显示关于节点的信息,第二部分存储下一个节点的地址,而最后一个节点则指向一个空值。

3.双向链表 每个节点有2个链接,一个是指向前一个节点(当此链接为第一个链接时,指向的是空值或空列表),另一个则指向后一个节点(当此链接为最后一个链接时,指向的是空值或空列表)。意思就是说双向链表有2个指针,一个是指向前一个节点的指针,另一个则指向后一个节点的指针。

4.循环链表  循环链表就是首节点和末节点被连接在一起。循环链表中第一个节点之前就是最后一个节点,反之亦然。

5 数组  一块连续的内存,然后当有数据进入的时候会将数据按顺序的存储在这块连续的内存中

 特点 寻址读取数据比较容易,插入和删除比较困难

5.数组和链表的区别?

链表是链式的存储结构;数组是顺序的存储结构

链表通过指针来连接元素与元素,数组则是把所有元素按次序依次存储。

2 HashCode & Equals(一致约定)

        1. hashCode相同,不一定是同一个对象 
        2. 同一个对象的,hashCode值一定相同

        3 equals返回true-hashCode值一定相同;equals返回false-hashCode值可以相同

 3 List Vs Set            List,Set实现Collection接口 ---xx---- Map没有实现Collection接口

List:1.可以允许重复的对象。

    2.可以插入多个null元素。

        3.是一个有序容器,保持了每个元素的插入顺序,输出的顺序就是插入的顺序。

        4.常用的实现类有 ArrayList、LinkedList 和 Vector。ArrayList 最为流行,它提供了使用索引的随意访问,而 LinkedList 则对于经常需要从 List 中添加或删除元素的场合更为合适。

 Set:1.不允许重复对象

     2. 无序容器,你无法保证每个元素的存储顺序,TreeSet通过 Comparator  或者 Comparable 维护了一个排序顺序。

        3. 只允许一个 null 元素

        4.Set 接口最流行的几个实现类是 HashSet、LinkedHashSet 以及 TreeSet。最流行的是基于 HashMap 实现的 HashSet;TreeSet 还实现了 SortedSet 接口,因此 TreeSet 是一个根据其 compare() 和 compareTo() 的定义进行排序的有序容器。

4 哈希表

1:Hash表是查询速度最快的存储方式

它的底层有3种存贮方式,一种是纯数组存贮,一种是数组挂链表存储,还有一种是链表挂链表。

哈希底层3种结构图如下:

当需要把某些对象给哈希表中存放时,那么会根据这些对象的特有数据结合相应的算法,计算出这个对象在哈希数组中的位置,然后把这个对象存放在哈希数组中。

         注意,如果两个对象hashCode方法算出结果一样,这样现象称为哈希冲突,这时会调用对象的equals方法,比较这两个对象是不是同一个对象,如果equals方法返回的是true,那么就不会把第二个对象存放在哈希表中,如果返回的是false,就会把这个值存放在哈希表中。

总结:保证HashSet集合元素的唯一,其实就是根据对象的hashCode和equals方法来决定的。如果我们往集合中存放自定义的对象,那么保证其唯一,就必须复写hashCode和equals方法建立属于当前对象的比较方式。

5 ArrayList   Vs   Vector   Vs  LinkedList   //List比较(可以存放多个null)

    1 Linkedlist为什么可以插入null   LinkedList 当您在列表中插入空值时,您将插入 $ 项目的 null节点,但 next 和 prev 指针是非空的。

    2 arrayList.indexOf  插入多个相投元素indexOf  返回找的第一个索引的下标

   3  ArrayList不具有有线程安全性,在单线程的环境中,LinkedList也是线程不安全的,如果在并发环境下使用它们,可以用              Collections类中的静态方法synchronizedList()对ArrayList和LinkedList进行调用即可。

      Vector实现线程安全的,即它大部分的方法都包含关键字synchronized,但是Vector的效率没有ArraykList和LinkedList高。

  4 ArrayList扩容后的容量是之前的1.5倍,然后把之前的数据拷贝到新建的数组中去

     而Vector默认情况下扩容后的容量是之前的2倍。

集合有List ,Set继承至Collection接口,Map为独立接口

     1 List有3种   

              @ArrayList   @Vector   @LinkedList

     2 Set有3种

               @HashSet(底层实现为hashmap)  @LinkedHashSet  @TreeSet

6 Map Vs Collection

             Collection中的集合,元素是孤立存在的(理解为单身),向集合中存储元素采用一个个元素的方式存储。

             Map中的集合,元素是成对存在的(理解为夫妻)。每个元素由键与值两部分组成,通过键可以找对所对应的值。

             Collection中的集合称为单列集合,Map中的集合称为双列集合。

             需要注意的是,Map中的集合不能包含重复的键,值可以重复;每个键只能对应一个值。

              Map中常用的集合为HashMap集合、LinkedHashMap集合。

   HashMap是利用合数组与链表结的形式构建的。竖列为数组结构,默认初始数量为16(1<<4)个,横列为链表结构用于解决散列冲突的问题。当数组中有值得元素超过了装载因子的比例(默认为0.75)时,会引发扩容的操作

è¿éåå¾çæè¿°

上图为jdk1.7之前的实现,jdk1.8实现方法是当某一个桶中的元素个数超过了8时,将此桶中的链表构建成红黑树。

 HashMap  VS HashTable

1.HashMap是非线程安全的,HashTable是线程安全的。它的大多数方法都加了synchronized。 
2.HashMap允许key和value的值为null,HashTable不允许null值的存在。在HashTable的put方法中,如果V为null,直接抛出NullPointerException。 
3.因为HashTable加了同步处理,所以HashMap效率高于HashTable。
HashTable  VS  ConcurrentHashMap

HashTable与ConcurrentHashMap都是线程安全的Map,有何不同? 
HashTable使用的synchronized对方法加锁,实际锁住的是整个对象;而ConcurrentHashMap使用的是lock,这样在操作的时候锁住的不是这个对象。 
而且ConcurrentHashMap采用了分段锁的设计,只有在同一个分段内才存在竞态关系,不同的分段锁之间没有锁竞争。相比于对整个Map加锁的设计,分段锁大大的提高了高并发环境下的处理能力。

ConcurrentHashMap使用多个子Hash表,即Segment。每个Segment是一个子Hash表。

ConcurrentHashMap要避免调用size()和containsValue()方法,会对整个Map进行扫描。

LinkedHashMap继承自HashMap,在HashMap的基础上增加了一个链表,用以存放元素的顺序。

hashmap的put方法 首先hashcode/size确定那个桶,再判断hashCode+equals(相同已有此key返回oldValue||不同返回null)

public V put(K key, V value) {
        if (key == null)
            return putForNullKey(value);
        int hash = hash(key.hashCode());
        int i = indexFor(hash, table.length);
        for (Entry<K,V> e = table[i]; e != null; e = e.next) {//每添加一个,则循环判断是否与map中的元素相等
            Object k;
            // 先判断hashcode是否一致,然后再判断值是否相等
            if (e.hash == hash && ((k = e.key) == key || key.equals(k))) {
                V oldValue = e.value;
                e.value = value;
                e.recordAccess(this);
                return oldValue;
            }
        }
 
        modCount++;
        addEntry(hash, key, value, i);
        return null;
    }

1 概述**List , Set, Map都是接口,前两个继承至Collection接口,Map为独立接口
    Set下有HashSet  HashSet内部就是使用HashMap实现,只不过HashSet里面的HashMap所有的value都是同一个Object而已

,             LinkedHashSet

,             TreeSet

-----不重复
    List下有ArrayList,Vector,LinkedList------有序,可重复
    Map下有Hashtable,**
不允许null作为key     **实现了Map接口和Dictionary抽象类  初始容量为11

LinkedHashMap,

HashMap,可以使用null作为key         对Map接口的实现  初始容量为16

TreeMap

HashMap可以使用null作为key,而Hashtable则不允许null作为key
虽说HashMap支持null值作为key,不过建议还是尽量避免这样使用,因为一旦不小心使用了,若因此引发一些问题,排查起来很是费事

HashMap的初始容量为16,Hashtable初始容量为11,两者的填充因子默认都是0.75
HashMap扩容时是当前容量翻倍即:capacity*2,Hashtable扩容时是容量翻倍+1即:capacity*2+1

两者计算hash的方法不同

HashMap和Hashtable的底层实现都是数组+链表结构实现
    Collection接口下还有个Queue接口,有PriorityQueue类

分类

 

   

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值