Collection
1、常用方法
Collection
接口用于表示任何对象或元素组。想要尽可能以常规方式处理一组元素时,就使用这一接口。Collection 在前面的大图也可以看出,它是List和Set 的父类。并且它本身也是一个接口。它定义了作为集合所应该拥有的一些方法。如下:
注意:
集合必须只有对象,集合中的元素不能是基本数据类型。
Collection接口支持如添加和除去等基本操作。设法除去一个元素时,如果这个元素存在,除去的仅仅是集合中此元素的一个实例。
u booleanadd(Object element)
u booleanremove(Object element)
Collection接口还支持查询操作:
u int size()
u booleanisEmpty()
u booleancontains(Object element)
u Iteratoriterator()
组操作 :Collection 接口支持的其它操作,要么是作用于元素组的任务,要么是同时作用于整个集合的任务。
u boolean containsAll(Collectioncollection)
u boolean addAll(Collection collection)
u void clear()
u void removeAll(Collection collection)
u void retainAll(Collection collection)
containsAll() 方法允许您查找当前集合是否包含了另一个集合的所有元素,即另一个集合是否是当前集合的子集。其余方法是可选的,因为特定的集合可能不支持集合更改。 addAll() 方法确保另一个集合中的所有元素都被添加到当前的集合中,通常称为并。 clear() 方法从当前集合中除去所有元素。 removeAll() 方法类似于 clear() ,但只除去了元素的一个子集。 retainAll() 方法类似于 removeAll() 方法,不过可能感到它所做的与前面正好相反:它从当前集合中除去不属于另一个集合的元素,即交。
我们看一个简单的例子,来了解一下集合类的基本方法的使用:
import java.util.*;
public class CollectionToArray {
public static voidmain(String[] args) {
Collection collection1=newArrayList();//创建一个集合对象
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=newArrayList();
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(inti=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
2 迭代器
迭代器(Iterator)本身就是一个对象,它的工作就是遍历并选择集合序列中的对象,而客户端的程序员不必知道或关心该序列底层的结构。此外,迭代器通常被称为“轻量级”对象,创建它的代价小。但是,它也有一些限制,例如,某些迭代器只能单向移动。
Collection接口的iterator() 方法返回一个Iterator。Iterator 和您可能已经熟悉的Enumeration接口类似。使用 Iterator接口方法,您可以从头至尾遍历集合,并安全的从底层Collection中除去元素。
下面,我们看一个对于迭代器的简单使用:
import java.util.ArrayList;
import java.util.Collection;
import java.util.Iterator;
publicclass IteratorDemo {
publicstaticvoid main(String[] args) {
Collection collection = new ArrayList();
collection.add("s1");
collection.add("s2");
collection.add("s3");
Iterator 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 iterator2 =collection.iterator();
while (iterator2.hasNext()) {//移除元素
Object element =iterator2.next();
System.out.println("remove: "+element);
iterator2.remove();
}
Iterator 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!
3 List
List中的元素是运行重复的,各元素间排列顺序就是对象的插入顺序。类似于数组,我们可以通过索引来访问元素。
List接口继承了Collection接口,所以包含了Collection中所有方法。List当然也有属于自己的一些常用方法。
List接口的实现类常用的是ArrayList和LinkedList。我们知道,父类的引用可以指向任何子类的对象,所以,我们可以使用List li = new ArrayList();来创建集合类对象。
关于集合的遍历
第一种方法可以通过For循环来遍历元素。
for(int i;i<=li.size();i++){
System.out.println(list.get(i));
}
第二种遍历方法可以使用迭代器便利元素
Iterator it = li.iterator();
while(it.hasNext()){
System.out.println(it.next());
}
List集合类的add(int index,object obj)方法可以将元素添加到集合中,set(int index,object obj)方法可以修改集合中的元素。set方法的索引位置依然是从0开始。
看以下代码:
import java.util.*;
public class MyList {
public static void main(String[] args) {
String a = "A";
String b = "B";
String c = "C";
String d = "D";
List li = new LinkedList();
li.add(a);
li.add(b);
li.add(c);
li.add(d);
System.out.println("第一种访问方式");
for (int i = 0; i < li.size(); i++) {
System.out.print(li.get(i) + " ");
}
System.out.println();
System.out.println("第二种访问方式");
Iterator it = li.iterator();
while (it.hasNext()) {
System.out.print(it.next() + " ");
}
System.out.println();
System.out.println("集合中元素在未修改前");
for (int i = 0; i < li.size(); i++) {
System.out.print(li.get(i) + " ");
}
String e = "E";
System.out.println();
System.out.println("将索引位置为2的元素修改为E");
li.set(2, e);
for (int i = 0; i < li.size(); i++) {
System.out.print(li.get(i) + " ");
}
}
}
代码执行结果:
第一种访问方式
A B C D
第二种访问方式
A B C D
集合中元素在未修改前
A B C D
将索引位置为2的元素修改为E
A B E D
因为List对象中可以包含重复对象,若要获取重复对象第一次出现的位置可以使用indexOf()方法,想获取对象最后一次出现的位置可以使用lastIndexOf()方法。索引位置依然从0开始,如果指定对象在List集合中只有一个,则通过这两个方法获得的索引值是相同的。所以可以得到一种,判断集合类中某元素对象是否有重复元素的方法,就是,indexOf()方法和lastIndexOf()方法得到的值相同。
看以下代码:
import java.util.*;
public class MyList {
public static void main(String[] args) {
String a = "A";
String b = "lanyan";
String c = "C";
List li = new LinkedList();
li.add(a);
li.add(b);
li.add(b);
li.add(a);
li.add(b);
li.add(a);
li.add(c);
System.out.println("对象lanyan首次出现的位置是:" + li.indexOf(b));
System.out.println("对象lanyan最后一次出现的位置是:" + li.lastIndexOf(b));
if (li.indexOf(c) == li.lastIndexOf(c)) {
System.out.println("对象c在集合中没有重复");
}
if (li.indexOf(a) != li.lastIndexOf(a)) {
System.out.println("对象a在集合中有重复");
}
}
}
代码执行结果:
对象lanyan首次出现的位置是:1
对象lanyan最后一次出现的位置是:4
对象c在集合中没有重复
对象a在集合中有重复
4、set
集合中的对象不按特定方式排列,并且没有重复对象,它的有些实现类能对集合中的对象按特定方式排列.
set接口主要有两个实现类HashSet和TreeSet,HashSet类按照哈希算法来存取集合中的对象,存取速度比较快,HashSet类还有一个子类LinkedHashSet类,不仅
实现了哈希算法,而且实现了链表数据结构,TreeSet类实现了SortedSet接口,具有排序功能.
那么,当一个新的对象加入到Set集合中,Set的add()方法是如何判断这个对象是否已经存在于集合中的呢?
boolean isExists=false;
Iterator it=set.iterator();
while(it.hasNext())
{
Object oldObject=it.next();
if(newObject.equals(oldObject))
{
isExists=true;
break;
}
}
可见,Set采用对象的equals()方法比较两个对象是否相等,而不是采用"=="比较运算符,以下程序代码尽管两次调用了Set的add()方法,
实际上只加入了一个对象:
Set set=new HashSet();
String s1=new String("hello");
String s2=new String("hello");
set.add(s1);
set.add(s2);
虽然变量s1和s2实际上引用的是两个内存地址不同的字符串对象,但是由于s2.equals(s1)的比较结果为true,因此Set认为他们是相等的对象,当第二次调用
Set的add()方法时,add()方法不会把s2引用的字符串对象加入到集合中.
HashSet类
按照哈希算法来存取集合中的对象,具有很好的存取性能,当HashSet向集合中加入一个对象时,会调用对象的hashCode()方法获得哈希码,然后根据这个哈希码
进一步计算出对象在集合中的存放位置.
在Object类中定义了hashCode()和equals()方法,Object类的euqals()方法按照内存地址比较对象是否相等,因此如果object1.equals(object2)为true,表明object1
变量和object2变量十九上引用同一个对象.那么object1和object2的哈希码也应该相同.
***如果用户定义的类覆盖了Object类的equals()方法,但是没有覆盖Object类的hashCode()方法,就会导致当object1.equals(object2)为true时,而object1和object2的
哈希码不一定一样,这样使HashSet无法正常工作.
TreeSet类:
实现了SortedSet接口,能够对集合中的对象进行排序.
如:
Set set=new TreeSet();
set.add(new Integer(7));
set.add(new Integer(9));
set.add(new Integer(8));
Iterator it=set.iterator();
while(it.hasNext())
{
System.out.println(it.next());
}
输出结果为:6 7 8
当TreeSet向集合中加入一个对象时,会把它插入到有序的对象序列中,那么TreeSet是如何对对象进行排序的捏?TreeSet支持
两种排序方式:自然排序和客户化排序,默认情况下是自然排序.
在JDK中,有一部分类实现了Comparable接口,如Integer,Double和String等,Comparable接口有一个compareTo(Object o)方法,
它返回整数类型,对于表达式x.compareTo(y),如果返回值为0,表示x和y相等,如果返回值大于0,表示x大于y,如果小于0,表示x<y.
TreeSet调用对象的compareTo()方法比较集合中对象的大小,然后进行升序排序,这种方式称为自然排序.
客户化排序:
java.util.Comparator接口用于指定具体的排序方式,它有个compare(Object obj1,Object obj2),用于比较两个对象的大小.
当表达式compare(x,y)的值大于0,表示x大于y,小于0,表示x小于y,等于0,表示x等于y,如果想让TreeSet进按照Customer对象的
name属性进行降序排列,可以先创建实现Comparator接口的类CustomerComparator,如:
import java.util.*;
public class CustomerComparator implements Comparator
{
public int compare(Object o1,Object o2)
{
Customer c1=(Custoemr)o1;
Customer c2=(Customer)o2;
if(c1.getName().compareTo(c2.getName())>0) return -1;
if(c1.getName().compareTo(c2.getName())<0) return 1;
return 0;
}
}
接下来在构造TreeSet的实例时,调用它的TreeSet(Comparator comparator)构造方法
Set set=new TreeSet(new CustomerComparator());
Customer c1=new Customer("TOM",15);
Customer c2=new Customer("JACK",20);
Customer c3=new Customer("MIKE",38);
set.add(c1);set.add(c2);set.add(c3);
Iterator it=set.iterator();
while(it.hasNext())
{Custoemr customer=(Customer)it.next();
System.out.println(customer.getName()+"" +customer.getAge();)
}
当TreeSet向集合中加入Customer对象时,会调用CustomerComparator类的compare()方法进行排序,以上Tree按照
Custoemr对象的name属性进行降序排列,最后输出为:
TOM 15 MIKE 38 JACK 16
List(列表):对象以线性方式存储,集合中的对象按索引位置排序,可以有重复对象,允许按照对象在集合中的索引位置检索对象.
实现类有LinkedList,ArrayList和Vector,LinkedList采用链表数据结构,而ArrayList代表大小可变的数组, Vector和
ArrayList比较相似,两者的区别在于Vecotr类的实现采用了同步机制,而ArrayList没有使用同步机制/
List按索引排列:
List list=new ArrayList();
list.add(new Integer(3));
list.add(new Integer(4));
list.add(new Integer(3));
list.add(new Integer(2));
// List的get(int index)方法返回集合中由参数index指定的索引位置的对象,第一个加入到集合中的对象的索引位置为0,
for( int i=0,i<list.size;i++)
{System.out.println(list.get(i));}
输出结果为:3 4 3 2.
List只能对集合中的对象按索引位置排序,如果希望对List中的对象按其他特定方式排序,可以借助Comparator接口和Collections类.
Collections类是Java集合API中的辅助类,它提供了操纵集合的各种静态方法,其中sort()方法用于对List中的对象进行排序:
sort(List list):对List中的对象进行自然排序.
sort(List list,Comparator comparator):对List中的对象进行客户化排序,comparator参数指定排序方式.
对以下List进行自然排序:
List list=new ArrayList();
list.add(new Integer(3));
list.add(new Integer(4));
list.add(new Integer(3));
list.add(new Integer(2));
Collections.sort(list);
for(int i=0;i<list.size();i++)
{
System.out.println(list.get(i));
}
以上输出结果:2 3 3 4
Map(映射):集合中的每一个元素包含一对键对象和一对值对象,集合中没有重复的键对象,值对象可以重复,它的有写实现类能
对集合中的键对象进行排序.
Map map=new HashMap();
map.put("1","Mon");
map.put("1",Monday);
map.put("2","monday");
由于第一次和第二次加入到Map中的键对象都是1,所以第一次加入的值对象将被覆盖,而第二个和第三个的值对象虽然相同,但是
键对象不一样,所以分配了不同的地址空间,所以不会覆盖,也就是说一共有两个元素在Map集合中.
Map有两种比较常用的实现:HashMap和TreeMap.Hashmap按照哈希算法来存取键对象,有很好的存取能力,为了保证HashMap能正常工作,
和HashSet一样,要求当两个键对象通过equals()方法比较为true时,这两个键对象的hashCode()方法返回的哈希码也一样.
TreeMap实现了SortedMap接口,能对键对象进行排序,和TreeSet一样,TreeMap也支持自然排序和客户化排序两种方式,以下程序中的TreeMap
会对四个字符串类型的键对象"1","3","4","2"进行自然排序:
Map map=new TreeMap();
map.put("1","Monday");
map.put("3","Wendsday");
map.put("4","Thursday");
map.put("2","Tuesday");
//返回集合中所有键对象的集合
Set keys=map.keySet();
Iterator it=keys.iterator();
while(it.hasNext)
{String key=(String)it.next();
//根据键对象得到值对象
String value=(String)map.get(key);
System.out.println(key+"" +value);
}
以上输出结果为:1 Monday 2 Wendsday 3 Thursday 4 Tuesday
如果希望TreeMap进行客户化排序,可以调用它的另一个构造方法TreeMap(Comparator comparator),参数comparator指定具体的排序方式.
5、map
http://blog.csdn.net/wikijava/article/details/5490454