您的位置:首页 > 编程语言 > Java开发

Java入门_集合框架

2015-09-26 13:56 337 查看
集合框架:

(1)为什么出现集合类?

面向对象对事物的体现都是以对象的形式,为了方便对多个对象的操作,就对对象进行存储。

集合就是存储对象最常用的一种方式.

(2)数组和集合都是容器,两者有何不同?

**数组长度固定,而集合长度是可变的

**数组值可以存储对象,还可以存储基本数据类型;而集合只能存储对象

**数组存储数据类型是固定的,而集合存储的数据类型不固定

(3)集合类的特点:

集合只能存储对象

集合的长度是可变的

集合可以存储不同类型的对象

(4)集合类框架(重要!!!要分清几种容器间的区别):

**Collection:顶层接口

|—>List:列表,元素是有序的(元素带角标索引),可以有重复元素,可以有null元素。

|—>ArrayList(JDK1.2):底层的数据结构是数组数据结构,特点是查询速度快(因为带角标),

但是增删速度稍慢,因为当元素多时,增删一个元素则所有元素的角标都得改变

线程不同步。默认长度是10,当超过长度时,按50%延长集合长度。

|—>LinkedList(JDK1.2):底层数据结构式链表数据结构(即后面一个元素记录前一个),

特点:查询速度慢,因为每个元素只知道前面一个元素,但增删速度快

因为元素再多,增删一个,只要让其前后的元素重新相连即可

线程是不同步的。

|—>Vector(JDK1.0):底层数据结构是数组数据结构.特点是查询和增删速度都很慢。

默认长度是10,当超过长度时,按100%延长集合长度。

线程同步。

(Vector功能跟ArrayList功能一模一样,已被ArrayList替代)

**List使用注意!

|—>ArrayList:

(1)当往ArrayList里面存入元素没什么要求时,即只要求有序就行时;

(2)当往ArrayList里面存入元素要求不重复时,比如存入学生对象,当同名同姓时
视为同一个人,则不往里面存储。则定义学生对象时,需复写equals方法
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
return false;
Student stu = (Student)obj;
return this.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的特有方法,可以实现某些数据特殊方式的存取,比如堆栈和队列。

一般情况下,使用哪种List接口下的实现类呢?
如果要求增删快,考虑使用LinkedList
如果要求查询快,考虑使用ArrayList
如果要求线程安全,考虑使用Vector。

|--->Set:集合,元素是无序的(因为没有索引),元素不可以重复。可以有null元素。
|--->HashSet(JDK1.2):底层数据结构是哈希表、存取速度快、元素唯一、线程不同步。
保证性元素唯一的原理:
先判断元素的hashCode值是否相同,再判断两元素的equals方法是否为true
(往HashSet里面存的自定义元素要复写hashCode和equals方法,
以保证元素的唯一性!)
|--->TreeSet:底层数据结构式二叉树。可以对Set集合中的元素进行排序。元素有序、线程不同步。
保证元素唯一性的依据:compareTo方法return 0
TreeSet排序的第一种方式:让元素自身具备比较性,比如八种基本数据类型或则字符串,
实现Compareble接口,覆盖compareTo方法,
此方式是元素的自然顺序
TreeSet排序的第一种方式:当元素自身不具备比较性(比如存储学生对象时)或者具备的
比较性不是我们所需要的比较性时(比如想字符串的长度排序),
此时就需要让集合自身具备自定义的比较性。
那如何让集合自身具备比较性呢?可在集合初始化时,
就让集合具备比较方式。即定义一个类,
实现Comparator接口,覆盖compare方法。

**Set集合使用注意事项:
(1)HashSet:
通过new的方式往HashSet里面存的元素的hashCode都不同,但通常我们定义对象,
比如学生对象时,虽然是new的两个学生对象,但是当他们name和age一样时,我们认为是
同一个对象,所以为了保证元素的唯一性,我们通常在往HashSet集合里面存储元素时,
在定义对象的类中通常复写hashCode和equals方法。
public int hashCode()
{
return name.hashCode()+age*39;
}
public boolean equals(Object obj)
{
if(!(obj instanceof Student))
return false;
Student stu = (Student)obj;
return this.name.equals(stu.name)&&this.age==stu.age;
}

HashSet是如何保证元素唯一性的呢?
**如果两元素的hashCode值不同,则不会调用equals方法
**如果两元素的hashCode值相同,则继续判断equals是否返回true;
**hashCode和equals方法虽然定义在自定义对象类里面,但不是我们手动调用
而是往HashSet集合里面存储元素的时候,集合底层自己调用hashCode和equals
它自己拿对象去判断,自己判断两元素是否是同一个元素。

