Java容器

Java Collection(集合)框架:

Collecion:接口
List:接口
【有序的,可以重复、和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector> 。】
Set:接口
【无序的、不能重复、检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>】、
Queue
AbstractList:接口 AbstractSet:接口 SortedSet:接口
Vector:实现类
【大多数方法是synchronization同步的;线程安全的;性能比ArrayList低】
ArrayList:实现类
【ArrayList的方法是不同步的;线程不安全的;】
AbstractSequentialList:接口 HashSet:实现类 TreeSet:实现类 TreeSet:实现类
Stack LinkedList:实现类
【双向列表来实现的;随机访问效率低,插入效率高;线程不安全的】
LinkedHashSet:实现类


Map:接口
【值value可以重复,但键key是唯一的,不能重复】
AbstractMap:接口 SortedMap:接口
HashMap:实现类
【基于散列表实现的】
WeakHashMap:实现类 HashTable:实现类 IdentityHashMap TreeMap:实现类 TreeMap:实现类
【基于红黑树实现的】
LinkedHashMap
【采用列表来维护内部的顺序的】

Java容器 - 图1

Java容器 - 图2
Java容器 - 图3

1、你所知道的集合类都有哪些?主要方法?

最常用的集合类是 List 和Map。
List 的具体实现包括 ArrayList 和 Vector,它们是可变大小的列表,比较适合构建、存储和操作任何类型对象的元素列表。 List 适用于按数值索引访问元素的情形。
Map 提供了一个更通用的元素存储方法。 Map 集合类用于存储元素对(称作”键”和”值”),其中每个键映射到一个值。
ArrayList/Vector—List
—Collection
HashSet/TreeSet—Set

Propeties—HashTable
—Map
Treemap/HashMap
我记的不是方法名,而是思想,我知道它们都有增删改查的方法,但这些方法的具体名称,我记得不是很清楚,对于set,大概的方法是add,remove, contains;对于map,大概的方法就是put,remove,contains等,因为,我只要在eclispe下按点操作符,很自然的这些方法就出来了。我记住的一些思想就是List类会有get(int index)这样的方法,因为它可以按顺序取元素,而set类中没有get(int index)这样的方法。List和set都可以迭代出所有元素,迭代时先要得到一个iterator对象,所以,set和list类都有一个iterator方法,用于返回那个iterator对象。map可以返回三个集合,一个是返回所有的key的集合,另外一个返回的是所有value的集合,再一个返回的key和value组合成的EntrySet对象的集合,map也有get方法,参数是key,返回值是key对应的value。

Vector(add、insert、remove、set、equals、hashcod)

2、Collection 和 Collections的区别。(宝典142)

Collection是集合类的上级接口,继承与他的接口主要有Set 和List.
Collection是一个集合接口。它提供了对集合对象进行基本操作的通用接口方法。实现该接口的类主要有List和Set,该接口的设计目标是为各种具体的集合提供最大化的统一操作方式。
Collections是针对集合类的一个包装类。它提供一系列静态方法以实现对各种集合的搜索、排序、线程安全化等操作,其中大多数方法都是用来处理线性表。Collections类不能实例化,如同一个工具类,服务于Collection框架。若在使用Collections类的方法时,对应的Collection的对象为null,则这些方法都会抛出NullPointerException。

3、List 和Map 区别?

一个是存储单列数据的集合,另一个是存储键和值这样的双列数据的集合,List中存储的数据是有顺序,并且允许重复;Map中存储的数据是没有顺序的,其键是不能重复的,它的值是可以有重复的。

