------<a href="http://www.itheima.com" target="blank">Java培训、Android培训、iOS培训、.Net培训</a>、期待与您交流! -------
集合框架
(1)为什么出现集合类?
面向对象对事物的体现都是以对象的形式,为了方便对多个对象的操作,就对对象进行存储。集合就是存储对象最常用的一种方式.
(2)数组和集合都是容器,两者有何不同?
数组长度固定,而集合长度是可变的
数组值可以存储对象,还可以存储基本数据类型;而集合只能存储对象
数组存储数据类型是固定的,而集合存储的数据类型不固定(要固定需要加泛型)
集合类框架:
Collection:顶层接口
|--->List:列表,元素是有序的(元素带角标索引),可以有重复元素,可以有null元素。
|--->ArrayList(JDK1.2):底层的数据结构是数组数据结构,特点是查询速度快(因为带角标),
但是增删速度稍慢,因为当元素多时,增删一个元素则所有元素的角标都得改变
线程不同步。默认长度是10,当超过长度时,按50%延长集合长度。
|--->LinkedList(JDK1.2):底层数据结构式链表数据结构(即后面一个元素记录前一个),
特点:查询速度慢,因为每个元素只知道前面一个元素,但增删速度快
因为元素再多,增删一个,只要让其前后的元素重新相连即可
线程是不同步的。
|--->Vector(JDK1.0):底层数据结构是数组数据结构.特点是查询和增删速度都很慢。
默认长度是10,当超过长度时,按100%延长集合长度。
线程同步。
(Vector功能跟ArrayList功能一模一样,已被ArrayList替代)
|--->Set:集合,元素是无序的(因为没有索引),元素不可以重复。可以有null元素。
|--->HashSet(JDK1.2):底层数据结构是哈希表、存取速度快、元素唯一、线程不同步。保证性元素唯一的原理:
先判断元素的hashCode值是否相同,再判断两元素的equals方法是否为true(往HashSet里面存的自定义元素要复写hashCode和equals方法,
以保证元素的唯一性!)
|--->TreeSet:底层数据结构式二叉树。可以对Set集合中的元素进行排序。元素有序、线程不同步。
|--->ArrayList:
(1)当往ArrayList里面存入元素没什么要求时,即只要求有序就行时;
(2)当往ArrayList里面存入元素要求不重复时,比如存入学生对象,当同名同姓时视为同一个人,则不往里面存储。则定义学生对象时,需复写equals方法
public boolean equals(Object obj)
{
if(!(objinstanceof Student))
returnfalse;
Studentstu = (Student)obj;
returnthis.name.equals(stu.name)&&this.age==stu.age;
}
则往ArrayList集合通过add存入学生对象时,集合底层自己会调用学生类的equals方法,判断重复学生则不存入。
注:对于List集合,无论是add、contains、还是remove方法,判断元素是否相同,都是通过复写equals方法来判断!
|--->LinkedList
(1)LinkLedist的特有方法:
boolean offerFirst(E e) 在此列表的开头插入指定的元素。
boolean offerLast(E e) 在此列表末尾插入指定的元素。
E peekFirst() 获取但不移除此列表的第一个元素;如果此列表为空,则返回 null。
E peekLast() 获取但不移除此列表的最后一个元素;如果此列表为空,则返回 null。
E pollFirst() 获取并移除此列表的第一个元素;如果此列表为空,则返回 null。
E pollLast() 获取并移除此列表的最后一个元素;如果此列表为空,则返回 null。
(2)通过LinkLedist的特有方法,可以实现某些数据特殊方式的存取,比如堆栈和队列。保证元素唯一性的依据:compareTo方法return 0
Set集合使用注意事项:
(1)HashSet:
通过new的方式往HashSet里面存的元素的hashCode都不同,但通常我们定义对象, 比如学生对象时,虽然是new的两个学生对象,但是当他们name和age一样时,我们认为是同一个对象,所以为了保证元素的唯一性,我们通常在往HashSet集合里面存储元素时,在定义对象的类中通常复写hashCode和equals方法。
public int hashCode()
{
returnname.hashCode()+age*39;
}
public boolean equals(Object obj)
{
if(!(objinstanceof Student))
returnfalse;
Studentstu = (Student)obj;
returnthis.name.equals(stu.name)&&this.age==stu.age;
}
HashSet是如何保证元素唯一性的呢?
如果两元素的hashCode值不同,则不会调用equals方法
如果两元素的hashCode值相同,则继续判断equals是否返回true;
hashCode和equals方法虽然定义在自定义对象类里面,但不是我们手动调用而是往HashSet集合里面存储元素的时候,集合底层自己调用hashCode和equals它自己拿对象去判断,自己判断两元素是否是同一个元素。
(2)TreeSet:
TreeSet的第一种排序方式:
让元素自身具备比较性,元素需要实现comparable接口,覆盖compareTo方法,这种 方式也称为元素的自然顺序,或者叫做默认顺序。
TreeSet的第二种排序方式:【很重要的】
当元素自身不具备比较性时,或者具备的比较性不是所需要的。
这时就需要让集合自身具备比较性。<字符串本身具有比较性>
class StringLengthComparator implementsComparator
{
publicint compare(Object obj1,Object obj2)
{
Strings1 = (String)obj1;
Strings2 = (String)obj2;
intnum = new Integer(s1.length()).compareTo(new Integer(s2.length()));
if(num==0)
returns1.compareTo(s2);
returnnum;
}
}
class TreeSetTest
{
publicstatic void main(String[] args)
{
TreeSetts = new TreeSet(new StringLengthComparator());
ts.add("addfg");
ts.add("dfg");
ts.add("agtuug");
ts.add("vgjkg");
sop(ts);
}
}
基本数据类型或字符串对象均实现了Comparable接口,故同种类型基本数据间具备比较性,即自然顺序。
Map:顶层接口,该集合存储的是键值对,而且键是唯一的,Map和Set很像,Set集合底层就是使用了Map集合。
Map集合没有迭代器,要取出元素必须先将Map集合转换成Set集合才能遍历元素
|--->HashTable(JDK1.0):
底层是哈希表数据结构;
不可以使用null键和null值;
用作键的对象必须实现hashCode和equals方法来保证键的唯一性
线程同步,效率低
|--->HashMap(JDK1.2):
底层是哈希表数据结构;
允许使用null键和null值;
线程不同步,效率高;
保证元素唯一性的:
原理:先判断元素的hashCode值是否相同,再判断两元素的equals方法是否为true (往HashSet里面存的自定义元素要复写hashCode和equals方法,以保证元素的唯一性!)
classStudent {
privateString name;
privateint age;
publicStudent(String name, int age) {
super();
this.name= name;
this.age= age;
}
publicint getAge() {
returnage;
}
publicvoid setAge(int age) {
this.age= age;
}
publicString getName() {
returnname;
}
publicvoid setName(String name) {
this.name= name;
}
@Override
publicint hashCode(){
returnname.hashCode()+age*34;
}
@Override
publicboolean equals(Object obj){
if(!(objinstanceof Student))
returnfalse;
Studentstu = (Student)obj;
returnthis.name.equals(stu.name)&&this.age==stu.age;
}
publicclass HashMapDemo1 {
publicstatic void main(String[] args) {
Map<Student, String> hmap = new HashMap<Student , String>();
hmap.put(newStudent("001",20), "beijing");
hmap.put(newStudent("002",25), "hebei");
hmap.put(newStudent("003",50), "hainan");
hmap.put(newStudent("001",20), "beijing");
System.out.println(hmap.size());
Set<Student>keySet = hmap.keySet();
Iterator<Student>it = keySet.iterator();
while(it.hasNext()){
Studentstu = it.next();
Stringaddr = hmap.get(stu);
System.out.println(stu.getName()+".."+stu.getAge()+"::"+addr);
}
}
}