一、什么是集合
很难给集合下一个精确的定义,通常情况下,把具有相同性质的一类东西,汇聚成一个整体,就可以称为集合。比如,用Java编程的所有程序员,全体中国人等。通常集合有两种表示法,一种是列举法,比如集合A={1,2,3,4},另一种是性质描述法,比如集合B={X|0<X<100且X属于整数}。集合论的奠基人康托尔在创建集合理论给出了许多公理和性质,这都成为后来集合在其它领域应用的基础,本文并不是讲述集合论的,所以如果你对集合论感兴趣,可以参考相关书籍。二、JAVA集合框架类图
三、理解集合类
集合类存放于java.util包中。
集合类存放的都是对象的引用,而非对象本身,出于表达上的便利,我们称集合中的对象就是指集合中对象的引用(reference)。
集合类型主要有3种:set(集)、list(列表)和map(映射)。
(1)集
集(set)是最简单的一种集合,它的对象不按特定方式排序,只是简单的把对象加入集合中,就像往口袋里放东西。
对集中成员的访问和操作是通过集中对象的引用进行的,所以集中不能有重复对象。
集也有多种变体,可以实现排序等功能,如TreeSet,它把对象添加到集中的操作将变为按照某种比较规则将其插入到有序的对象序
列中。它实现的是SortedSet接口,也就是加入了对象比较的方法。通过对集中的对象迭代,我们可以得到一个升序的对象集合。
(2)列表
列表(List)的主要特征是其对象以线性方式存储,没有特定顺序,只有一个开头和一个结尾,当然,它与根本没有顺序的集是不同的。
列表在数据结构中分别表现为:数组和向量、链表、堆栈、队列。
关于实现列表的集合类,是我们日常工作中经常用到的,将在后边的笔记详细介绍。
(3)映射
映射(hashing)与集或列表有明显区别,映射中每个项都是成对的。映射中存储的每个对象都有一个相关的关键字(Key)对象,关键字决定了对象在映射中的存储位置,检索对象时必须提供相应的关键字,就像在字典中查单词一样。关键字应该是唯一的。
关键字本身并不能决定对象的存储位置,它需要对过一种散列(hashing)技术来处理,产生一个被称作散列码(hash code)的整数值,散列码通常用作一个偏置量,该偏置量是相对于分配给映射的内存区域起始位置的,由此确定关键字/对象对的存储位置。理想情况下,散列处理应该产生给定范围内均匀分布的值,而且每个关键字应得到不同的散列码。
四、集合类简介
java.util中共有13个类可用于管理集合对象,它们支持集、列表或映射等集合,以下是这些类的简单介绍
集:
HashSet: 使用HashMap的一个集的实现。虽然集定义成无序,但必须存在某种方法能相当高效地找到一个对象。使用一个HashMap对象实现集的存储和检索操作是在固定时间内实现的.
TreeSet: 在集中以升序对对象排序的集的实现。这意味着从一个TreeSet对象获得第一个迭代器将按升序提供对象。TreeSet类使用了一个TreeMap.
列表:
Vector: 实现一个类似数组一样的表,自动增加容量来容纳你所需的元素。使用下标存储和检索对象就象在一个标准的数组中一样。你也可以用一个迭代器从一个Vector中检索对象。Vector是唯一的同步容器类当两个或多个线程同时访问时也是性能良好的。
Stsck: 这个类从Vector派生而来,并且增加了方法实现栈一种后进先出的存储结构。
LinkedList: 实现一个链表。由这个类定义的链表也可以像栈或队列一样被使用。
ArrayList: 实现一个数组,它的规模可变并且能像链表一样被访问。它提供的功能类似Vector类但不同步。
映射:
HashTable: 实现一个映象,所有的键必须非空。为了能高效的工作,定义键的类必须实现hashcode()方法和equal()方法。这个类是前面java实现的一个继承,并且通常能在实现映象的其他类中更好的使用。
HashMap: 实现一个映象,允许存储空对象,而且允许键是空(由于键必须是唯一的,当然只能有一个)。
WeakHashMap: 实现这样一个映象:通常如果一个键对一个对象而言不再被引用,键/对象对将被舍弃。这与HashMap形成对照,映象中的键维持键/对象对的生命周期,尽管使用映象的程序不再有对键的引用,并且因此不能检索对象。
TreeMap: 实现这样一个映象,对象是按键升序排列的。
Set和List都是由公共接口Collection扩展而来,所以它们都可以使用一个类型为Collection的变量来引用。这就意味着任何列表或集构成的集合都可以用这种方式引用,只有映射类除外(但也不是完全排除在外,因为可以从映射获得一个列表。)所以说,把一个列表或集传递给方法的标准途径是使用Collection类型的参数。
五、实例、代码
看一个简单的例子,来了解一下集合类的基本方法的使用:
public class CollectionToArray {
public static void main(String[] args) {
Collection<String> collection1 = new ArrayList<String>();// 创建一个集合对象
collection1.add("000");// 添加对象到Collection集合中
collection1.add("111");
collection1.add("222");
System.out.println("集合collection1的大小:" + collection1.size());
System.out.println("集合collection1的内容:" + collection1);
collection1.remove("000");// 从集合collection1中移除掉 "000" 这个对象
System.out.println("集合collection1移除 000 后的内容:" + collection1);
System.out.println("集合collection1中是否包含000 :"
+ collection1.contains("000"));
System.out.println("集合collection1中是否包含111 :"
+ collection1.contains("111"));
Collection collection2 = new ArrayList();
collection2.addAll(collection1);// 将collection1 集合中的元素全部都加到collection2中
System.out.println("集合collection2的内容:" + collection2);
collection2.clear();// 清空集合 collection1 中的元素
System.out.println("集合collection2是否为空 :" + collection2.isEmpty());
// 将集合collection1转化为数组
Object s[] = collection1.toArray();
for(int i=0;i<s.length;i++){
System.out.println(s[i]);
}
}
}
运行结果为:
集合collection1的大小:3
集合collection1的内容:[000, 111, 222]
集合collection1移除 000 后的内容:[111, 222]
集合collection1中是否包含000 :false
集合collection1中是否包含111 :true
集合collection2的内容:[111, 222]
集合collection2是否为空 :true
111
222
这里需要注意的是,Collection 它仅仅只是一个接口,而我们真正使用的时候,确是创建该接口的一个实现类。做为集合的接口,它定义了所有属于集合的类所都应该具有的一些方法。
ArrayList (列表)类是集合类的一种实现方式。 下面,我们看一个对于迭代器的简单使用:
public class IteratorDemo {
public static void main(String[] args) {
Collection<String> collection = new ArrayList<String>();
collection.add("s1");
collection.add("s2");
collection.add("s3");
Iterator<String> iterator = collection.iterator();// 得到一个迭代器
while (iterator.hasNext()) {// 遍历
Object element = iterator.next();
System.out.println("iterator = " + element);
}
if (collection.isEmpty())
System.out.println("collection is Empty!");
else
System.out.println("collection is not Empty! size="
+ collection.size());
Iterator<String> iterator2 = collection.iterator();
while (iterator2.hasNext()) {// 移除元素
Object element = iterator2.next();
System.out.println("remove: " + element);
iterator2.remove();
}
Iterator<String> iterator3 = collection.iterator();
if (!iterator3.hasNext()) {// 察看是否还有元素
System.out.println("还有元素");
}
if (collection.isEmpty())
System.out.println("collection is Empty!");
// 使用collection.isEmpty()方法来判断
}
}
程序的运行结果为:
iterator = s1
iterator = s2
iterator = s3
collection is not Empty! size=3
remove: s1
remove: s2
remove: s3
还有元素
collection is Empty!
可以看到,Java的Collection的Iterator 能够用来:
1) 使用方法 iterator() 要求容器返回一个Iterator .第一次调用Iterator 的next()方法时,它返回集合序列的第一个元素。
2) 使用next() 获得集合序列的中的下一个元素。
3) 使用hasNext()检查序列中是否元素。
4) 使用remove()将迭代器新返回的元素删除。
需要注意的是:方法删除由next方法返回的最后一个元素,在每次调用next时,remove方法只能被调用一次 .
下面看看Set的用法
public class TestHashSet {
/**
* @param args
*/
public static void main(String[] args) {
HashSet<Person> hs = new HashSet<Person>();
hs.add(new Person("dfad"));
hs.add(new Person("ad"));
hs.add(new Person("ad"));
//Collections.synchronizedList(list);
System.out.println(hs);
}
}
class Person {
private String name ;
public Person(String name){
this.name = name;
}
public String getName() {
return name;
}
@Override
public int hashCode() {
return name.hashCode();
}
public boolean equals(Object obj) {
System.out.println("----");
return ((Person) obj).getName().equals(this.name);
}
@Override
public String toString() {
return "name:"+name;
}
}
HashSet是Set的一个实现类,在使用HashSet时存入其中的类,一定要复写 hasCode和equals方法。HashSet是无序的。
Map集是以键值对的形式存放的,键不可以重复,值可以重复,如果键重复,会将原来的值覆盖,Map集的实现类主要有三个:HashMap,TreeMap,HashTable
HashMap与HashTable 的区别: 1、HashTable是线程安全的,支持同步。2、HashMap线程不安全,不支持同步,但性能比HashTable好。
Map集的遍历:
1、
Map map=new HashMap()
map.put("1","张飞");
map.put("2","关羽");
map.put("3","刘备");
//得到键的集合
Set set=map.keySet();
for(Object obj :set)
{
System.out.println(map.get(obj));
}
2、
//得到健值对的集合
Set s=map.entrySet();
for(Object obj :set) {
System.out.println(obj);
}
TreeMap是自带排序的(按自然排序),所有存入中的对象必须实现c Comparable 或 ( Comparator)这俩个接口。
例如: class Users implements Comparable{……}