(2)TreeSet:
TreeSet要求往里面存的元素具备比较性,否则会报错。
TreeSet排序的第一种方式:让元素自身具备比较性
定义对象类,实现Compareble接口,复写compareTo方法,此方式是元素的自然顺序
class Student implements Comparable
{
private String name;
private int age;
public Student(String name,int age)
{
this.name=name;
this.age=age;
}
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public int compareTo(Object obj)
{
if(!(obj instanceof Student))
throw new RuntimeException("不是学生对象!");
Student stu = (Student)obj;
int num = this.age-stu.age;
if(num==0)
return this.name.compareTo(stu.name);
return num;
}
}
TreeSet排序的第二种方式:让集合具备比较性
当元素自身不具备比较性(比如存储学生对象时)或者具备的
比较性不是我们所需要的比较性时(比如想字符串的长度排序),
此时就需要让集合自身具备自定义的比较性。
那如何让集合自身具备比较性呢?可在集合初始化时,
就让集合具备比较方式。即定义一个类,
实现Comparator接口,覆盖compare方法。
class StringLengthComparator implements Comparator
{
public int compare(Object obj1,Object obj2)
{
4000
String s1 = (String)obj1;
String s2 = (String)obj2;
int num = new Integer(s1.length()).compareTo(new Integer(s2.length()));
if(num==0)
return s1.compareTo(s2);
return num;
}
}
class TreeSetTest
{
public static void main(String[] args)
{
TreeSet ts = 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方法,

以保证元素的唯一性!)

class Student {

private String name;

private int age;

public Student(String name, int age) {

super();

this.name = name;

this.age = age;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override
public int hashCode(){
return name.hashCode()+age*34;
}
@Override
public boolean equals(Object obj){

if(!(obj instanceof Student))
return false;
Student stu = (Student)obj;
return this.name.equals(stu.name)&&this.age==stu.age;
}
public class HashMapDemo1 {
public static void main(String[] args) {
Map<Student , String> hmap = new HashMap<Student , String>();
hmap.put(new Student("001",20), "beijing");
hmap.put(new Student("002",25), "hebei");
hmap.put(new Student("003",50), "hainan");
hmap.put(new Student("001",20), "beijing");

System.out.println(hmap.size());
Set<Student> keySet = hmap.keySet();
Iterator<Student> it = keySet.iterator();
while(it.hasNext()){
Student stu = it.next();
String addr = hmap.get(stu);
System.out.println(stu.getName()+".."+stu.getAge()+"::"+addr);
}
}
}


|—>TreeMap(JDK1.0):

底层是二叉树结构;

允许使用null键和null值;

线程不同步;

可以给Map集合中的键进行排序.

TreeMap排序的第一种方式:让元素自身具备比较性,比如八种基本数据类型或则字符串,

实现Compareble接口,覆盖compareTo方法,

此方式是元素的自然顺序

TreeMap排序的第一种方式:当元素自身不具备比较性(比如存储学生对象时)或者具备的

比较性不是我们所需要的比较性时(比如想字符串的长度排序),

此时就需要让集合自身具备自定义的比较性。

那如何让集合自身具备比较性呢?可在集合初始化时,

就让集合具备比较方式。即定义一个类,

实现Comparator接口,覆盖compare方法。

class Student implements Comparable{

private String name;

private int age;

public Student(String name, int age) {

super();

this.name = name;

this.age = age;

}

public int getAge() {

return age;

}

public void setAge(int age) {

this.age = age;

}

public String getName() {

return name;

}

public void setName(String name) {

this.name = name;

}

@Override

public int compareTo(Student stu) {

int num = new Integer(this.age).compareTo(new Integer(stu.age));

if(num==0)

return this.name.compareTo(stu.name);

return num;

}

}

public class HashMapDemo1 {
public static void main(String[] args) {

Map<Student , String> tmap = new TreeMap<Student , String>();
tmap.put(new Student("001",20), "beijing");
tmap.put(new Student("002",25), "hebei");
tmap.put(new Student("003",50), "hainan");
tmap.put(new Student("001",20), "beijing");

System.out.println(tmap.size());
Set<Student> keySet1 = tmap.keySet();
Iterator<Student> it1 = keySet1.iterator();
while(it1.hasNext()){
Student stu = it1.next();
String addr = tmap.get(stu);
System.out.println(stu.getName()+".."+stu.getAge()+"::"+addr);
}
}
}


**Iterator:对collection进行迭代的迭代器.迭代器取代了Enumeration。

迭代器和枚举的区别:

迭代器允许调用者利用定义良好的语义在迭代期间从迭代器所指向的collection移除元素

方法名称得到了改进,简化书写

**LisIterator:系列表迭代器,允许程序员按任一方向遍历列表、迭代期间修改列表

**Comparable:此接口强行对实现它的每个类的对象进行整体自然排序。使元素具备比较性

**Comparator:强行对某个对象collection进行整体排序的比较函数,使集合具备比较性

**Collections:此类完全由在 collection 上进行操作或返回 collection 的静态方法组成。

**Arrays:此类包含用来操作数组(比如排序和搜索)的各种静态方法
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  java