集合

Java集合框架图

 

 

  ji

 集合接口:6个接口(短虚线表示),表示不同集合类型,是集合框架的基础。

  抽象类:5个抽象类(长虚线表示),对集合接口的部分实现。可扩展为自定义集合类。

  实现类:8个实现类(实线表示),对接口的具体实现。

 

 

Array是数组,不在集合框架范畴之内,一旦选定了,它的容量大小就不能改变了,所以通常在编程中不选用数组来存放.

集合
:
集合对象:用于管理其他若干对象的对象

数组:长度不可变


List:
有顺序的,元素可以重复

遍历:for 迭代

排序:
Comparable Comparator Collections.sort()
ArrayList
:底层用数组实现的
List
特点:查询效率高,增删效率低 轻量级 线程不安全

LinkedList
:底层用双向循环链表 实现的
List
特点:查询效率低,增删效率高

Vector:
底层用数组实现List接口的另一个类

特点:重量级,占据更多的系统开销 线程安全


Set
:无顺序的,元素不可重复(值不相同)

遍历:迭代

排序:
SortedSet
HashSet
:采用哈希算法来实现Set接口

唯一性保证:重复对象equals方法返回为
true
重复对象hashCode方法返回相同的整数

不同对象 哈希码 尽量保证不同(提高效率)


SortedSet
:对一个Set排序

TreeSet
:在元素添加的同时,进行排序。也要给出排序规则

唯一性保证:根据排序规则,compareTo方法返回为0,就可以认定两个对象中有一个是重复对象。


Map
:元素是键值对 key:唯一,不可重复 value:可重复

遍历:先迭代遍历key的集合,再根据key得到
value
HashMap:
轻量级 线程不安全 允许key或者value
null
Hashtable
:重量级 线程安全 不允许key或者value
null
Properties
Hashtable的子类,keyvalue都是
String

SortedMap
:元素自动对key排序

TreeMap


集合是指一个对象可以容纳了多个对象(不是引用),这个集合对象主要用来管理维护一系列相似的对象。


集合接口类层次
:
位于
package java.util.*;
Collection

|ˉˉˉˉˉˉ|
Set List Map
↑ ↑
| |
SortedSet SortedMap

1) Set:
集合类中不允许有重复对象
;
2) SortedSet:
Set接口同,但元素按升序排列
;
3) List:
元素加载和移出时按照顺序,可以保存重复对象。

4) Map: (key-value
)存储了唯一关键字辨识和对应的值。

5) SortedMap:
Map类同,但对象按他们关键字的升序排列。


集合类层次
:
(注:JAVA1.5JAVA1.4的最大改进就是增加了对范型的支持)


Collection

|ˉˉˉˉˉˉ|
HashSet LinkedList Hashtable
(Set) Vector, ArrayList Hashmap
(List) (Map)
↑ ↑
| |
TreeSet TreeMap
(SortedSet) (SortedMap)
Collection
接口的方法:

add(Object o)
addAll(Collection c)
contains(Object o)
containsAll(Collection c)
remove(Object o)
removeAll(Collection c)
clear()
equals(Object o)
isEmpty()
iterator()
size()
toArray()
toArray(Object[] o)


五个最常用的集合类之间的区别和联系
:
1
ArrayList: 元素单个,效率高,多用于查询

2
Vector: 元素单个,线程安全,多用于查询

3
LinkedList:元素单个,多用于插入和删除

4
HashMap: 元素成对,元素可为空

5
HashTable: 元素成对,线程安全,元素不可为空


ArrayList
底层是Object数组,所以ArrayList具有数组的查询速度快的优点以及增删速度慢的缺点。

而在LinkedList的底层是一种双向循环链表。在此链表上每一个数据节点都由三部分组成:前指针(指向前面的节点的位置),数据,后指针(指向后面的节点的位置)。最后一个节点的后指针指向第一个节点的前指针,形成一个循环。

双向循环链表的查询效率低但是增删效率高。

ArrayList
LinkedList在用法上没有区别,但是在功能上还是有区别的。


LinkedList
经常用在增删操作较多而查询操作很少的情况下:队列和堆栈。

队列:先进先出的数据结构。

栈:后进先出的数据结构。

注意:使用栈的时候一定不能提供方法让不是最后一个元素的元素获得出栈的机会。


Vector
(与ArrayList相似,区别是Vector是重量级的组件,使用使消耗的资源比较多。)

结论:在考虑并发的情况下用Vector(保证线程的安全)。

在不考虑并发的情况下用ArrayList(不能保证线程的安全)。



java.util.stack
stack即为堆栈)的父类为Vector。可是stack的父类是最不应该为Vector的。因为Vector的底层是数组,且Vectorget方法(意味着它可能访问到并不属于最后一个位置元素的其他元素,很不安全)。

对于堆栈和队列只能用push类和get类。

Stack
类以后不要轻易使用。

实现栈一定要用LinkedList

(在JAVA1.5中,collectionqueue来实现队列。)


Set-HashSet
实现类:

遍历一个Set的方法只有一个:迭代器(interator)。

