集合
集合是指一个对象容纳了多个对象,这个集合对象主要用来管理维护一系列相似的对象。
1)、Collection接口:集合中每一个元素为一个对象,这个接口将这些对象组织在一起,形成一维结构。
2)、List接口代表按照元素一定的相关顺序来组织(在这个序列中顺序是主要的),List接口中数据可重复。
3)、Set接口是数学中集合的概念:其元素无序,且不可重复。(正好与List对应)SortedSet会按照数字将元素排列,为“可排序集合”。
4)、Map接口中每一个元素不是一个对象,而是一个键对象和值对象组成的键值对(Key-Value)。Key-Value是用一个不可重复的key集合对应可重复的value集合。SortedMap:如果一个Map可以根据key值排序,则称其为SortedMap。(如字典)
!!注意数组和集合的区别:数组中只能存简单数据类型。Collection接口和Map接口只能存对象。
以下介绍接口:
1)、ArreatList接口:
ArrayList和数组非常类似,其底层也用数组组织数据,ArrayList是动态可变数组。
ArrayList有一个add(Object o)方法用于插入数组。ArrayList中数组的顺序与添加顺序一致。
只有List可用get和size。而Set则不可用(因其无序)。
Collection接口都是通过Iterator()(即迭代器)来对Set和List遍历。
通过语句:Iterator it=c.iterator(); 得到一个迭代器,将集合中所有元素顺序排列。然后可以通过interator方法进行遍历,迭代器有一个指针指向首位置。
Interator有hasNext(),用于判断元素右边是否还有数据,返回True说明有。然后就可以调用next动作。Next()会将游标移到下一个元素,并把它所跨过的元素返回。(这样就可以对元素进行遍历)。每个迭代器只能迭代一次。
2)、Vector接口:
Vector和ArrayList用法基本一致。它们之间的最大区别在于,Vector时线程安全的。而Arraylist不是。由于这个原因,Vector的效率会比ArrayList低。
结论:在考虑并发的情况下用Vector(保证线程的安全)。
在不考虑并发的情况下用ArrayList(不能保证线程的安全)。
3)、LinkedList接口:
ArrayList底层是object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点。
而在LinkedList的底层是一种双向循环链表。在此链表上每一个数据节点都由三部分组成:前指针(指向前面的节点的位置),数据,后指针(指向后面的节点的位置)。最后一个节点的后指针指向第一个节点的前指针,形成一个循环。
双向循环链表的查询效率低但是增删效率高。所以LinkedList具有查询效率低但增删效率高的特点。
结论:ArrayList和LinkedList在用法上没有区别,但是在功能上还是有区别的。ArrayList经常用在查询,LinkedList经常用在增删操作较多而查询操作很少的情况下。
Set-HashSet实现类:
4)、HashSet中元素是无序的(这个无序指的是数据的添加顺序和后来的排列顺序不同),而且元素不可重复。
在Object中除了有final(),toString(),equals(),还有hashCode()。
HashSet底层用的也是数组。
当向数组中利用add(Object o)添加对象的时候,系统先找对象的hashCode:
inthc=o.hashCode(); 返回的hashCode为整数值。
Int I=hc%n;(n为数组的长度),取得余数后,利用余数向数组中相应的位置添加数据,以n为6为例,如果I=0则放在数组a[0]位置,如果I=1,则放在数组a[1]位置。如果equals()返回的值为true,则说明数据重复。如果equals()返回的值为false,则再找其他的位置进行比较。这样的机制就导致两个相同的对象有可能重复地添加到数组中,因为他们的hashCode不同。
如果我们能够使两个相同的对象具有相同hashcode,才能在equals()返回为真。
在实例中,定义student对象时覆盖它的hashcode。
因为String类是自动覆盖的,所以当比较String类的对象的时候,就不会出现有两个相同的string对象的情况。
结论:如将自定义类用hashSet来添加对象,一定要覆盖hashcode()和equals(),覆盖的原则是保证当两个对象hashcode返回相同的整数,而且equals()返回值为True。
我们要保证相同对象的返回的hashCode一定相同,也要保证不相同的对象的hashCode尽可能不同(因为数组的边界性,hashCode还是可能相同的)
使用hashSet的优点:
hashSet的底层是数组,其查询效率非常高。而且在增加和删除的时候由于运用的hashCode的比较开确定添加元素的位置,所以不存在元素的偏移,所以效率也非常高。因为hashSet查询和删除和增加元素的效率都非常高。
但是hashSet增删的高效率是通过花费大量的空间换来的:因为空间越大,取余数相同的情况就越小。HashSet这种算法会建立许多无用的空间。
使用hashSet接口时要注意,如果发生冲突,就会出现遍历整个数组的情况,这样就使得效率非常的低。
5)、Set-TreeSet实现类:
用法和hashSet基本相同,treeSet实现对增加元素的排序功能。自动排序。依据的就是compareTo方法,要求存入其中的元素具有可比较性。
比较可以有两种方式:
①java.lang下面有一个接口:Compareble(可比较的)
可以让自定义对象实现一个接口,这个接口只有一个方法compareTo(Object o)
其规则是当前对象与o对象进行比较,其返回一个int值,系统根据此值来进行排序。
如 当前对象>o对象,则返回值>0;(可将返回值定义为1)
如 当前对象=o对象,则返回值=0;
如 当前对象<o对象,则返回值〈0。(可将返回值定义为-1)
看TestArraylist的java代码。
我们通过返回值1和-1位置的调换来实现升序和降序排列的转换。
②java.util下有一个Comparator(比较器)
它拥有compare(),用来比较两个方法。
要生成比较器,则用Sort中Sort(List,List(Compate))
第二种方法更灵活,且在运行的时候不用编译。
注意:要想实现comparTo()就必须在主方法中写上implement comparable.