JAVA的容器---List,Map,Set
Collection
├List
│├LinkedList
│├ArrayList
│└Vector
│ └Stack
└Set
Map
├Hashtable
├HashMap
└WeakHashMap
Collection接口
Collection是最基本的集合接口,一个Collection代表一组Object,即Collection的元素(Elements)。一些 Collection允许相同的元素而另一些不行。一些能排序而另一些不行。Java SDK不提供直接继承自Collection的类,Java SDK提供的类都是继承自Collection的“子接口”如List和Set。
所有实现Collection接口的类都必须提供两个标准的构造函数:无参数的构造函数用于创建一个空的Collection,有一个 Collection参数的构造函数用于创建一个新的Collection,这个新的Collection与传入的Collection有相同的元素。后一个构造函数允许用户复制一个Collection。
如何遍历Collection中的每一个元素?不论Collection的实际类型如何,它都支持一个iterator()的方法,该方法返回一个迭代子,使用该迭代子即可逐一访问Collection中每一个元素。典型的用法如下:
Iterator it = collection.iterator(); // 获得一个迭代子
while(it.hasNext()) {
Object obj = it.next(); // 得到下一个元素
}
由Collection接口派生的两个接口是List和Set。
List接口
List是有序的Collection,使用此接口能够精确的控制每个元素插入的位置。用户能够使用索引(元素在List中的位置,类似于数组下标)来访问List中的元素,这类似于Java的数组。
和下面要提到的Set不同,List允许有相同的元素。
除了具有Collection接口必备的iterator()方法外,List还提供一个listIterator()方法,返回一个 ListIterator接口,和标准的Iterator接口相比,ListIterator多了一些add()之类的方法,允许添加,删除,设定元素,还能向前或向后遍历。
实现List接口的常用类有LinkedList,ArrayList,Vector和Stack。
LinkedList类
LinkedList实现了List接口,允许null元素。此外LinkedList提供额外的get,remove,insert方法在 LinkedList的首部或尾部。这些操作使LinkedList可被用作堆栈(stack),队列(queue)或双向队列(deque)。
注意LinkedList没有同步方法。如果多个线程同时访问一个List,则必须自己实现访问同步。一种解决方法是在创建List时构造一个同步的List:
List list = Collections.synchronizedList(new LinkedList(...));
ArrayList类
ArrayList实现了可变大小的数组。它允许所有元素,包括null。ArrayList没有同步。
size,isEmpty,get,set方法运行时间为常数。但是add方法开销为分摊的常数,添加n个元素需要O(n)的时间。其他的方法运行时间为线性。
每个ArrayList实例都有一个容量(Capacity),即用于存储元素的数组的大小。这个容量可随着不断添加新元素而自动增加,但是增长算法并没有定义。当需要插入大量元素时,在插入前可以调用ensureCapacity方法来增加ArrayList的容量以提高插入效率。
和LinkedList一样,ArrayList也是非同步的(unsynchronized)。
Vector类
Vector非常类似ArrayList,但是Vector是同步的。由Vector创建的Iterator,虽然和ArrayList创建的 Iterator是同一接口,但是,因为Vector是同步的,当一个Iterator被创建而且正在被使用,另一个线程改变了Vector的状态(例如,添加或删除了一些元素),这时调用Iterator的方法时将抛出ConcurrentModificationException,因此必须捕获该异常。
Stack 类
Stack继承自Vector,实现一个后进先出的堆栈。Stack提供5个额外的方法使得Vector得以被当作堆栈使用。基本的push和pop 方法,还有peek方法得到栈顶的元素,empty方法测试堆栈是否为空,search方法检测一个元素在堆栈中的位置。Stack刚创建后是空栈。
Set接口
Set是一种不包含重复的元素的Collection,即任意的两个元素e1和e2都有e1.equals(e2)=false,Set最多有一个null元素。
很明显,Set的构造函数有一个约束条件,传入的Collection参数不能包含重复的元素。
请注意:必须小心操作可变对象(Mutable Object)。如果一个Set中的可变元素改变了自身状态导致Object.equals(Object)=true将导致一些问题。
Map接口
请注意,Map没有继承Collection接口,Map提供key到value的映射。一个Map中不能包含相同的key,每个key只能映射一个 value。Map接口提供3种集合的视图,Map的内容可以被当作一组key集合,一组value集合,或者一组key-value映射。
Hashtable类
Hashtable继承Map接口,实现一个key-value映射的哈希表。任何非空(non-null)的对象都可作为key或者value。
添加数据使用put(key, value),取出数据使用get(key),这两个基本操作的时间开销为常数。
Hashtable通过initial capacity和load factor两个参数调整性能。通常缺省的load factor 0.75较好地实现了时间和空间的均衡。增大load factor可以节省空间但相应的查找时间将增大,这会影响像get和put这样的操作。
使用Hashtable的简单示例如下,将1,2,3放到Hashtable中,他们的key分别是”one”,”two”,”three”:
Hashtable numbers = new Hashtable();
numbers.put(“one”, new Integer(1));
numbers.put(“two”, new Integer(2));
numbers.put(“three”, new Integer(3));
要取出一个数,比如2,用相应的key:
Integer n = (Integer)numbers.get(“two”);
System.out.println(“two = ” + n);
由于作为key的对象将通过计算其散列函数来确定与之对应的value的位置,因此任何作为key的对象都必须实现hashCode和equals方法。hashCode和equals方法继承自根类Object,如果你用自定义的类当作key的话,要相当小心,按照散列函数的定义,如果两个对象相同,即obj1.equals(obj2)=true,则它们的hashCode必须相同,但如果两个对象不同,则它们的hashCode不一定不同,如果两个不同对象的hashCode相同,这种现象称为冲突,冲突会导致操作哈希表的时间开销增大,所以尽量定义好的hashCode()方法,能加快哈希表的操作。
如果相同的对象有不同的hashCode,对哈希表的操作会出现意想不到的结果(期待的get方法返回null),要避免这种问题,只需要牢记一条:要同时复写equals方法和hashCode方法,而不要只写其中一个。
Hashtable是同步的。
HashMap类
HashMap和Hashtable类似,不同之处在于HashMap是非同步的,并且允许null,即null value和null key。,但是将HashMap视为Collection时(values()方法可返回Collection),其迭代子操作时间开销和HashMap 的容量成比例。因此,如果迭代操作的性能相当重要的话,不要将HashMap的初始化容量设得过高,或者load factor过低。
WeakHashMap类
WeakHashMap是一种改进的HashMap,它对key实行“弱引用”,如果一个key不再被外部所引用,那么该key可以被GC回收。
总结
如果涉及到堆栈,队列等操作,应该考虑用List,对于需要快速插入,删除元素,应该使用LinkedList,如果需要快速随机访问元素,应该使用ArrayList。
如果程序在单线程环境中,或者访问仅仅在一个线程中进行,考虑非同步的类,其效率较高,如果多个线程可能同时操作一个类,应该使用同步的类。
要特别注意对哈希表的操作,作为key的对象要正确复写equals和hashCode方法。
尽量返回接口而非实际的类型,如返回List而非ArrayList,这样如果以后需要将ArrayList换成LinkedList时,客户端代码不用改变。这就是针对抽象编程。
http://taoliyi.maifou.net/
http://www.kulego.com/shopex/
http://club.joyes.com/assort-2.html
摘要: 读书笔记——《Ant – The Definitive Guide,2nd Edition》
选择自 hopson 的 Blog
关键字
...
阅读全文
作者:江南白衣
这篇文档是专门写给那些编程狂热者,在Ant里编程时要留意的重要Task。
不知为何,老外的各种脚本都写得格外漂亮。从Appfuse里学到很多,在编写SpringSide2.0的构件安装脚本时又被迫自学了不少,这里作下总结。
如果只说一样最重要的事情,就是ant-contrib的<if> 和 <for>节点,使Ant 拥有了完整的编程能力。
1. 变量
Ant里的变量有个诡异的特性----一旦被赋值就不会改变,这个特性有时候帮助很大,有时候让人很苦恼,一定要注意。另一样要注意的是,Ant里的变量和其他语言的变量一样,有可效范围。
1.由命令行赋值
ant build.xml -Dtomcat.home=foo
2.与用户交互输入--Input task
<input message="请选择一个Target "
validargs="compile,jar,test"
addproperty="my.input"/>
3.从propertis文件读取并存盘 --
propertyfile task
<propertyfile file="my.properties">
<entry key="springside.home" default="."/>
</propertyfile>
如果my.properties 不存在,生成my.properties文件,springside.home=.。有一个特别有用的地方:有些properties文件的属性每个开发者都不同,不想放入svn,但又想初始化数值,可以用该命令。
<propertyfile file="my.properties">
<entry key="springside.home" value="....."/>
</propertyfile>
重新写入配置文件。
2. 流程控制
如果没有ant-contrib 贡献的<if> 和<for>节点,Ant的可编程性是极低极低的。
2.1 if task
ant原来可以在target级进行if判断(unless,if 属性),但实在太不方便了。
2.2 Conditions
但Ant预先封装的一堆condition很是很方便的。这些condition完全从实际出发,包括文件是否存在,http://localhost:8080是否连通都可以作为条件,见Ant的参考手册。
2.3 For task
支持"a,b,c,d" 字符串数组的循环与文件目录,Fileset的循环。
2.4 Parallel task
Parallel非常有用,比如我想一边开tomcat,一边做别的,就需要使用它,否则就只有用spawn=true属性把tomcat放在后台运行。spawn有很多不好的地方,比如不能即时在console看到信息,停止ant运行不能把tomcat关掉等。
Parallel相当于一个容器,放在里面的每个task都会被并行执行。如果想把某几个task顺序执行,用相当于()的Sequential task 包起来。
2.5 Waitfor task
暂停ant执行直到条件符合,比如<waitfor><http url=http://localhost:8080/></waitfor>就会等待tomcat启动后才会继续往下执行。Macrodef task
3. 代码封装
ant 代码最基本的封装是
1. ant task:调用其他脚本的任务,可设定dir 与是否继承本脚本的变量。
2. antcall task:调用本脚本内其他task,可设置参数。
3. import task :就像其他语言的include一样,引入其他脚本内容到本脚本里。
1. AntFetch, AntCallBack task
ant-contrib贡献,对应于Ant 与 AntCall。原版只能向被调用函数传递变量,函数执行后没办法return 值。antcallback的语法如下
<antcallback target="mytarget" return="myresult1,myresult2"/>
2. Macrodef task
作为最小的封装单位,与以<target>封装再<antcall target="xxx">调用差不太远,细微之处自行体验了。个人比较喜欢用macrodef。
3. Java task 与 Exec task 直接执行Java类或程序
注意执行目录的定义。另在Windows下如果要直接运行dos窗口中的命令,以下指令启动默认浏览器访问localhost:
<exec executable="cmd.exe">
<arg line="/c start http://localhost:8080"/>
</exec>
4. 扩展Ant的Task
扩展ant task很简单,实现execute() 方法执行task,实现setter接口让ant框架执行属性注入。继承Task 获得一些ant的能力,比如查询某个变量的值。
稍微有点麻烦的是多层嵌套属性的注入。详细请看http://ant.apache.org/manual/developlist.html
SpringSide 2.0 里很简单的实现了一个XML File Merge的task,见XmlMergeTask.java。
蛋蛋 说扩展Ant的最方便的方法还是在ANT里嵌套脚本。导入BSF库以后,你就可以用BSF支持的脚本语言了(见Script Task)。接下来有机会尝试一下。
5. 文件操作
刚好springside里进行了比较多的文件操作,随便记一下。
replace 与 copy 时加入filter, 都可以进行字符串替换.
concat在文件末添加其他文件的内容。
好困,很多东西没写详细,明天再补充。
题外话,Ant
完整演示了如何编写XML式的代码,虽然对于开发人员来说XML编码非常麻烦,远远没有Ruby的rake以ruby代码本身来构建系统清晰,但对于
IDE,特别是希望图形化编程的IDE来说,XML比普通代码要容易渲染得多,所以普元EOS的图形化编程也是序列成XML代码。再另外,Ant的
task 和 普元的构件也有相似。
tomcat5.5.9+sql2000数据库连接池配置的一些心得体会
作者:chiefboy
版权声明:本文可以自由转载,转载时请务必以超链接形式标明文章原始出处和作者信息及本声明
作者:叶枫
原
文:[http://www.matrix.org.cn/resource/article/44/44021_tomcat_sql2000.html]http://www.matrix.org.cn/resource/article/44/44021_tomcat_sql2000.html[/url]
关键字:tomcat sql2000
终于解决了困扰多天的连接池的问题,写下这编文章与大家一起分享。我是在tomcat5.5.9下配置的,tomcat5.5.X和以前的版本有一些差
别,所以配置上也有差别。我就说一下在tomcat5.5.9配置的基本步骤:(确定你以安装好tomcat5.5.9、sql2000)
1、把数据库JDBC驱动拷贝到%TOMCAT_HOME%/common/lib和%TOMCAT_HOME%/webapps/yourweb/WEB-INF/lib下(我的web文件夹名字叫quickstart)
这一步大家都知道,不然tomcat无法与数据库连接。
2、修改%TOMCAT_HOME%/conf/server.xml文件,在 <GlobalNamingResources></GlobalNamingResources>之间
添加以下内容:
<Resource
name="jdbc/quickstart"
type="javax.sql.DataSource"
password="123456"
driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
maxIdle="2"
maxWait="5000"
username="sa"
url="jdbc:microsoft:sqlserver://localhost;DatabaseName=quickstart"
maxActive="4"/>
以上内容根据大家的具体情况进行相应修改,比如:把name="jdbc/quickstart"中的quickstart改成和你web文件夹名称一样,把password="123456"中的“123456”改成你数据库的密码。
3、在%TOMCAT_HOME%/conf/Catalina/localhost下新建一个与你web文件夹同名的xml文件(我的是quickstart.xml)
这一步非常重要,如果没有这步就会出错,会出现
org.apache.tomcat.dbcp.dbcp.SQLNestedException: Cannot create JDBC driver of class '' for connect URL 'null'
这样的错误,在文件中加入第2步的内容,如下:
<?xml version="1.0" encoding="UTF-8"?>
<Context>
<Resource
name="jdbc/quickstart"
type="javax.sql.DataSource"
password="123456"
driverClassName="com.microsoft.jdbc.sqlserver.SQLServerDriver"
maxIdle="2"
maxWait="5000"
username="sa"
url="jdbc:microsoft:sqlserver://localhost;DatabaseName=quickstart"
maxActive="4"/>
</Context>
根据个人具体情况进行相应修改。
4、修改%TOMCAT_HOME%/webapps/yourweb/WEB-INF下的web.xml文件,在<web-app></web-app>之间添加以下内容
<resource-ref>
<description>sqlserverDB Connection</description>
<res-ref-name>jdbc/quickstart</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
把<res-ref-name>jdbc/quickstart</res-ref-name>中的quickstart改成你的web文件夹名称。
5、测试,在quickstart下新建一个index.jsp文件
<%@ page contentType="text/html; charset=gb2312" %>
<%@ page import="javax.naming.*" %>
<%@ page import="javax.sql.*" %>
<%@ page import="java.sql.*" %>
<html>
<head>
<title>JDBC Test</title>
</head>
<body>
<%
Connection conn=null;
Statement stmt=null;
ResultSet rs=null;
ResultSetMetaData md=null;
try
{
Context initCtx=new InitialContext();
DataSource ds=(DataSource)initCtx.lookup("java:comp/env/jdbc/quickstart");
if(ds!=null)
{
out.println("已经获得DataSource");
out.println(ds.toString());
conn=ds.getConnection();
stmt=conn.createStatement();
out.println("aa");
rs=stmt.executeQuery("select * from cat");
md=rs.getMetaData();
out.println("<table border=1>");
out.println("<tr>");
for(int i=0;i<md.getColumnCount();i++)
{
out.println("<td>"+md.getColumnName(i+1)+"</td>");
}
while(rs.next())
{
out.println("<tr>");
out.println("<td>"+rs.getString(1)+"</td>");
out.println("<td>"+rs.getString(2)+"</td>");
out.println("<td>"+rs.getString(3)+"</td>");
out.println("<td>"+rs.getString(4)+"</td>");
out.println("</tr>");
}
out.println("</table>");
conn.close();
}
}
catch(Exception e)
{
out.println(e.toString());
System.out.println(e.toString());
}
%>
</body>
</html>
Tomcat5.x和Hibernate数据库连接池配置方法
首先确保你的TOMCAT HIBERNATE SQLSERVER环境运转正常。
接着我们到TOMCAT安装目录找到/Conf/server.xml文件在你的标签内部加入下面的红色部分代码
代码内容
<Context path="" docBase="" debug="0" >
<WatchedResource>WEB-INF/web.xml</WatchedResource>
<Resource name="JNDI/gamvan" auth="Container"
type="javax.sql.DataSource" driverClassName="net.sourceforge.jtds.jdbc.Driver"
url="jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=GVclub_gamvan"
username="sa" password="123" maxActive="100" maxIdle="10"
maxWait="-1"/>
</Context>
其中net.sourceforge.jtds.jdbc.Driver应该是你的数据库驱动类;jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=GVclub_gamvan 应该是你的数据库连接地址;
JNDI/gamvan 连接池名字
username="sa" password="123" 你的数据库登陆ID和密码
然后到你的网站根目录/WEB-INF/ 打开web.xml 在web-app标签内部加上如下代码
代码内容
<resource-ref>
<description>Oracle Datasource example</description>
<res-ref-name>JNDI/gamvan</res-ref-name>
<res-type>javax.sql.DataSource</res-type>
<res-auth>Container</res-auth>
</resource-ref>
TOMCAT部分我们配置完毕,记下来配置hibernate的配置文件hibernate.cfg.xml
代码内容
<!-- Datasource Start -->
<property name="connection.datasource">java:comp/env/JNDI/gamvan</property>
<property name="show_sql">false</property>
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
<!-- Datasource END -->
将原来的数据库连接标签部分注销,比如SQLSERVER2000注销以下部分
代码内容
<property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property>
<property name="dialect">org.hibernate.dialect.SQLServerDialect</property>
<property name="connection.url">
jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=GVclub_gamvan;
</property>
<property name="connection.username">sa</property>
<property name="connection.password">123</property>
接着重起TOMCAT就可以使用连接池了。TOMCAT5.5.9 HIBERNATE3.05版本上测试成功
Tomcat5.x和Hibernate数据库连接池配置方法
来源: 今晚在线
作者:我容易么我
类别: 原创
时间: 2005-11-8
浏览:
首先确保你的TOMCAT HIBERNATE SQLSERVER环境运转正常。
接着我们到TOMCAT安装目录找到/Conf/server.xml文件在你的标签内部加入下面的红色部分代码
代码内容
<Context path="" docBase="" debug="0" > <WatchedResource>WEB-INF/web.xml</WatchedResource> <Resource name="JNDI/gamvan" auth="Container" type="javax.sql.DataSource" driverClassName="net.sourceforge.jtds.jdbc.Driver" url="jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=GVclub_gamvan" username="sa" password="123" maxActive="100" maxIdle="10" maxWait="-1"/> </Context> |
其中net.sourceforge.jtds.jdbc.Driver应该是你的数据库驱动类;jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=GVclub_gamvan 应该是你的数据库连接地址;
JNDI/gamvan 连接池名字
username="sa" password="123" 你的数据库登陆ID和密码
然后到你的网站根目录/WEB-INF/ 打开web.xml 在web-app标签内部加上如下代码
代码内容 <resource-ref> <description>Oracle Datasource example</description> <res-ref-name>JNDI/gamvan</res-ref-name> <res-type>javax.sql.DataSource</res-type> <res-auth>Container</res-auth> </resource-ref> |
TOMCAT部分我们配置完毕,记下来配置hibernate的配置文件hibernate.cfg.xml
代码内容 <!-- Datasource Start --> <property name="connection.datasource">java:comp/env/JNDI/gamvan</property> <property name="show_sql">false</property> <property name="dialect">org.hibernate.dialect.SQLServerDialect</property> <!-- Datasource END --> |
将原来的数据库连接标签部分注销,比如SQLSERVER2000注销以下部分
代码内容 <property name="connection.driver_class">net.sourceforge.jtds.jdbc.Driver</property> <property name="dialect">org.hibernate.dialect.SQLServerDialect</property> <property name="connection.url"> jdbc:jtds:sqlserver://127.0.0.1:1433;DatabaseName=GVclub_gamvan; </property> <property name="connection.username">sa</property> <property name="connection.password">123</property> |
接着重起TOMCAT就可以使用连接池了。TOMCAT5.5.9 HIBERNATE3.05版本上测试成功。
如有什么疑问可以到 http://club.GamVan.com 技术讨论区内提出,大家共同解决!