HashSet
中元素是无序的(这个无序指的是数据的添加顺序和后来的排列顺序不同),而且元素不可重复。

Object中除了有finalize()toString()equals(),还有hashCode()

HashSet
底层用的也是数组。

当向数组中利用add(Object o)添加对象的时候,系统先找对象的hashCode

int hc=o.hashCode();
返回的hashCode为整数值。

Int I=hc%n;
n为数组的长度),取得余数后,利用余数向数组中相应的位置添加数据,以n6为例,如果I=0则放在数组a[0]位置,如果I=1,则放在数组a[1]位置。如果equals()返回的值为true,则说明数据重复。如果equals()返回的值为false,则再找其他的位置进行比较。这样的机制就导致两个相同的对象有可能重复地添加到数组中,因为他们的hashCode不同。

如果我们能够使两个相同的对象具有相同hashcode,才能在equals()返回为真。

在实例中,定义student对象时覆盖它的hashcode

因为String类是自动覆盖的,所以当比较String类的对象的时候,就不会出现有两个相同的string对象的情况。

现在,在大部分的JDK中,都已经要求覆盖了hashCode

结论:如将自定义类用hashSet来添加对象,一定要覆盖hashcode()equals(),覆盖的原则是保证当两个对象hashcode返回相同的整数,而且equals()返回值为True

如果偷懒,没有设定equals(),就会造成返回hashCode虽然结果相同,但在程序执行的过程中会多次地调用equals(),从而影响程序执行的效率。


我们要保证相同对象的返回的hashCode一定相同,也要保证不相同的对象的hashCode尽可能不同(因为数组的边界性,hashCode还是可能相同的)。


例子:

public int hashCode(){
return name.hashcode()+age;
}
这个例子保证了相同姓名和年龄的记录返回的hashCode是相同的。


使用hashSet的优点:

hashSet
的底层是数组,其查询效率非常高。而且在增加和删除的时候由于运用的hashCode的比较开确定添加元素的位置,所以不存在元素的偏移,所以效率也非常高。因为hashSet查询和删除和增加元素的效率都非常高。

但是hashSet增删的高效率是通过花费大量的空间换来的:因为空间越大,取余数相同的情况就越小。HashSet这种算法会建立许多无用的空间。

使用hashSet类时要注意,如果发生冲突,就会出现遍历整个数组的情况,这样就使得效率非常的低。


1.1.4.
比较

Collections
类(工具类―――全是static 方法)

Public static int binarySearch(List list,Object key)
Public static void Sort(List list,Comparator com)
Public static void sort(List list)
方法一:

Comparator
接口

Int compare(Object a,Object b)
Boolean equals(Object o)
例子:

import java.util.*;
public class Test {
public static void main(String[] arg) {
ArrayList al = new ArrayList();
Person p1 = new Person("dudi");
Person p2 = new Person("cony");
Person p3 = new Person("aihao");
al.add(p1);
al.add(p2);
al.add(p3);
Collections.sort(al,p1);
for(Iterator it = al.iterator();it.hasNext();){
Person p = (Person)it.next();
System.out.println(p.name);
}
}
}
class Person implements java.util.Comparator
{
public String name;
public Person(String name){
this.name = name;
}
public int compare(Object a,Object b){
if(a instanceof Person&&b instanceof Person){
Person pa = (Person)a;
Person pb = (Person)b;
return pa.name.compareTo(pb.name);
}
return 0;
}
public boolean equals(Object a){return true;}
}
方法二

Java.lang.Comparable
Public int compareTo(Object o)
Class Person implements java.lang.Comparable{
Public int compareTo(Object o){
Comparable c1=(Comparable)this;
Comparable c2=(Comparable)o;
Return c1.name.compareTo(c2.name );
}
}
……………………………….
}

 

 

 

 

 

 

首先CollectionMap是两个毫无关系的接口,Collection是对象集合,Map是键值对集合  
  Collection
有两个子接口List
Set  
  List
可以通过下标(1,2..)来取得值,值可以重复
 
 
Set只能通过游标来取值,并且值是不能重复的
 
  ArrayList
VectorLinkedListList的实现类
 
  ArrayList
是线程不安全的,Vector是线程安全的,这两个类底层都是由数组实现的
 
  LinkedList
是线程不安全的,底层是由链表实现的
 
  HashTable
HashMapMap的实现类
 
  HashTable
是线程安全的,不能存储null
 
  HashMap
不是线程安全的,可以存储null  

 

 

 

 

实现Collection接口的类,如果底层是用数组实现,那么添加新元素花费的时间会比较多,因为他要保证这个数组的容量足够大,所以在每添加一个新元素的时候都要自动扩大数组容量....如果实现Collection接口的类底层是用链表实现,那么他查找一个元素所花费的时间会比较长,因为他不能通过下标来查找,只能一个个的遍历....所以在add()操作比较多的时候用LinkedList性能比较好,search()操作比较多的时候用ArrayListVector比较好

 

posted @ 2009-12-04 16:49  饺子吃遍天  阅读(80)  评论(0编辑  收藏  举报