Java中的集合类
集合框架中的接口
1) Collection:集合层次中的根接口,JDK没有提供这个接口直接的实现类。
2) Set:不能包含重复的元素。SortedSet是一个按照升序排列元素的Set。
3) List:是一个有序的集合,可以包含重复的元素。提供了按索引访问的方式。
4) Map:包含了key-value对。Map不能包含重复的key。SortedMap是一个按照升序排列key的Map。
集合框架中的实现类:实现list接口的ArrayList 类和LinkedList类;实现Map接口的HashMap类;实现SortedMap的TreeMap类;实现Set接口的HashSet类和LinkednHashSet类;实现SortedSet接口的TreeSet类。
ArrayList
1) ArrayList:可以将其看作是能够自动增长容量的数组。
2) 利用ArrayList的toArray()返回一个数组。
3) Arrays.asList()返回一个列表。
4) 迭代器(Iterator) 提供了一种通用的方式来访问集合中的元素。
迭代器(Iterator)的作用:可以为那些本身没有提供获取元素方法的集合类提供获取元素的途径,同时可以可以通过一个通用的方法来打印集合类对象中的元素。如可以定义以下方法,此时当要打印任何集合类对象中的元素时,只需调用此通用方法即可。
public static void printElements(Collection c)
{
Iterator i=c.iterator();
while(i.hasNext())
{
System.out.println(i.next());
}
}
Collections类
1) 排序:Collections.sort()
(1)自然排寻(natural ordering );
(2)实现比较器(Comparator)接口。
2) 取最大和最小的元素:Collections.max()、Collections.min()。
3) 在已排序的List中搜索指定的元素:Collectons.binarySearch()。
对于Collections.sort()方法,如果要对类对象进行排序,此类必须实现Comparable接口,覆盖compareTo()方法,此和Arrays.sort()方法实现Comparable接口一致。如果要事先比较器,则可以在类中利用内部类来定义比较器。
class Student implements Comparable
{
int num;
String name;
Student(int num,String name)
{
this.num=num;
this.name=name;
}
static class StuentComparator implements Comparator//内部类实现比较器
{
public int compare(Object o1,Object o2)
{
Student s1=(Student)o1;
Student s2=(Student)o2;
int result=s1.num>s2.num?1:(s1.num==s2.num?0:-1);
if(0==result)
{
result=s1.name.compareTo(s2.name);
}
return result;
}
}
public String toString()
{
return "number="+num+",name="+name;
}
public int compareTo(Object o)
{
Student s=(Student)o;
int result=num>s.num?1:(num==s.num?0:-1);
if(0==result)
{
result=name.compareTo(s.name);
}
return result;
}
}
在main中使用:
ArrayList al=new ArrayList();
al.add(new Student(1,"zhangshan"));
al.add(new Student(1,"libole"));
al.add(new Student(3,"liuliu"));
al.add(new Student(2,"wangwu"));
Collections.sort(al,new Student.StuentComparator());
此时可以利用StuentComparator比较器中的比较方法来实现ArrayList al中对Student类的排序。
LinkedList
1) LinkedList是采用双向循环链表实现的。
2) 利用LinkedList实现栈(stack)、队列(queue)、双向队列(double-ended queue )。
ArrayList和LinkedList的比较
1) ArrayList底层采用数组完成,而LinkedList则是以一般的双向链表(double-linked list)完成,其内每个对象除了数据本身外,还有两个引用,分别指向前一个元素和后一个元素。
2) 如果经常在List的开始处增加元素,或者在List中进行插入和删除操作,则应该使用LinkedList,否则的话,使用ArrayList将更加快速。
HashSet
1) 实现Set接口的hash table(哈希表),依靠HashMap来实现的。
2) 应该为要存放到散列表的各个对象定义hashCode()和equals()。
如用以下代码增加两个相同的对象,此时HashSet认为增加的两个号为2且名字同为”lisi”的对象不同,因为其主要是依靠hashCode来判断,由于是用两个new来创建对象,其hashCode不同。故要让HashSet能够认识到这是两个相同的对象,要重写hashCode()和equals()方法。
HashSet hs=new HashSet();
hs.add(new Student(1,"zhangshan"));
hs.add(new Student(2,"lisi"));
hs.add(new Student(2,"lisi"));
此时只需在Student类中增加以下方法即可:
public int hashCode()
{
return num*name.hashCode();//对于name,可以直接调用String类的hashCode()类。
}
public boolean equals(Object o)
{
Student st=(Student)o;
return (num==st.num)&&name.equals(st.name);
}
TreeSet
1) TreeSet是依靠TreeMap来实现的。
2) TreeSet是一个有序集合,TreeSet中元素将按照升序排列,缺省是按照自然顺序进行排列,意味着TreeSet中元素要实现Comparable接口。
3) 可以在构造TreeSet对象时,传递实现了Comparator接口的比较器对象。
HashSet和TreeSet的比较
HashSet是基于Hash算法实现的,其性能通常都优于TreeSet。通常都应该使用HashSet,在需要排序的功能时,才使用TreeSet。
HashMap
1) HashMap对key进行散列。
2) keySet()可以得到key值,values()可以得到key对应的值,entrySet()则可以得到key--值对。
TreeMap
TreeMap按照key进行排序。
HashMap和TreeMap的比较
和Set类似,HashMap的速度通常都比TreeMap快,只有在需要排序的功能的时候,才使用TreeMap。