4、Set和List的区别(菜鸟教程)

  1. Set 接口实例存储的是无序的,不重复的数据。List 接口实例存储的是有序的,可以重复的元素。
    2. Set检索效率低下,删除和插入效率高,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>。
    3. List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector>。

    5、List、Map、Set三个接口,存取元素时,各有什么特点?

    这样的题属于随意发挥题:这样的题比较考水平,两个方面的水平:一是要真正明白这些内容,二是要有较强的总结和表述能力。如果你明白,但表述不清楚,在别人那里则等同于不明白。
    首先,List与Set具有相似性,它们都是单列元素的集合,所以,它们有一个功共同的父接口,叫Collection。Set里面不允许有重复的元素,所谓重复,即不能有两个相等(注意,不是仅仅是相同)的对象,即假设Set集合中有了一个A对象,现在我要向Set集合再存入一个B对象,但B对象与A对象equals相等,则B对象存储不进去,所以,Set集合的add方法有一个boolean的返回值,当集合中没有某个元素,此时add方法可成功加入该元素时,则返回true,当集合含有与某个元素equals相等的元素时,此时add方法无法加入该元素,返回结果为false。Set取元素时,没法说取第几个,只能以Iterator接口取得所有的元素,再逐一遍历各个元素。
    List表示有先后顺序的集合,注意,不是那种按年龄、按大小、按价格之类的排序。当我们多次调用add(Obj e)方法时,每次加入的对象就像火车站买票有排队顺序一样,按先来后到的顺序排序。有时候,也可以插队,即调用add(int index,Obj e)方法,就可以指定当前对象在集合中的存放位置。一个对象可以被反复存储进List中,每调用一次add方法,这个对象就被插入进集合中一次,其实,并不是把这个对象本身存储进了集合中,而是在集合中用一个索引变量指向这个对象,当这个对象被add多次时,即相当于集合中有多个索引指向了这个对象,如图x所示。List除了可以以Iterator接口取得所有的元素,再逐一遍历各个元素之外,还可以调用get(index i)来明确说明取第几个。
    Map与List和Set不同,它是双列的集合,其中有put方法,定义如下:put(obj key,obj value),每次存储时,要存储一对key/value,不能存储重复的key,这个重复的规则也是按equals比较相等。取则可以根据key获得相应的value,即get(Object key)返回值为key 所对应的value。另外,也可以获得所有的key的结合,还可以获得所有的value的结合,还可以获得key和value组合成的Map.Entry对象的集合。
    List 以特定次序来持有元素,可有重复元素。Set 无法拥有重复元素,内部排序。Map保存key-value值,value可多值。
    HashSet按照hashcode值的某种运算方式进行存储,而不是直接按hashCode值的大小进行存储。例如,”abc” —-> 78,”def”—-> 62,”xyz” —-> 65在hashSet中的存储顺序不是62,65,78,这些问题感谢以前一个叫崔健的学员提出,最后通过查看源代码给他解释清楚,看本次培训学员当中有多少能看懂源码。LinkedHashSet按插入的顺序存储,那被存储对象的hashcode方法还有什么作用呢?学员想想!hashset集合比较两个对象是否相等,首先看hashcode方法是否相等,然后看equals方法是否相等。new 两个Student插入到HashSet中,看HashSet的size,实现hashcode和equals方法后再看size。
    同一个对象可以在Vector中加入多次。往集合里面加元素,相当于集合里用一根绳子连接到了目标对象。往HashSet中却加不了多次的。

    6、Set里的元素是不能重复的,那么用什么方法来区分重复与否呢? 是用==还是equals()? 它们有何区别?

    Set里的元素是不能重复的,元素重复与否是使用equals()方法进行判断的。
    equals()和==方法决定引用值是否指向同一对象equals()在类中被覆盖,为的是当两个分离的对象的内容和类型相配的话,返回真值。

    7.ArrayList和LinkedList的区别?

    ArrayList底层使用的是数组,LinkedList使用的是链表。
    数组具有索引,查询特定的元素比较快,而插入和删除,修改比较慢 (数组在内存中是一块连续的内存,如果插入或删除时需要移动内存)。
    链表不要求内存时连续的,在当前元素中存放下一个或上一个元素的地址,查询时需要从头开始,一个一个地找,查询效率低,而插入时不需要移动内存,只需要改变引用指向即可。所以插入或删除效率高。
    ArrayList适用于查询比较多,但是插入和删除比较少的情况。
    而LinkedList使用在查询比较少,但是插入和删除比较多的情况。

    8、ArrayList、Vector和LinkedList的区别(宝典135)

    一,相同点:
    ArrayList、Vector和LinkedList类均在java.util包中,均为可伸缩数组,即可以动态改变长度的数组。
    ArrayList和Vector都是基于存储元素的Object[] array来实现的、都有一个初始化的容量大小,当里面存储的元素超过这个大小时就需要动态地扩充它们的存储空间。其中ArrayList默认扩充为原来的1.5倍(没有提供方法来设置空间扩充的方法),Vector默认扩充为原来的2倍(每次扩充空间的大小都是可以设置的)。
    二,不同:
    ArrayList、Vector最大的区别就是Synchronization(同步)的使用:
    ArrayList的方法是不同步的、线程不安全性能高
    Vector的绝大多数方法(add、insert、remove、set、equals、hashcod)都是同步的、线程安全的、性能低
    LinkedList是采用双向列表来实现的,对数据的索引需要从列表头开始遍历,因此用于随机访问则效率比较低,但是插入元素时不需要对数据进行移动,因此插入效率比较高。同时,LinkedList是线程不安全的。
    三,实际应用中,该如何选择合适的容器:
    当对数据的主要操作为索引或只在集合的末端增加、删除元素时,使用ArrayList或Vector效率比较高;
    当对数据的操作主要为指定位置的插入或删除操作时,使用LinkedList效率比较高;
    当在多线程中使用容器(即多个线程会同时访问该容器)时,使用Vector比较安全;

    9、说出ArrayList,Vector, LinkedList的存储性能和特性

    ArrayList和Vector都是使用数组方式存储数据,此数组元素数大于实际存储的数据以便增加和插入元素,它们都允许直接按序号索引元素,但是插入元素要涉及数组元素移动等内存操作,所以索引数据快而插入数据慢,Vector由于使用了synchronized方法(线程安全),通常性能上较ArrayList差,而LinkedList使用双向链表实现存储,按序号索引数据需要进行前向或后向遍历,但是插入数据时只需要记录本项的前后项即可,所以插入速度较快。
    LinkedList也是线程不安全的,LinkedList提供了一些方法,使得LinkedList可以被当作堆栈和队列来使用。

    10、去掉一个Vector集合中重复的元素

    Vector newVector =new Vector();
    For (inti=0;i{
    Object obj = vector.get(i);
    if(!newVector.contains(obj);
    newVector.add(obj);
    }
    还有一种简单的方式,HashSetset = new HashSet(vector);

    11、HashMap和HashTable的区别?

    1.HashMap和HashTable都可以使用来存储key-value的数据。
    2.HashMap是可以把null作为key或者value的,而hashTable是不可以的。
    3.HashMap是线程不安全的,效率较高。HashTable是线程安全的,效率较低。

    问题:我想线程安全又想效率高?

    答:使用CurrentHashMap。通过把整个Map分为N个Segment(类似于HashTable),可以提供相同的线程安全,但效率提升N倍,默认是提升16倍。

    12、HashMap、HashTable、TreeMap和WeakHashMap有哪些区别(宝典136)

    HashMap是Hashtable的区别:

    1 HashMap是Hashtable的轻量级实现(非线程安全的实现),他们都完成了Map接口,主要区别在于HashMap允许空(null)键值(key)(但需要注意,最多只允许一条记录的键为null,不允许多条记录的值为null),而Hashtable不允许。由于非线程安全,在只有一个线程访问的情况下,效率要高于Hashtable。
    2 HashMap把Hashtable的contains方法去掉了,改成containsvalue和containsKey。因为contains方法容易让人引起误解。 Hashtable继承自Dictionary类,而HashMap是Java1.2引进的Map interface的一个实现。
    3 Hashtable的方法是线程安全的,而HashMap不支持线程的同步,所以它不是线程安全的。在多个线程访问Hashtable时,不需要开发人员对它进行同步,而HashMap 就必须为之提供额外的同步机制。所以就效率而言,HashMap》Hashtable
    4 Hashtable使用Enumeration,HashMap使用Iterator。
    5 Hashtable和HashMap采用的hash/rehash算法都大概一样,所以性能不会有很大的差异。
    6 在Hashtable中,hash数组默认大小是11,增加的方式是old*2+1;
    在HashMap中,,hash数组默认大小是16,而且一定是2的指数。
    7 hash值的使用不同。Hashtable直接使用对象的hashCode。

    就HashMap与HashTable主要从三方面来说。
    一.历史原因:Hashtable是基于陈旧的Dictionary类的,HashMap是Java 1.2引进的Map接口的一个实现
    二.同步性:Hashtable是线程安全的,也就是说是同步的,而HashMap是线程序不安全的,不是同步的
    三.值:只有HashMap可以让你将空值作为一个表的条目的key或value

    在map中插入、删除和定位元素,HashMap是最后的选择。
    如果需要按自然顺序或自定义顺序遍历键,那么TreeMap会更好。
    如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按读取顺序来排列。

    WeakHashMap于HashMap的区别:

    WeakHashMap于HashMap类似,二者的不同在于WeakHashMap中key采用的是“弱引用”的方式,只要WeakHashMap中的key不再被外部引用,它就可以被垃圾回收器回收。而HashMap中key采用的是“强引用”的方式,当HashMap中的key没有被外部引用时,只有在这个key从HashMap中删除后,才可以被垃圾回收器回收。

    总结:

    一、collection接口
    Java容器 - 图4
    二、map接口
    Java容器 - 图5

    一、List、Set、Map

    1.List:

    有序的允许重复、存储单列数据的集合、查找元素效率高(List和数组类似,可以动态增长,根据实际存储的数据的长度自动增长List的长度。查找元素效率高,插入删除效率低,因为会引起其他元素位置改变 <实现类有ArrayList,LinkedList,Vector>。)

    2.Set:

    无序的不重复、存储单列元素的集合、删除和插入效率高(Set检索效率低下,插入和删除不会引起元素位置改变 <实现类有HashSet,TreeSet>
    。)

    3.Map:

    无序的、其键key不能重复,值value可以有重复的、存储键和值这样的双列数据的集合

    二、ArrayList、Vector和LinkedList

    相同:

    1.ArrayList、Vector和LinkedList类均在java.util包中,均为可伸缩数组,即可以动态改变长度的数组。
    2.ArrayList和Vector都是基于存储元素的Object[] array来实现的、都有一个初始化的容量大小,当里面存储的元素超过这个大小时就需要动态地扩充它们的存储空间。其中ArrayList默认扩充为原来的1.5倍(没有提供方法来设置空间扩充的方法),Vector默认扩充为原来的2倍(每次扩充空间的大小都是可以设置的)。

    不同:

    1.ArrayList:

    基于数组、线程不安全、性能高、方法不同步、多用于查询。

    2.LinkedList:

    基于链表、线程不安全的、多用于插入和删除(采用双向列表来实现的,对数据的索引需要从列表头开始遍历,因此用于随机访问则效率比较低,但是插入元素时不需要对数据进行移动,因此插入效率比较高)

    3.Vector:

    线程安全的性能低、绝大多数方法(add、insert、remove、set、equals、hashcod)都是同步的。

    应用场景:

    当对数据的主要操作为索引只在集合的末端增加、删除元素时,使用ArrayList或Vector效率比较高;
    当对数据的操作主要为指定位置的插入或删除操作时,使用LinkedList效率比较高;
    当在多线程中使用容器(即多个线程会同时访问该容器)时,使用Vector比较安全;

    三、HashMap、HashTable、WeakHashMap

    相同:

    1.HashMap和HashTable都可以使用key-value存储数据

    不同:

    1.HashMap:

    线程不安全的、效率较高不同步的可以把null作为key或者value的、是基于Java 1.2引进的Map接口的一个实现、使用Iterator、hash数组默认大小是16,而且一定是2的指数、key采用的是“强引用”的方式(当HashMap中的key没有被外部引用时,只有在这个key从HashMap中删除后,才可以被垃圾回收器回收)。

    2.HashTable:

    线程安全的效率较低同步的不可以把null作为key或者value的、基于陈旧的Dictionary类的、使用Enumeration、hash数组默认大小是11,增加的方式是old*2+1

    3.WeakHashMap:

    key采用的是“弱引用”的方式(只要WeakHashMap中的key不再被外部引用,它就可以被垃圾回收器回收)。

    问题:我想线程安全又想效率高?

    答:使用CurrentHashMap。通过把整个Map分为N个Segment段(类似于HashTable),可以提供相同的线程安全,但效率提升N倍,默认是提升16倍。

    场景:

    在map中插入、删除和定位元素HashMap是最好的选择。
    如果需要按自然顺序自定义顺序遍历键,那么TreeMap会更好。
    如果需要输出的顺序和输入的相同,那么用LinkedHashMap可以实现,它还可以按读取顺序来排列。

    喂,she!即线程安全的集合类是vector**,stack,hashtable,enumeration**