集合类是Java数据结构的实现。Java的集合类是java.util包中的重要内容,它允许以各种方式将元素分组,并定义了各种使这些元素更容易操作的方法。Java集合类是Java将一些基本的和使用频率极高的基础类进行封装和增强后再以一个类的形式提供。集合类是可以往里面保存多个对象的类,存放的是对象,不同的集合类有不同的功能和特点,适合不同的场合,用以解决一些实际问题。(内容来自百度百科)
Java中的集合类可以分为两大类: A、类是实现Collection接口: Collection是一个基本的集合接口,Collection中可以容纳一组集合元素(Element),Collection有两个重要的子接口List和Set*。List表达一个有序的集合,List中的每个元素都有索引,使用此接口能够准确的控制每个元素插入的位置。用户也能够使用索引来访问List中的元素,List类似于Java的数组。Set接口的特点是不能包含重复的元素。对Set中任意的两个元素element1和element2都有elementl.equals(element2)= false。另外,Set最多有一个null元素。此接口模仿了数学上的集合概念。*
B、类是实现Map接口: Map没有继承Collection接口,与Collection是并列关系。Map提供键(key)到值(value)的映射。一个Map中不能包含相同的键,每个键只能映射一个值。
Collection接口、List接口、Set接口以及相关类的关系如图1所示。 图1如下: Map接口与Collection接口不同,Map提供键到值的映射。Map接口提供三种Collection视图,允许以键集、值集或键一值映射关系集的形式查看某个映射的内容。Map接口及其相关类的关系如图2所示 图2如下:
集合类的特点有三个: 1、集合类这种框架是高性能的。对基本类集(动态数组,链接表,树和散列表)的实现是高效率的。一般人很少去改动这些已经很成熟并且高效的APl;
2、集合类允许不同类型的集合以相同的方式和高度互操作方式工作;
3、集合类容易扩展和修改,可以很容易地稍加改造就能满足自己的数据结构需求。
集合类带来的好处: (1)降低编程难度:在编程中会经常需要链表、向量等集合类,如果自己动手写代码实现这些类,需要花费较多的时间和精力。调用Java中提供的这些接口和类,可以很容易的处理数据。
(2)提升程序的运行速度和质量:Java提供的集合类具有较高的质量,运行时速度也较快。使用这些集合类提供的数据结构,程序员可以从“重复造轮子”中解脱出来,将精力专注于提升程序的质量和性能。
(3)无需再学习新的APl:借助泛型,只要了解了这些类的使用方法,就可以将它们应用到很多数据类型中。如果知道了linkedList的使用方法,也会知道linkedList怎么用,则无需为每一种数据类型学习不同的API。
(4)增加代码重用性:也是借助泛型,就算对集合类中的元素类型进行了修改,集合类相关的代码也几乎不用修改。
说一下这里报错原因:java.lang.String不能转换为java.lang.Integer ,类型转换错误。
上图可以发现Set集合的remove()方法只能按照对象方法来进行删除不能根据下标进行删除。
这里可以清楚的看到Set集合的去重性,上面的报错3换成String类型的就可以直接使用了。
如上图,如果key重复的话会被后面相同的key进行覆盖。
A、List集合特性
ArrayList 默认的构造方法是创建一个初始容量为10的空数组,扩容机制:1.5倍 基于数组实现的,查询快,增删慢,线程不安全,效率高,可存储重复元素
linkedList 基于链表(双向链表)实现的,查询慢,增删快,线程不安全,效率高,可以存储重复元素 特有的方法:addFirst(),addLast(),removeFirst(),removeLast(),getFirst(),getLast()
Vector 基于数组实现的,查询慢,增删快,线程安全,效率低 特有方法:addElement()(相当于add),elementAt()(相当于get)
ArrayList、linkedList、Vector的区别: ArrayList扩容后的容量是之前的1.5倍,然后把之前的数据拷贝到新建的数组中去。而Vector默认情况下扩容后的容量是之前的2倍。Vector可以设置容量增量,而ArrayList不可以。扩容与capacityIncrement(容量增量)参数相关,若此参数大于0,则按该值扩增容量,否则,成倍扩增
B、Set集合特性
HashSet 按照Hash算法来存储集合中的元素,根据对象的哈希码确定对象的存储位置,具有良好的存取和查找性能。 元素无序且唯一,线程不安全,效率高,可以存储null元素,元素的唯一性是靠所存储元素类型是否重写hashCode()和equals()方法来保证的,如果没有重写这两个方法,则无法保证元素的唯一性。 实现唯一性的过程: 存储元素首先会使用hash()算法函数生成一个int类型hashCode散列值,然后已经的所存储的元素的hashCode值比较,如果hashCode不相等,则所存储的两个对象一定不相等,此时存储当前的新的hashCode值处的元素对象;如果hashCode相等,存储元素的对象还是不一定相等,此时会调用equals()方法判断两个对象的内容是否相等,如果内容相等,那么就是同一个对象,无需存储;如果比较的内容不相等,那么就是不同的对象,就该存储了 HashSet中的元素是不重复的, HashSet采用哈希算法,底层用数组存储数据。默认初始化容量16,加载因子0.75。
linkedHashSet 底层数据结构采用链表和哈希表共同实现,链表保证了元素的顺序与存储顺序一致,哈希表保证了元素的唯一性。线程不安全,效率高。 根据元素hashCode值来决定元素存储位置,但它同时使用链表维护元素的次序,这样使得元素看起来是以插入的顺序保存的。
TreeSet TreeSet集合中的元素处于排序状态,主要按照红黑树的数据结构来存储对象 TreeSet根据元素的实际大小进行排序,不同于List是按照元素插入顺序进行排序。
C、Map集合特性
Map 没有继承 Collection 接口, Map 提供 key 到 value 的映射,你可以通过“键”查找“值”。 一个 Map 中不能包含相同的 key ,每个 key 只能映射一个 value
HashMap HashMap 最多只允许一条记录的键为 null,允许多条记录的值为 null。 HashMap 根据键的 hashCode 值存储数据,大多数情况下可以直接定位到它的值,因而具有很快 的访问速度,但遍历顺序却是不确定的。 HashMap 非线程安全,即任一时刻可以有多个线程同时写 HashMap,可能会导 致数据的不一致。如果需要满足线程安全,可以用 Collections 的 synchronizedMap 方法使 HashMap 具有线程安全的能力,或者使用 ConcurrentHashMap。
HashTable HashTable是同步的,这个类中的方法中添加了synchronized关键字,保证了HashTable是线程安全的 HashTable不能存放空值,性能较差 Hashtable 不建议在新代码中使用,不需要线程安全的场合可以用 HashMap 替换,需要线程安全的场合可以用 ConcurrentHashMap 替换
TreeMap TreeMap 实现 SortedMap 接口,能够把它保存的记录根据键排序,默认是按键值的升序排序,也可以指定排序的比较器,当用 Iterator 遍历 TreeMap 时,得到的记录是排过序的。 如果使用排序的映射,建议使用 TreeMap。 在使用 TreeMap 时, key 必须实现 Comparable 接口或者在构造 TreeMap 传入自定义的Comparator,否则会在运行时抛出 java.lang.ClassCastException 类型的异常。 linkedHashMap 使用双向链表来维护键值对的次序 linkedHashMap 是 HashMap 的一个子类,保存了记录的插入顺序,在用 Iterator 遍历linkedHashMap 时,先得到的记录肯定是先插入的,也可以在构造时带参数,按照访问次序排序。
这里注意Set集合没有get方法如果想去某个值需要进行数组或其它集合转换。