集合与数组

 

首先我们先来看概念

  数组:用来存放对象的一种容器(可以存储基本数据类型),长度固定,不适合对象数量未知的情况下使用。

  集合:可以存放多种对象类型的容器(只能存储对象),长度可变。

 

数组与集合的区别

  1、数组声明了数据类型,然后就只能存储那一种数据类型。集合能存放多种(不加泛型时,类型是Object)。

  2、数组是静态的,一个数组实例具有固定的大小,一旦创建了就无法改变容量了。集合是动态扩展容量的,可以根据需要动态改变大小。

  3、数组是java语言中内置的数据类型,是线性排列的,执行效率或类型检查都是最快的。

 

集合只能存放对象,基本数据类型如何解决?

  可以通过包装类把基本数据类型转为对象类型,存放引用。因为有了自动装箱和自动拆箱功能,想把数据类型存入集合,直接存就可以了。系统会自动将其装箱成封装类,然后放入集合。(未指定泛型的话,集合中拿出来的都是Object类型)

 

所以用数组的原因是数组比集合快吗?用集合的原因是能存放多种类型对象?

   一般用 ArrayList 比较多,它基于数组,又实现了Collection和List接口。可以说是综合了这两个。

 

集合类体系

 

单列集合

Collection
├List (有序集合,允许相同元素和null)
│├LinkedList (非同步(线程不安全),允许相同元素和null,增删快查改慢)
│├ArrayList (非同步(线程不安全),允许相同元素和null,实现了动态大小的数组,增删慢查改快)
│└Vector(同步(线程安全),允许相同元素和null,效率低)
│ └Stack(继承自Vector,实现一个后进先出的堆栈)
└Set (无序集合,不允许相同元素,最多有一个null元素)

     |-HashSet(无序集合,不允许相同元素,最多有一个null元素)

 

双列集合
Map (没有实现collection接口,key不能重复,value可以重复,一个key映射一个value)
├Hashtable (实现Map接口,同步(线程安全),不允许null作为key和value,用自定义的类当作key的话要复写hashCode和equals方法,)
├HashMap (实现Map接口,非同步(线程不安全),允许null作为key和value,用的多)
└WeakHashMap(实现Map接口)

 

Collection接口是集合类的根接口,Java中没有提供这个接口的直接的实现类。但是却让其被继承产生了两个接口,就是Set和List。Set中不能包含重复的元素。List是一个有序的集合,可以包含重复的元素,提供了按索引访问的方式。 

  Collection和Collections的区别
            Collection是集合类的上级接口,继承与他有关的接口主要有List和Set
            Collections 是一个包装类,它包含有各种有关集合操作的静态多态方法。此类不能实例化,就像一个工具类,服务于Java的Collection框架。

 

Map是Java.util包中的另一个接口,它和Collection接口没有关系,是相互独立的,但是都属于集合类的一部分。Map包含了key-value对。Map不能包含重复的key,但是可以包含相同的value。

 

Iterator,所有的集合类,都实现了Iterator接口,这是一个用于遍历集合中元素的接口。(使用 for / foreach 循环遍历的时候不能删除集合元素)

  主要包含以下三种方法:

    ①.hasNext()是否还有下一个元素。
    ②.next()返回下一个元素。
    ③.remove()删除当前元素。

  Iterator 和 ListIterator 的区别是什么?

    Iterator 可以用来遍历 Set 和 List 集合,但是ListIterator 只能遍历 List 。

    Iterator 对集合只能是前向遍历,ListIterator 可以前向也可以后向。

    ListIterator 实现了 Iterator 接口。并且扩展了其他功能(如:增加元素,替换元素,获取前一个后一个元素索引等)

  Enumeration 接口和 Iterator 接口的区别有哪些?

    Enumeration 速度是 Iterator 的两倍。Iterator 线程安全,可以删除集合元素。

 

1、List(有序、可重复)
List里存放的对象是有序的,同时也是可以重复的,List关注的是索引,拥有一系列和索引相关的方法,查询速度快。因为往list集合里插入或删除数据时,会伴随着后面数据的移动,所有插入删除数据速度慢。

  ArrayList和LinkedList的区别

    LinkedList经常用在增删操作较多而查询操作很少的情况下,ArrayList则相反。

    LinkedList是链表结构,查询的时候是移动指针一个个找过去的,比较慢;而增加只需要连接上去就可以了。

    ArrayList是数组结构,查询是根据索引随机查询的,比价快;而增删需要更新索引,所以比较慢。

    若只对单条数据插入或删除,ArrayList的速度反而优于LinkedList。但若是批量随机的插入删除数据,LinkedList的速度大大优于ArrayList. 因为ArrayList每插入一条数据,要移动插入点及之后的所有数据。

    

2、Set(无序、不能重复)
Set里存放的对象是无序,不能重复的,集合中的对象不按特定的方式排序,只是简单地把对象加入集合中。

  set是如何不能加入重复值的?

    set 的 add() 方法底层是 map.put(key,value) 方法,我们添加进来的对象放在 map 中 key 的位置

    而 map 的 key 是不能重复的。这里靠的是重写了 hashCode() 和 equals() 方法。

  TreeSet和HashSet的区别?

    首先两者值都不能重复。

    TreeSet是二叉树结构的,是自动排好序的,不允许放入null值。

    HashSet 的话,是无序的,并且要求放入的对象必须实现HashCode()方法。只能有一个 null 值(这里是map底层判断传入对象是否为空,为空则创建一个为 null 的对象)

 

 

3、Map(键值对、键唯一、值不唯一)
Map集合中存储的是键值对,键不能重复,值可以重复。根据键得到值,对map集合遍历时先得到键的set集合,对set集合进行遍历,得到相应的值。

  HashTable与HashMap
    同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的。
    HashMap允许存在一个为null的key,多个为null的value 。
    hashtable的key和value都不允许为null。

 

最后我们再重点讲一下 ArrayList

  它其实就是动态数组,提供了动态的增加和减少元素

  实现了Collection和List接口,可以灵活的设置数组的大小。

  线程不安全,因此一般建议在单线程中使用ArrayList。

  ArrayList是基于数组的,长度是固定的(没设置的时候默认是10),如果要填充的数据超出了长度会怎么办?
            答:ArrayList会增加长度,底层会创建一个新的数组,长度是newLength = oldLength + oldLength/2,如果初始值是10,那么依次是15,22,33,49,73......
posted @ 2018-04-10 13:11  贱小提莫  阅读(238)  评论(0编辑  收藏  举报