??xml version="1.0" encoding="utf-8" standalone="yes"?>
TreeMap is implemented based on red-black tree structure, and it is ordered by the key.
LinkedHashMap preserves the insertion order
Hashtable is synchronized, in contrast to HashMap.
]]>
]]>
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class MapTest {
public static Map<String,String> createMap(){
Map<String,String> map=new HashMap<String, String>();
map.put("a", "111");
map.put("b", "222");
return map;
}
public static void parseMap(Map<String,String> map){
for(Iterator it=map.entrySet().iterator();it.hasNext();){
Map.Entry entry=(Map.Entry)it.next();
System.out.println("key="+entry.getKey());
System.out.println("value="+entry.getValue());
if("a".equals(entry.getKey())){
it.remove();
}
}
for(Iterator it=map.entrySet().iterator();it.hasNext();){
Map.Entry entry=(Map.Entry)it.next();
System.out.println("key1="+entry.getKey());
System.out.println("value1="+entry.getValue());
}
}
public static void main(String[] args) {
Map<String,String> map=createMap();
parseMap(map);
}
}
package chn.lass.liu.collection;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
public class ListTest {
public static List<String> createList(){
List<String> list=new ArrayList<String>();
for(int i=0;i<5;i++){
list.add(""+i);
}
return list;
}
public static void ParseList(List<String> list){
for(Iterator it=list.iterator();it.hasNext();){
String its=(String)it.next();
System.out.println("list is:"+its);
it.remove();
}
}
public static void main(String[] args) {
List<String> list=createList();
ParseList(list);
}
}
package chn.lass.liu.collection;
import java.util.Iterator;
import java.util.Vector;
public class VectorTest {
public static Vector<String> createVector(){
Vector<String> vector=new Vector<String>();
vector.addElement("aa");
vector.addElement("bb");
return vector;
}
public static void parseVector(Vector<String> vector){
for(Iterator it=vector.iterator();it.hasNext();){
String its=(String)it.next();
System.out.println("its is:"+its);
}
}
public static void main(String[] args) {
Vector<String> vector=createVector();
parseVector(vector);
}
}
package chn.lass.liu.collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Set;
public class SetTest {
public static Set<String> createSet(){
Set<String> set=new HashSet<String>();
set.add("a");
set.add("b");
return set;
}
public static void parseSet(Set<String> set){
for(Iterator it=set.iterator();it.hasNext();){
String its=(String)it.next();
System.out.println("its is:"+its);
}
}
public static void main(String[] args) {
Set<String> set=createSet();
parseSet(set);
}
}
import java.util.Queue;
public interface IMakeQueue {
public void addQueue(Object obj);
public boolean hasQueue();
public Object getQueueHeader();
public int queueSize();
public boolean delQueue();
}
package com.abin.lee.queue;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;
public class MakeQueue implements IMakeQueue{
private static Queue queue=new LinkedBlockingQueue();
public void addQueue(Object obj) {
queue.offer(obj);
}
public boolean hasQueue() {
boolean flag=false;
if(queue.isEmpty()){
flag=true;
}
return flag;
}
public Object getQueueHeader() {
Object obj=queue.peek();
return obj;
}
public int queueSize() {
int queueSize=queue.size();
return queueSize;
}
public boolean delQueue() {
boolean flag=false;
Object obj=queue.poll();
if(obj!=null){
flag=true;
}
return flag;
}
}
package com.abin.lee.queue;
import org.springframework.beans.BeansException;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.support.ClassPathXmlApplicationContext;
/**
*
* 获取spring容器Q以讉K容器中定义的其他bean
*
* @author lyltiger
* @since MOSTsView 3.0 2009-11-16
*/
public class SpringContextUtil implements ApplicationContextAware {
// Spring应用上下文环?br /> private static ApplicationContext applicationContext = new ClassPathXmlApplicationContext(
"com/abin/lee/spring/applicationContext-queue.xml");
/**
* 实现ApplicationContextAware接口的回调方法,讄上下文环?br /> *
* @param applicationContext
*/
public void setApplicationContext(ApplicationContext applicationContext) {
SpringContextUtil.applicationContext = applicationContext;
}
/**
* @return ApplicationContext
*/
public static ApplicationContext getApplicationContext() {
return applicationContext;
}
/**
* 获取对象 q里重写了beanҎ(gu)Qv主要作用
*
* @param name
* @return Object 一个以所l名字注册的bean的实?br /> * @throws BeansException
*/
public static Object getBean(String name) throws BeansException {
return applicationContext.getBean(name);
}
}
package com.abin.lee.queue;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.util.Map;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
public class QueueServlet extends HttpServlet{
protected void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, IOException {
Map map=request.getParameterMap();
String name1=(String)((Object[])map.get("name1"))[0];
String name2=(String)((Object[])map.get("name2"))[0];
MakeQueue makeQueue = (MakeQueue)SpringContextUtil.getBean("makeQueue");//bean的名U?
System.out.println(makeQueue.queueSize());
makeQueue.addQueue(name1);
makeQueue.addQueue(name2);
System.out.println(makeQueue.queueSize());
ServletOutputStream out=response.getOutputStream();
BufferedWriter writer=new BufferedWriter(new OutputStreamWriter(out));
writer.write("success");
writer.flush();
writer.close();
}
}
package com.abin.lee.spring;
import java.util.ArrayList;
import java.util.List;
import junit.framework.TestCase;
import org.apache.http.HttpEntity;
import org.apache.http.HttpResponse;
import org.apache.http.NameValuePair;
import org.apache.http.client.HttpClient;
import org.apache.http.client.entity.UrlEncodedFormEntity;
import org.apache.http.client.methods.HttpPost;
import org.apache.http.impl.client.DefaultHttpClient;
import org.apache.http.message.BasicNameValuePair;
import org.apache.http.protocol.HTTP;
import org.apache.http.util.EntityUtils;
public class SpringUnit extends TestCase {
private static final String HTTP_URL="http://localhost:1010/WebService/servlet/QueueServlet";
public void testBean() {
HttpClient client=new DefaultHttpClient();
HttpPost post=new HttpPost(HTTP_URL);
try {
List<NameValuePair> nvps=new ArrayList<NameValuePair>();
nvps.add(new BasicNameValuePair("name1", "lee"));
nvps.add(new BasicNameValuePair("name2", "abin"));
post.setEntity(new UrlEncodedFormEntity(nvps,HTTP.UTF_8));
HttpResponse response=client.execute(post);
HttpEntity entity=response.getEntity();
String result=EntityUtils.toString(entity);
System.out.println("result="+result);
} catch (Exception e) {
e.printStackTrace();
}
}
}
<?xml version="1.0" encoding="UTF-8"?> <!-- Queue全局队列 --> </beans>
<beans xmlns=" xmlns:xsi=" xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/aop
http://www.springframework.org/schema/aop/spring-aop-3.0.xsd
http://www.springframework.org/schema/context
<bean id="makeQueue" class="com.abin.lee.queue.MakeQueue" scope="singleton" />
]]>
import java.util.Collections;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
public class CollectionIterator {
/**
* 创徏二维MAP
*
* @return
*/
public static Map<String, Map<String, String>> createMap() {
Map<String, Map<String, String>> map2 = Collections
.synchronizedMap(new HashMap<String, Map<String, String>>());
Map<String, String> map1 = Collections
.synchronizedMap(new HashMap<String, String>());
Map<String, String> map3 = Collections
.synchronizedMap(new HashMap<String, String>());
map1.put("abin", "varyall");
map1.put("abing", "boy");
map1.put("peng", "boy");
map1.put("pengzi", "man");
map2.put("user", map1);
map3.put("chinese", "beijing");
map3.put("china", "shanghai");
map2.put("contury", map3);
return map2;
}
/**
* 解析二维MAP
* @param map
* @return
*/
public static String getMap(Map<String, Map<String, String>> map) {
for (Iterator iterator = map.entrySet().iterator(); iterator.hasNext();) {
Map.Entry entry=(Map.Entry)iterator.next();
//先遍历一lmap
System.out.println("one map name="+entry.getKey());
System.out.println("one map name="+entry.getValue());
Map<String, String> map1=(Map<String, String>)entry.getValue();
if(entry.getValue() instanceof Map){
for(Iterator it=map1.entrySet().iterator();it.hasNext();){
Map.Entry entry2=(Map.Entry)it.next();
//再遍历二lmap
System.out.println("two map name="+entry2.getKey());
System.out.println("two map name="+entry2.getValue());
}
}
}
return null;
}
public static void main(String[] args) {
Map<String, Map<String, String>> map=createMap();
getMap(map);
}
}
Set,List,Map,Vector,ArrayList的区?
JAVA的容?--List,Map,Set
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection接口
Collection是最基本的集合接口,一个Collection代表一lObjectQ即Collection的元素(ElementsQ。一?Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接承自Collection的类QJava SDK提供的类都是l承自Collection?#8220;子接?#8221;如List和Set?
所有实现Collection接口的类都必L供两个标准的构造函敎ͼ无参数的构造函数用于创Z个空的CollectionQ有一?Collection参数的构造函数用于创Z个新的CollectionQ这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection?
如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个P代子Q用该q代子即可逐一讉KCollection中每一个元素。典型的用法如下Q?
Iterator it = collection.iterator(); // 获得一个P代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一个元?
}
由Collection接口z的两个接口是List和Set?
List接口
List是有序的CollectionQ用此接口能够_的控制每个元素插入的位置。用戯够用烦引(元素在List中的位置Q类g数组下标Q来讉KList中的元素Q这cM于Java的数l?
和下面要提到的Set不同QList允许有相同的元素?
除了hCollection接口必备的iterator()Ҏ(gu)外,Listq提供一个listIterator()Ҏ(gu)Q返回一?ListIterator接口Q和标准的Iterator接口相比QListIterator多了一些add()之类的方法,允许dQ删除,讑֮元素Q还能向前或向后遍历?
实现List接口的常用类有LinkedListQArrayListQVector和Stack?
LinkedListc?
LinkedList实现了List接口Q允许null元素。此外LinkedList提供额外的getQremoveQinsertҎ(gu)?LinkedList的首部或N。这些操作LinkedList可被用作堆栈QstackQ,队列QqueueQ或双向队列QdequeQ?
注意LinkedList没有同步Ҏ(gu)。如果多个线E同时访问一个ListQ则必须自己实现讉K同步。一U解x法是在创建List时构造一个同步的ListQ?
List list = Collections.synchronizedList(new LinkedList(...));
ArrayListc?
ArrayList实现了可变大的数组。它允许所有元素,包括null。ArrayList没有同步?
sizeQisEmptyQgetQsetҎ(gu)q行旉为常数。但是addҎ(gu)开销为分摊的常数Q添加n个元素需要O(n)的时间。其他的Ҏ(gu)q行旉为线性?
每个ArrayList实例都有一个容量(CapacityQ,即用于存储元素的数组的大。这个容量可随着不断d新元素而自动增加,但是增长法q没有定义。当需要插入大量元素时Q在插入前可以调用ensureCapacityҎ(gu)来增加ArrayList的容量以提高插入效率?
和LinkedList一PArrayList也是非同步的QunsynchronizedQ?
Vectorc?
Vector非常cMArrayListQ但是Vector是同步的。由Vector创徏的IteratorQ虽然和ArrayList创徏?Iterator是同一接口Q但是,因ؓVector是同步的Q当一个Iterator被创且正在被用,另一个线E改变了Vector的状态(例如Q添加或删除了一些元素)Q这时调用Iterator的方法时抛出ConcurrentModificationExceptionQ因此必L莯异常?
Stack c?
Stackl承自VectorQ实C个后q先出的堆栈。Stack提供5个额外的Ҏ(gu)使得Vector得以被当作堆栈用。基本的push和pop Ҏ(gu)Q还有peekҎ(gu)得到栈顶的元素,emptyҎ(gu)试堆栈是否为空QsearchҎ(gu)一个元素在堆栈中的位置。Stack刚创建后是空栈?
Set接口
Set是一U不包含重复的元素的CollectionQ即L的两个元素e1和e2都有e1.equals(e2)=falseQSet最多有一个null元素?
很明显,Set的构造函数有一个约束条Ӟ传入的Collection参数不能包含重复的元素?
h意:必须心操作可变对象QMutable ObjectQ。如果一个Set中的可变元素改变了自w状态导致Object.equals(Object)=true导致一些问题?
Map接口
h意,Map没有l承Collection接口QMap提供key到value的映。一个Map中不能包含相同的keyQ每个key只能映射一?value。Map接口提供3U集合的视图QMap的内容可以被当作一lkey集合Q一lvalue集合Q或者一lkey-value映射?
Hashtablec?
Hashtablel承Map接口Q实C个key-value映射的哈希表。Q何非I(non-nullQ的对象都可作ؓkey或者value?
d数据使用put(key, value)Q取出数据用get(key)Q这两个基本操作的时间开销为常数?
Hashtable通过initial capacity和load factor两个参数调整性能。通常~省的load factor 0.75较好地实C旉和空间的均衡。增大load factor可以节省I间但相应的查找旉增大,q会影响像get和putq样的操作?
使用Hashtable的简单示例如下,?Q?Q?攑ֈHashtable中,他们的key分别?#8221;one”Q?#8221;two”Q?#8221;three”Q?
Hashtable numbers = new Hashtable();
numbers.put(“one”, new Integer(1));
numbers.put(“two”, new Integer(2));
numbers.put(“three”, new Integer(3));
要取Z个数Q比?Q用相应的keyQ?
Integer n = (Integer)numbers.get(“two”);
System.out.println(“two = ” + n);
׃作ؓkey的对象将通过计算其散列函数来定与之对应的value的位|,因此M作ؓkey的对象都必须实现hashCode和equalsҎ(gu)。hashCode和equalsҎ(gu)l承自根cObjectQ如果你用自定义的类当作key的话Q要相当心Q按照散列函数的定义Q如果两个对象相同,即obj1.equals(obj2)=trueQ则它们的hashCode必须相同Q但如果两个对象不同Q则它们的hashCode不一定不同,如果两个不同对象的hashCode相同Q这U现象称为冲H,冲突会导致操作哈希表的时间开销增大Q所以尽量定义好的hashCode()Ҏ(gu)Q能加快哈希表的操作?
如果相同的对象有不同的hashCodeQ对哈希表的操作会出现意想不到的l果Q期待的getҎ(gu)q回nullQ,要避免这U问题,只需要牢C条:要同时复写equalsҎ(gu)和hashCodeҎ(gu)Q而不要只写其中一个?
Hashtable是同步的?
HashMapc?
HashMap和HashtablecMQ不同之处在于HashMap是非同步的,q且允许nullQ即null value和null key。,但是HashMap视ؓCollectionӞvalues()Ҏ(gu)可返回CollectionQ,其P代子操作旉开销和HashMap 的容量成比例。因此,如果q代操作的性能相当重要的话Q不要将HashMap的初始化定w讑־q高Q或者load factorq低?
WeakHashMapc?
WeakHashMap是一U改q的HashMapQ它对key实行“弱引?#8221;Q如果一个key不再被外部所引用Q那么该key可以被GC回收?
ȝ
如果涉及到堆栈,队列{操作,应该考虑用ListQ对于需要快速插入,删除元素Q应该用LinkedListQ如果需要快速随问元素,应该使用ArrayList?
如果E序在单U程环境中,或者访问仅仅在一个线E中q行Q考虑非同步的c,其效率较高,如果多个U程可能同时操作一个类Q应该用同步的cR?
要特别注意对哈希表的操作Q作为key的对象要正确复写equals和hashCodeҎ(gu)?
量q回接口而非实际的类型,如返回List而非ArrayListQ这样如果以后需要将ArrayList换成LinkedListӞ客户端代码不用改变。这是针对抽象~程?
Java 集合c?map set list arraylist hashmap hashtable(?
Vector的方法都是同步的(Synchronized),是线E安全的(thread-safe)Q而ArrayList的方法不是,׃U程的同步必然要影响性能Q因?ArrayList的性能比Vector好?
当Vector或ArrayList中的元素过它的初始大小?Vector会将它的定wd?而ArrayList只增?0%的大,q样,ArrayList有利于节约内存I间?
Hashtable和HashMap
它们的性能斚w的比较类?Vector和ArrayListQ比如Hashtable的方法是同步?而HashMap的不是?
ArrayList和LinkedList
?于处理一列数据项,Java提供了两个类ArrayList和LinkedList,ArrayList的内部实现是Z内部数组Object[],所?从概念上?它更象数l,但LinkedList的内部实现是Z一l连接的记录,所?它更象一个链表结构,所?它们在性能上有很大的差别?nbsp;
Q?Q?从上面的分析可知,在ArrayList的前面或中间插入数据?你必d其后的所有数据相应的后移,q样必然要花费较多时_所?当你的操作是在一?数据的后面添加数据而不是在前面或中?q且需要随机地讉K其中的元素时,使用ArrayList会提供比较好的性能?nbsp;
Q?Q而访问链表中的某个元素时,必M链表的一端开始沿着q接方向一个一个元素地L?直到扑ֈ所需的元素ؓ止,所?当你的操作是在一列数据的前面或中间添加或删除数据,q且按照序讉K其中的元素时,应该用LinkedList了?nbsp;
Q?Q如果在~程?1Q?两种情Ş交替出现,q时,你可以考虑使用Listq样的通用接口,而不用关心具体的实现Q在具体的情形下,它的性能由具体的实现来保证?
讄集合cȝ初始大小
在Java 集合框架中的大部分类的大是可以随着元素个数的增加而相应的增加的,我们g不用兛_它的初始大小,但如果我们考虑cȝ性能问题?׃定要考虑可?地设|好集合对象的初始大?q将大大提高代码的性能Q比?Hashtable~省的初始大ؓ101,载入因子?.75,卛_果其中的元素个数过 75?它就必须增加大小q新组l元素,所?如果你知道在创徏一个新的Hashtable对象时就知道元素的确切数目如?10,那么,应其初始 大小设ؓ110/0.75=148,q样,可以避免重新组l内存ƈ增加大小?
特别要理解的Q?
Hashtablec?
Hashtablel承Map接口Q实C个key-value映射的哈希表。Q何非I(non-nullQ的对象都可作ؓkey或者value?
d数据使用put(key, value)Q取出数据用get(key)Q这两个基本操作的时间开销为常数?
Hashtable 通过initial capacity和load factor两个参数调整性能。通常~省的load factor 0.75较好地实C旉和空间的 均衡。增大load factor可以节省I间但相应的查找旉增大,q会影响像get和putq样的操作?
使用Hashtable的简单示例如下,?Q?Q?攑ֈHashtable中,他们的key分别?#8221;one”Q?#8221;two”Q?#8221;three”Q?
Hashtable numbers = new Hashtable();
numbers.put(“one”, new Integer(1));
numbers.put(“two”, new Integer(2));
numbers.put(“three”, new Integer(3));
要取Z个数Q比?Q用相应的keyQ?
Integer n = (Integer)numbers.get(“two”);
System.out.println(“two = ” + n);
׃作ؓkey的对象将通过计算其散列函数来定与之对应的value的位|,因此M作ؓkey的对象都必须实现hashCode和equals?法。hashCode和equalsҎ(gu)l承自根cObjectQ如果你用自定义的类当作key的话Q要相当心Q按照散列函数的定义Q如果两个对象相 同,即obj1.equals(obj2)=trueQ则它们的hashCode必须相同Q但如果两个对象不同Q则它们的hashCode不一定不同,?果两个不同对象的hashCode相同Q这U现象称为冲H,冲突会导致操作哈希表的时间开销增大Q所以尽量定义好的hashCode()Ҏ(gu)Q能加快哈希 表的操作?
如果相同的对象有不同的hashCodeQ对哈希表的操作会出现意想不到的l果Q期待的getҎ(gu)q回nullQ,要避免这U问题,只需要牢C条:要同时复写equalsҎ(gu)和hashCodeҎ(gu)Q而不要只写其中一个?
Hashtable是同步的?
HashMapc?
HashMap和HashtablecMQ不同之处在于HashMap是非同步的,q且允许nullQ即null value和null key。,?是将HashMap视ؓCollectionӞvalues()Ҏ(gu)可返回CollectionQ,其P代子操作旉开销和HashMap的容量成?例。因此,如果q代操作的性能相当重要的话Q不要将HashMap的初始化定w讑־q高Q或者load factorq低?
LinkedListc?
LinkedList实现了List接口Q允许null元素。此外LinkedList提供额外的getQremoveQinsertҎ(gu)?LinkedList的首部或N。这些操作LinkedList可被用作堆栈QstackQ,队列QqueueQ或双向队列QdequeQ?
注意LinkedList没有同步Ҏ(gu)。如果多个线E同时访问一个ListQ则必须自己实现讉K同步。一U解x法是在创建List时构造一个同步的ListQ?
List list = Collections.synchronizedList(new LinkedList(...));
ArrayListc?
ArrayList实现了可变大的数组。它允许所有元素,包括null。ArrayList没有同步?
sizeQisEmptyQgetQsetҎ(gu)q行旉为常数。但是addҎ(gu)开销为分摊的常数Q添加n个元素需要O(n)的时间。其他的Ҏ(gu)q行旉为线性?
每个ArrayList实例都有一个容量(CapacityQ,即用于存储元素的数组的大。这个容量可随着不断d新元素而自动增加,但是增长法q?没有定义。当需要插入大量元素时Q在插入前可以调用ensureCapacityҎ(gu)来增加ArrayList的容量以提高插入效率?
和LinkedList一PArrayList也是非同步的QunsynchronizedQ?
Vectorc?
Vector非常cMArrayListQ但是Vector是同步的。由Vector创徏的IteratorQ虽然和ArrayList创徏?Iterator是同一接口Q但是,因ؓVector是同步的Q当一个Iterator被创且正在被用,另一个线E改变了Vector的状态(?如,d或删除了一些元素)Q这时调用Iterator的方法时抛出ConcurrentModificationExceptionQ因此必L莯 异常?
l说Java之utilc?
U性表Q链表,哈希表是常用的数据结构,在进行Java开发时QJDK已经为我们提供了一pd相应的类来实现基本的数据l构。这些类均在java.util包中。本文试N过单的描述Q向读者阐q各个类的作用以及如何正用这些类?
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection接口
Collection是最基本的集合接口,一个Collection代表一lObjectQ即Collection的元素(ElementsQ。一?Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接承自Collection的类QJava SDK提供的类都是l承自Collection?#8220;子接?#8221;如List和Set?br /> 所有实现Collection接口的类都必L供两个标准的 构造函敎ͼ无参数的构造函数用于创Z个空的CollectionQ有一个Collection参数的构造函数用于创Z个新的CollectionQ这 个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection?br /> 如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个P代子Q用该q代子即可逐一讉KCollection中每一个元素。典型的用法如下Q?br /> Iterator it = collection.iterator(); // 获得一个P代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一个元?br /> }
由Collection接口z的两个接口是List和Set?
List接口
List是有序的CollectionQ用此接口能够_的控制每个元素插入的位置。用戯够用烦引(元素在List中的位置Q类g数组下标Q来讉KList中的元素Q这cM于Java的数l?br />和下面要提到的Set不同QList允许有相同的元素?br /> 除了hCollection接口必备的iterator()Ҏ(gu)外,Listq提供一个listIterator()Ҏ(gu)Q返回一?ListIterator接口Q和标准的Iterator接口相比QListIterator多了一些add()之类的方法,允许dQ删除,讑֮元素Q?q能向前或向后遍历?br /> 实现List接口的常用类有LinkedListQArrayListQVector和Stack?
LinkedListc?/strong> ArrayListc?/strong> Vectorc?/strong> Stack c?/strong> Set接口 Map接口 Hashtablec?/strong> HashMapc?/strong> WeakHashMapc?/strong> ȝ
LinkedList实现了List接口Q允许null元素。此外LinkedList提供额外的getQremoveQinsertҎ(gu)?LinkedList的首部或N。这些操作LinkedList可被用作堆栈QstackQ,队列QqueueQ或双向队列QdequeQ?br /> 注意LinkedList没有同步Ҏ(gu)。如果多个线E同时访问一个ListQ则必须自己实现讉K同步。一U解x法是在创建List时构造一个同步的ListQ?br /> List list = Collections.synchronizedList(new LinkedList(...));
ArrayList实现了可变大的数组。它允许所有元素,包括null。ArrayList没有同步?br />sizeQisEmptyQgetQsetҎ(gu)q行旉为常数。但是addҎ(gu)开销为分摊的常数Q添加n个元素需要O(n)的时间。其他的Ҏ(gu)q行旉为线性?br /> 每个ArrayList实例都有一个容量(CapacityQ,即用于存储元素的数组的大。这个容量可随着不断d新元素而自动增加,但是增长法q?没有定义。当需要插入大量元素时Q在插入前可以调用ensureCapacityҎ(gu)来增加ArrayList的容量以提高插入效率?br /> 和LinkedList一PArrayList也是非同步的QunsynchronizedQ?
Vector非常cMArrayListQ但是Vector是同步的。由Vector创徏的IteratorQ虽然和ArrayList创徏?Iterator是同一接口Q但是,因ؓVector是同步的Q当一个Iterator被创且正在被用,另一个线E改变了Vector的状态(?如,d或删除了一些元素)Q这时调用Iterator的方法时抛出ConcurrentModificationExceptionQ因此必L莯 异常?
Stackl承自VectorQ实C个后q先出的堆栈。Stack提供5个额外的Ҏ(gu)使得Vector得以被当作堆栈用。基本的push和pop?法,q有peekҎ(gu)得到栈顶的元素,emptyҎ(gu)试堆栈是否为空QsearchҎ(gu)一个元素在堆栈中的位置。Stack刚创建后是空栈?
Set是一U不包含重复的元素的CollectionQ即L的两个元素e1和e2都有e1.equals(e2)=falseQSet最多有一个null元素?br /> 很明显,Set的构造函数有一个约束条Ӟ传入的Collection参数不能包含重复的元素?br /> h意:必须心操作可变对象QMutable ObjectQ。如果一个Set中的可变元素改变了自w状态导致Object.equals(Object)=true导致一些问题?
h意,Map没有l承Collection接口QMap提供key到value的映。一个Map中不能包含相同的keyQ每个key只能映射一?value。Map接口提供3U集合的视图QMap的内容可以被当作一lkey集合Q一lvalue集合Q或者一lkey-value映射?
Hashtablel承Map接口Q实C个key-value映射的哈希表。Q何非I(non-nullQ的对象都可作ؓkey或者value?br /> d数据使用put(key, value)Q取出数据用get(key)Q这两个基本操作的时间开销为常数?br />Hashtable 通过initial capacity和load factor两个参数调整性能。通常~省的load factor 0.75较好地实C旉和空间的均衡。增大load factor可以节省I间但相应的查找旉增大,q会影响像get和putq样的操作?br />使用Hashtable的简单示例如下,?Q?Q?攑ֈHashtable中,他们的key分别?#8221;one”Q?#8221;two”Q?#8221;three”Q?br /> Hashtable numbers = new Hashtable();
numbers.put(“one”, new Integer(1));
numbers.put(“two”, new Integer(2));
numbers.put(“three”, new Integer(3));
要取Z个数Q比?Q用相应的keyQ?br /> Integer n = (Integer)numbers.get(“two”);
System.out.println(“two = ” + n);
׃作ؓkey的对象将通过计算其散列函数来定与之对应的value的位|,因此M作ؓkey的对象都必须实现hashCode和equals?法。hashCode和equalsҎ(gu)l承自根cObjectQ如果你用自定义的类当作key的话Q要相当心Q按照散列函数的定义Q如果两个对象相 同,即obj1.equals(obj2)=trueQ则它们的hashCode必须相同Q但如果两个对象不同Q则它们的hashCode不一定不同,?果两个不同对象的hashCode相同Q这U现象称为冲H,冲突会导致操作哈希表的时间开销增大Q所以尽量定义好的hashCode()Ҏ(gu)Q能加快哈希 表的操作?br /> 如果相同的对象有不同的hashCodeQ对哈希表的操作会出现意想不到的l果Q期待的getҎ(gu)q回nullQ,要避免这U问题,只需要牢C条:要同时复写equalsҎ(gu)和hashCodeҎ(gu)Q而不要只写其中一个?br /> Hashtable是同步的?
HashMap和HashtablecMQ不同之处在于HashMap是非同步的,q且允许nullQ即null value和null key。,但是HashMap视ؓCollectionӞvalues()Ҏ(gu)可返回CollectionQ,其P代子操作旉开销和HashMap 的容量成比例。因此,如果q代操作的性能相当重要的话Q不要将HashMap的初始化定w讑־q高Q或者load factorq低?
WeakHashMap是一U改q的HashMapQ它对key实行“弱引?#8221;Q如果一个key不再被外部所引用Q那么该key可以被GC回收?
如果涉及到堆栈,队列{操作,应该考虑用ListQ对于需要快速插入,删除元素Q应该用LinkedListQ如果需要快速随问元素,应该使用ArrayList?br /> 如果E序在单U程环境中,或者访问仅仅在一个线E中q行Q考虑非同步的c,其效率较高,如果多个U程可能同时操作一个类Q应该用同步的cR?br /> 要特别注意对哈希表的操作Q作为key的对象要正确复写equals和hashCodeҎ(gu)?br /> 量q回接口而非实际的类型,如返回List而非ArrayListQ这样如果以后需要将ArrayList换成LinkedListӞ客户端代码不用改变。这是针对抽象~程?
1. ArrayList概述Q?/span>
ArrayList是List接口的可变数l的实现。实C所有可选列表操作,q允许包?null 在内的所有元素。除了实?List 接口外,此类q提供一些方法来操作内部用来存储列表的数l的大小?br /> 每个ArrayList实例都有一个容量,该容量是指用来存储列表元素的数组的大。它L臛_{于列表的大。随着向ArrayList中不断添加元 素,其容量也自动增长。自动增长会带来数据向新数组的重新拷贝,因此Q如果可预知数据量的多少Q可在构造ArrayList时指定其定w。在d大量元素 前,应用E序也可以用ensureCapacity操作来增加ArrayList实例的容量,q可以减递增式再分配的数量?
注意Q此实现不是同步的。如果多个线E同时访问一个ArrayList实例Q而其中至一个线E从l构上修改了列表Q那么它必须保持外部同步?/p>
2. ArrayList的实玎ͼ
对于ArrayList而言Q它实现List接口、底层用数l保存所有元素。其操作基本上是Ҏ(gu)l的操作。下面我们来分析ArrayList的源代码Q?/p>
1) 底层使用数组实现Q?/span>
2) 构造方法:
ArrayList提供了三U方式的构造器Q可以构造一个默认初始容量ؓ10的空列表、构造一个指定初始容量的I列表以及构造一个包含指定collection的元素的列表Q这些元素按照该collection的P代器q回它们的顺序排列的?/p>
3) 存储Q?/span> 4) dQ?/span> 5) 删除Q?/span> 注意Q从数组中移除元素的操作Q也会导致被U除的元素以后的所有元素的向左Ud一个位|?br /> 6) 调整数组定wQ?/span> 从上qC码中可以看出Q数l进行扩Ҏ(gu)Q会老数l中的元素重新拷贝一份到新的数组中,每次数组定w的增长大U是其原定w?.5倍。这U操作的代h(hun)是很 高的Q因此在实际使用Ӟ我们应该量避免数组定w的扩张。当我们可预知要保存的元素的多少Ӟ要在构造ArrayList实例Ӟ指定其定wQ以避免 数组扩容的发生。或者根据实际需求,通过调用ensureCapacityҎ(gu)来手动增加ArrayList实例的容量?br /> ArrayListq给我们提供了将底层数组的容量调整ؓ当前列表保存的实际元素的大小的功能。它可以通过trimToSizeҎ(gu)来实现。代码如下: 7) Fail-Fast机制Q?/span>
ArrayList提供了set(int index, E element)、add(E e)、add(int index, E element)、addAll(Collection<? extends E> c)、addAll(int index, Collection<? extends E> c)q些d元素的方法。下面我们一一讲解Q?/p>
ArrayList提供了根据下标或者指定对象两U方式的删除功能。如下:
从上面介l的向ArrayList中存储元素的代码中,我们看到Q每当向数组中添加元素时Q都要去查添加后元素的个数是否会出当前数组的长度,如果?出,数组会q行扩容Q以满d数据的需求。数l扩定w过一个公开的方法ensureCapacity(int minCapacity)来实现。在实际d大量元素前,我也可以使用ensureCapacity来手动增加ArrayList实例的容量,以减递增 式再分配的数量?/p>
ArrayList也采用了快速失败的机制Q通过记录modCount参数来实现。在面对q发的修Ҏ(gu)QP代器很快׃完全p|Q而不是冒着在将来某个不定旉发生L不确定行为的风险。具体介l请参考我之前的文章深入Java集合学习pdQHashMap的实现原?中的Fail-Fast机制?br /> 8) 关于其他 的一些方法的实现都很单易懂,读者可参照API文档和源代码Q一看便知,q里׃再多说?/p>
3. 相关阅读Q?/span>
本系列的文章之前q整理了以下几篇Q有兴趣的可以参考,望与大家分n心得Q共同进步:
1) 深入Java集合学习pdQHashMap的实现原??br /> 2) 深入Java集合学习pdQLinkedHashMap的实现原??br /> 3) 深入Java集合学习pdQHashSet的实现原??br /> 4) 深入Java集合学习pdQLinkedHashSet的实现原??/p>
"学习新版语言的一个危险就是疯狂用新的语法结?
先学习一下enum的简单应用,以下z的代码已经包括enum所提供的绝大部分功能?/p>
1.enum的应用,包括定义Q遍历,switchQenumsetQenummap{?/p>
Java代码
import java.util.EnumMap;
有什么不好了Q大安q样用了很长旉了,没什么问题啊?br />首先Q它不是cd安全的。你必须保是int
其次Q你q要保它的范围??
最后,很多时候你打印出来的时候,你只看到 1 ? Q?/p>
但其没有看到代码的hq不知道你的企图Q抛弃你所有旧的public static final帔R?/p>
2.可以创徏一个enumc,把它看做一个普通的cR除了它不能l承其他cM?java是单l承Q它已经l承了Enum),
可以d其他Ҏ(gu)Q覆盖它本n的方?/p>
3.switch()参数可以使用enum?/p>
4.values()Ҏ(gu)是编译器插入到enum定义中的staticҎ(gu)Q所以,当你enum实例向上转型为父cEnum是,values()׃可访问了。解军_法:在Class中有一个getEnumConstants()Ҏ(gu)Q所以即便Enum接口中没有values()Ҏ(gu)Q我们仍然可以通过Class对象取得所有的enum实例
5.无法从enuml承子类Q如果需要扩展enum中的元素Q在一个接口的内部Q创建实现该接口的枚举,以此元素进行分l。达到将枚D元素q行分组?/p>
6.使用EnumSet代替标志。enum要求其成员都是唯一的,但是enum中不能删除添加元素?/p>
7.EnumMap的key是enumQvalue是Q何其他Object对象?/p>
8.enum允许E序员ؓeunm实例~写Ҏ(gu)。所以可以ؓ每个enum实例赋予各自不同的行为?/p>
9.使用enum的职责链(Chain of Responsibility) .q个关系到设计模式的职责链模式。以多种不同的方法来解决一个问题。然后将他们链接在一赗当一个请求到来时Q遍历这个链Q直到链中的某个解决Ҏ(gu)能够处理该请求?/p>
10.使用enum的状态机
11.使用enum多\分发
转蝲自:http://blog.csdn.net/mqboss/article/details/5647851
public interface UserService {
public static enum UserType{
UserBasic("Basic Information"),
UserName("Name Of User"),
UserSex("Sex Of User"),
UserAge("Age Of User"),
UserInitialize("Initialize Of User");
private String info;
private UserType(String _info){
this.info=_info;
}
public String getObject(){
return info;
}
};
int UserSum(int one,int two,UserType userInfo);
String Welcome(String username,UserType userInfo);
}
package com.abin.inter.serviceImpl;
import com.abin.inter.service.UserService;
public class UserServiceImpl implements UserService{
@Override
public int UserSum(int one, int two,UserType userInfo) {
UserType user=UserType.UserInitialize;
System.out.println("Enum Info:"+user.getObject());
if(userInfo.equals(UserType.UserAge)){
System.out.println("UserInfo:"+userInfo);
return one+two;
}
return 0;
}
@Override
public String Welcome(String username,UserType userInfo) {
UserType user=UserType.UserInitialize;
System.out.println("Enum Info:"+user);
if(userInfo.equals(UserType.UserName)){
System.out.println("UserInfo:"+userInfo);
return "Ƣ迎"+username;
}
return "NOT WELCOME";
}
@Override
public String toString() {
// TODO Auto-generated method stub
return super.toString();
}
}
package com.abin.inter.test;
import com.abin.inter.service.UserService;
import com.abin.inter.service.UserService.UserType;
import com.abin.inter.serviceImpl.UserServiceImpl;
import junit.framework.TestCase;
public class TestUser extends TestCase{
public void test(){
UserService service=new UserServiceImpl();
UserType userInfo=UserType.UserAge;
int result=service.UserSum(10, 17, userInfo);
System.out.println("UserSum="+result);
UserType userInfo1=UserType.UserName;
String result1=service.Welcome("abin", userInfo1);
System.out.println("Welcome="+result1);
}
}