??xml version="1.0" encoding="utf-8" standalone="yes"?> 目前支持的类型有Q?
M提供两类功能Q?
1. 字W串转换为指定类型;
2. 注册、注销和查询类型{换器Q?/font> Q意的实例转变?font face='"Times' New Roman">StringQ用法非常简单。在试的过E中Q感觉与调用实例上的toString()Ҏ的效果一P不知道是不是在这个方法内仅仅是调用了传入实例?font face='"Times' New Roman">toString()Ҏ?/font> ps:需要读源代码才能清楚?/font> 字W串value转换?font face='"Times' New Roman">clazz的一个实例;如果p|的话Q就?font face='"Times' New Roman">String的Ş式返?font face='"Times' New Roman">value?
q个Ҏ是对前一Ҏ的加强版Q将数组中的每个value都进行{换,最后以Objectq回。(数组也是Object啊)
注销转换器,前者将所有的转换器注销掉,后者只注销对应?font face='"Times' New Roman">clazz的{换器。注销在这里不是彻底删除了Q而是{换器变ؓ默认的{换器Q?font face='"Times' New Roman">apache commons提供的)?/font> 获取指定cdclazz的{换器. 为指定类?font face='"Times' New Roman">clazz注册转换?font face='"Times' New Roman">converter。如?font face='"Times' New Roman">clazz已经存在一个对应的转换器,那么converterQ将覆盖原来的{换器。也是_我们可以?font face='"Times' New Roman">String,Double创徏自定义的cd转换器,q在注册后进行用?/font> ps:apache的类定义明确Q描q非常清楚,所以就不脓Z子了。当然这只是到达可以正常使用的阶D,如果要进行改造或者创qConvertUtilsQ那可能需要更多的旉Q因要去参?font face='"Times' New Roman">ConvertUtilsBeanQ这里就不详qC?br />
]]>
]]>
]]>
]]>
]]>/**
2 * @param input
3 * @return
4 * @throws Exception
5 */
6public static String encryptData(String input) throws Exception {
7
8 SecureRandom sr = new SecureRandom();
9 byte rawKeyData[] = "ABCDEFGH".getBytes();
10 DESKeySpec dks = new DESKeySpec(rawKeyData);
11
12 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
13 SecretKey key = keyFactory.generateSecret(dks);
14
15 Cipher c = Cipher.getInstance("DES");
16 c.init(Cipher.ENCRYPT_MODE, key, sr);
17 byte[] cipherByte = c.doFinal(input.getBytes());
18 String dec = new BASE64Encoder().encode(cipherByte);
19 return dec;
20
21}
22
23/**
24 * @param input
25 * @return
26 * @throws Exception
27 */
28public static String decryptData(String input) throws Exception {
29 byte[] dec = new BASE64Decoder().decodeBuffer(input);
30
31 SecureRandom sr = new SecureRandom();
32 byte rawKeyData[] = "ABCDEFGH".getBytes();
33
34 DESKeySpec dks = new DESKeySpec(rawKeyData);
35
36 SecretKeyFactory keyFactory = SecretKeyFactory.getInstance("DES");
37
38 SecretKey key = keyFactory.generateSecret(dks);
39
40 Cipher c = Cipher.getInstance("DES");
41 c.init(Cipher.DECRYPT_MODE, key, sr);
42 byte[] clearByte = c.doFinal(dec);
43
44 return new String(clearByte);
45
46}
47
注:转自 http://jlusdy.javaeye.com/blog/145803
]]>
]]>
convert(java.lang.Object value)
convert(java.lang.String value, java.lang.Class clazz)
convert(java.lang.String[] values, java.lang.Class clazz)
deregister()?a href_cetemp='http://www.itepub.net/html/kaifajingcui/Java/2006/0514/"file:///F:/software/apache/commons/commons-beanutils-1.7.0/docs/api/org/apache/commons/beanutils/ConvertUtils.html#deregister()"'>deregister(java.lang.Class clazz)
lookup(java.lang.Class clazz)
register(Converter converter, java.lang.Class clazz)
以下Z用convertUtils的一个DATEcd的例子(该例子来源于学堂视屏)
1.定义converter
package com.bjsxt.oa.web;
2
3import java.text.ParseException;
4import java.text.SimpleDateFormat;
5import java.util.Date;
6
7import org.apache.commons.beanutils.Converter;
8
9public class UtilDateConverter implements Converter {
10
11 private static SimpleDateFormat format = new SimpleDateFormat("yyyy-MM-dd");
12
13 public Object convert(Class type, Object value) {
14 if (value == null) {
15 return value;
16 }
17 if (value instanceof Date) {
18 return value;
19 }
20 if (value instanceof String) {
21 try {
22 return format.parse((String)value);
23 } catch (ParseException e) {
24 e.printStackTrace();
25 }
26 }
27 return null;
28 }
29
30}
31
package com.bjsxt.oa.web;
2
3import java.util.Date;
4
5import javax.servlet.ServletException;
6import javax.servlet.http.HttpServlet;
7
8import org.apache.commons.beanutils.ConvertUtils;
9
10public class UtilDateConverterInitServlet extends HttpServlet {
11
12 @Override
13 public void init() throws ServletException {
14 ConvertUtils.register(new UtilDateConverter(), Date.class);
15 }
16
17}
18
<servlet>
2 <servlet-name>utilDateConverter</servlet-name>
3 <servlet-class>com.bjsxt.oa.web.UtilDateConverterInitServlet</servlet-class>
4 <load-on-startup>3</load-on-startup>
5 </servlet>
]]>
BeanUtils提供?Java反射和自省API的包装。其主要目的是利用反机制对JavaBean的属性进行处理。我们知道,一个JavaBean通常包含了大量的属性,?多情况下Q对JavaBean的处理导致大量get/set代码堆积Q增加了代码长度和阅M码的隑ֺ?br />
二、用法:
BeanUtils是这个包里比较常用的一个工LQ这里只介绍它的copyProperties()Ҏ。该Ҏ定义如下Q?br />
public static void copyProperties(java.lang.Object dest,java.lang.Object orig)
throws java.lang.IllegalAccessException,
java.lang.reflect.InvocationTargetException
?果你有两个具有很多相同属性的JavaBeanQ一个很常见的情况就是Struts里的PO对象Q持久对象)和对应的ActionFormQ例?Teacher和TeacherForm。我们一般会在Action里从ActionForm构造一个PO对象Q传l的方式是用类g面的语句对属性?个赋|
//得到TeacherForm
TeacherForm teacherForm=(TeacherForm)form;
//构造Teacher对象
Teacher teacher=new Teacher();
//赋?br />
teacher.setName(teacherForm.getName());
teacher.setAge(teacherForm.getAge());
teacher.setGender(teacherForm.getGender());
teacher.setMajor(teacherForm.getMajor());
teacher.setDepartment(teacherForm.getDepartment());
//持久化Teacher对象到数据库
HibernateDAO=;
HibernateDAO.save(teacher);
而用BeanUtils后,代码大大改观了Q如下所C:
//得到TeacherForm
TeacherForm teacherForm=(TeacherForm)form;
//构造Teacher对象
Teacher teacher=new Teacher();
//赋?br />
BeanUtils.copyProperties(teacher,teacherForm);
//持久化Teacher对象到数据库
HibernateDAO=;
HibernateDAO.save(teacher);
?果Teacher和TeacherForm间存在名UC相同的属性,则BeanUtils不对q些属性进行处理,需要程序员手动处理。例?Teacher包含modifyDateQ该属性记录最后修Ҏ期,不需要用户在界面中输入)属性而TeacherForm无此属性,那么在上面代码的 copyProperties()后还要加上一句:
teacher.setModifyDate(new Date());
?么样Q很方便吧!除BeanUtils外还有一个名为PropertyUtils的工LQ它也提供copyProperties()ҎQ作用与 BeanUtils的同名方法十分相|主要的区别在于后者提供类型{换功能,卛_C个JavaBean的同名属性ؓ不同cdӞ在支持的数据cd范围 内进行{换,而前者不支持q个功能Q但是速度会更快一些。BeanUtils支持的{换类型如下:
* java.lang.BigDecimal
* java.lang.BigInteger
* boolean and java.lang.Boolean
* byte and java.lang.Byte
* char and java.lang.Character
* java.lang.Class
* double and java.lang.Double
* float and java.lang.Float
* int and java.lang.Integer
* long and java.lang.Long
* short and java.lang.Short
* java.lang.String
* java.sql.Date
* java.sql.Time
* java.sql.Timestamp
q里要注意一点,java.util.Date是不被支持的Q而它的子cjava.sql.Date是被支持的。因此如果对象包含时间类型的属性,且希望被转换的时候,一定要使用java.sql.Datecd。否则在转换时会提示argument mistype异常?br />
三、优~点Q?br />
Apache Jakarta Commons目非常有用。我曑֜许多不同的项目上或直接或间接C用各U流行的commonslg。其中的一个强大的lg是BeanUtils。我 说明如何用BeanUtilslocal实体bean转换为对应的value 对象Q?br />
BeanUtils.copyProperties(aValue, aLocal)
?面的代码从aLocal对象复制属性到aValue对象。它相当单!它不localQ或对应的valueQ对象有多少个属性,只管q行复制。我们假?local对象?00个属性。上面的代码使我们可以无需键入臛_100行的冗长、容易出错和反复的get和setҎ调用。这太棒了!太强大了Q太有用 了!
现在Q还有一个坏消息Q用BeanUtils的成本惊人地昂贵Q我做了一个简单的试QBeanUtils所p的时间要过取数 据、将其复制到对应?value对象Q通过手动调用get和setҎQ,以及通过串行化将其返回到q程的客h的时间d。所以要心使用q种威力Q?
该文章的原文地址为:http://lifejava.spaces.live.com/Blog/cns!A666C33543221640!158.entry
]]>
]]>
]]>
思义它是local variableQ线E局部变量)。它的功用非常简单,是为每一个用该变量的线E都提供一个变量值的副本Q是每一个线E都可以独立地改变自q副本Q而不会和其它U程的副本冲H。从U程的角度看Q就好像每一个线E都完全拥有该变量?/p>
使用场景
ThreadLocalc?/strong>
?主要由四个方法组成initialValue()Qget()Qset(T)Qremove()Q其中值得注意的是initialValue()Q该Ҏ 是一个protected的方法,昄是ؓ了子c重写而特意实现的。该Ҏq回当前U程在该U程局部变量的初始|q个Ҏ是一个gq调用方法,在一个线 E第1ơ调用get()或者set(Object)时才执行Qƈ且仅执行1ơ。ThreadLocal中的实实现直接q回一个nullQ?/p>
ThreadLocal的原?/p>
ThreadLocal是如何做Cؓ每一个线E维护变量的副本的呢Q其实实现的思\很简单,在ThreadLocalcM有一个MapQ用于存储每一个线E的变量的副本。比如下面的CZ实现Q?/p>
public class ThreadLocal
{
private Map values = Collections.synchronizedMap(new HashMap());
public Object get()
{
Thread curThread = Thread.currentThread();
Object o = values.get(curThread);
if (o == null && !values.containsKey(curThread))
{
o = initialValue();
values.put(curThread, o);
}
return o;
}
public void set(Object newValue)
{
values.put(Thread.currentThread(), newValue);
}
public Object initialValue()
{
return null;
}
}
ThreadLocal 的?/strong>
使用Ҏ一Q?/p>
Hibernate的文档时看到了关于ThreadLocal理多线E访问的部分。具体代码如?
1. public static final ThreadLocal session = new ThreadLocal();
2. public static Session currentSession() {
3. Session s = (Session)session.get();
4. //open a new session,if this session has none
5. if(s == null){
6. s = sessionFactory.openSession();
7. session.set(s);
8. }
return s;
9. }
我们逐行分析
1?初始化一个ThreadLocal对象QThreadLocal有三个成员方?get()、set()、initialvalue()?
如果不初始化initialvalueQ则initialvalueq回null?
3?session的getҎ当前U程q回其对应的U程内部变量Q也是我们需要的net.sf.hibernate.SessionQ相当于对应每个数据 库连接).多线E情况下׃n数据库链接是不安全的。ThreadLocal保证了每个线E都有自qsQ数据库q接Q?
5。如果是该线E初ơ访问,自然QsQ数据库q接Q会是nullQ接着创徏一个SessionQ具体就是行6?
6。创Z个数据库q接实例 s
7。保存该数据库连接s到ThreadLocal中?
8。如果当前线E已l访问过数据库了Q则从session中get()可以获取该U程上次获取q的q接实例
以上转自 榄?nbsp; http://hi.baidu.com/mojiedao/blog/item/0ceeab99e7a0ad086f068c09.html
2、国际化资源文g是由baseName+localel成Q如QMessageBundle_en_US.properties
baseName是Q意合法的文g?/p>
3、native2ascii命o的位|和用法
* 位置QJAVA_HOME/bin
* 使用native2ascii.exe o.properties MessagesBundle_zh_CN.properties
elements()q回此哈希表中的值的枚D
?code>keys()q回此哈希表中的键的枚D?br />
Vector?code>elements()q回此向量的lg的枚?br />
Properties?a href="mk:@MSITStore:H:\帮助资料\JDK15chs\JDK1.5中文帮助(CHM)\JAVA_API_CN.CHM::/api/java/util/Properties.html#propertyNames()">propertyNames()q回属性列表中所有键的枚举,如果在主属性列表中未找到同名的键,则包括默认属性列表中不同的键?br />
Properties
?code>getPropertyҎ有两个;一个是getProperty(String key)用指定的键在此属性列表中搜烦属?/code>
一个是getProperty(String key, String defaultValue)用指定的键在属性列表中搜烦属性。如果在属性列表中未找到该键,则接着递归查默认属性列表及光认倹{如果未扑ֈ属性,则此Ҏq回默认值变量?br />
ThreadGroup U程l表CZ个线E的集合。此外,U程l也可以包含其他U程l。线E组构成一|Q在树中Q除了初始线E组外,每个U程l都有一个父U程l?
构造方法摘?/strong>
ThreadGroup(String name)
构造一个新U程l?/td>
ThreadGroup(ThreadGroup parent, String name)
创徏一个新U程l?/td>

]]>
Java中的separatorQpathSeparator{常? -
File.separatorChar q回一个字W,表示当前pȝ默认的文件名分隔W,在Windows中ؓ"\",unix中ؓ"/"?br /> File.separator 与前者相同,但将分隔W作为字W串cdq回?br /> pathSeparatorChar q回一个字W,表示当前pȝ默认的\径名分隔W,在Windows中ؓ";",unix中ؓ":"?br /> File.pathSeparator 与前者相同,但将分隔W作为字W串cdq回?/p>
正文为JDKAPI帮助文档相关内容Q?/p>
separatorChar
public static final char separatorCharThe system-dependent default name-separator character. This field is initialized to contain the first character of the value of the system property file.separator. On UNIX systems the value of this field is '/'; on Microsoft Windows systems it is '\'.
See Also:
System.getProperty(java.lang.String)
--------------------------------------------------------------------------------
separator
public static final String separatorThe system-dependent default name-separator character, represented as a string for convenience. This string contains a single character, namely separatorChar.
--------------------------------------------------------------------------------
pathSeparatorChar
public static final char pathSeparatorCharThe system-dependent path-separator character. This field is initialized to contain the first character of the value of the system property path.separator. This character is used to separate filenames in a sequence of files given as a path list. On UNIX systems, this character is ':'; on Microsoft Windows systems it is ';'.
See Also:
System.getProperty(java.lang.String)
--------------------------------------------------------------------------------
pathSeparator
public static final String pathSeparatorThe system-dependent path-separator character, represented as a string for convenience. This string contains a single character, namely pathSeparatorChar.
1.可以在windows 更改pȝ环境变量
加上JAVA_OPTS=-Xms64m -Xmx512m
2,如果用的tomcat,在windows?可以?/strong>
C:\tomcat5.5.9\bin\catalina.bat 中加?
set JAVA_OPTS=-Xms64m -Xmx256m
位置? rem Guess CATALINA_HOME if not defined q行的下面加合?
3.如果是linuxpȝ
Linux 在{tomcat_home}/bin/catalina.sh的前面,?
set JAVA_OPTS='-Xms64 -Xmx512'
使用JavaE序从数据库中查询大量的数据时出现异?java.lang.OutOfMemoryError: Java heap space 在JVM中如?8Q的旉是用于GC且可用的 Heap size 不2Q的时候将抛出此异怿息?JVM堆的讄是指javaE序q行q程中JVM可以调配使用的内存空间的讄.JVM在启动的时候会自动讄Heap size的|其初始空??Xms)是物理内存的1/64Q最大空?-Xmx)是物理内存的1/4。可以利用JVM提供?Xmn -Xms -Xmx{选项可进行设|。例如:java -jar -Xmn16m -Xms64m -Xmx128m MyApp.jar如果Heap Size讄偏小Q除了这些异怿息外Q还会发现程序的响应速度变慢了。GC占用了更多的旉Q而应用分配到的执行时间较。Heap Size 最大不要超q可用物理内存的80Q,一般的要将-Xms?Xmx选项讄为相同,?Xmn?/4?Xmx倹{Heap size?-Xms -Xmn 讄不要出物理内存的大。否则会提示“Error occurred during
在用Java的时候,我们都会遇到使用集合QCollectionQ的时候,但是Java API提供了多U集合的实现Q我在用和面试的时候频 频遇到这L“抉择” ?:Q(主要q是面试的时候) 久而久之,也就有了一点点的心得体会,写出来以供大家讨??/p> ȝ说来QJava API中所用的集合c,都是实现了Collection接口Q他的一个类l承l构如下Q?/p> Collection<--List<--Vector Collection<--List<--ArrayList Collection<--List<--LinkedList Collection<--Set<--HashSet Collection<--Set<--HashSet<--LinkedHashSet Collection<--Set<--SortedSet<--TreeSet Vector : ZArray的ListQ其实就是封装了Array所不具备的一些功能方便我们用,它不可能走入Array的限制。性能也就不可?/p> 越Array。所以,在可能的情况下,我们要多q用Array。另外很重要的一点就是Vector“sychronized”的,q个也是Vector?/p> ArrayList的唯一的区别?/p> ArrayListQ同Vector一h一个基于Array上的链表Q但是不同的是ArrayList不是同步的。所以在性能上要比Vector优越一些,?/p> 是当q行到多U程环境中时Q可需要自己在理U程的同步问题?/p> LinkedListQLinkedList不同于前面两UListQ它不是ZArray的,所以不受Array性能的限制。它每一个节点(NodeQ都包含两方 面的内容Q?.节点本n的数据(dataQ;2.下一个节点的信息QnextNodeQ。所以当对LinkedList做添加,删除动作的时候就不用?/p> ZArray的List一P必须q行大量的数据移动。只要更改nextNode的相关信息就可以实现了。这是LinkedList的优ѝ?/p> ListȝQ?/p> 1. 所有的List中只能容U_个不同类型的对象l成的表Q而不是KeyQValue键值对。例如:[ tom,1,c ]Q?/p> 2. 所有的List中可以有相同的元素,例如Vector中可以有 [ tom,koo,too,koo ]Q?/p> 3. 所有的List中可以有null元素Q例如[ tom,null,1 ]Q?/p> 4. ZArray的ListQVectorQArrayListQ适合查询Q而LinkedListQ链表)适合dQ删除操作?/p> HashSetQ虽然Set同List都实CCollection接口Q但是他们的实现方式却大不一栗List基本上都是以Array为基。但是Set则是 在HashMap的基上来实现的,q个是Set和List的根本区别。HashSet的存储方式是把HashMap中的Key作ؓSet的对应存储项。看?/p> HashSet的addQObject objQ方法的实现可以一目了然了?/p> public boolean add(Object obj) { return map.put(obj, PRESENT) == null; } q个也是Z么在Set中不能像在List中一h重复的项的根本原因,因ؓHashMap的key是不能有重复的?/p> LinkedHashSetQHashSet的一个子c,一个链表?/p> TreeSetQSortedSet的子c,它不同于HashSet的根本就是TreeSet是有序的。它是通过SortedMap来实现的?/p> SetȝQ?/p> 1. Set实现的基是MapQHashMapQ; 2. Set中的元素是不能重复的Q如果用add(Object obj)Ҏd已经存在的对象,则会覆盖前面的对?/p> Z么要使用集合c?/p> 当你事先不知道要存放数据的个敎ͼ或者你需要一U比数组下标存取机制更灵zȝҎӞ你就需要用到集合类?/p> 理解集合c?/p> 集合cd放于java.util包中?/p> 集合cd攄都是对象的引用,而非对象本nQ出于表达上的便利,我们U集合中的对象就是指集合中对象的引用Qreference)?/p> 集合cd主要?U:set(集)、list(列表Q和map(映射)?/p> (1)?/p> 集(setQ是最单的一U集合,它的对象不按特定方式排序Q只是简单的把对象加入集合中Q就像往口袋里放东西?/p> 寚w中成员的讉K和操作是通过集中对象的引用进行的Q所以集中不能有重复对象?/p> 集也有多U变体,可以实现排序{功能,如TreeSetQ它把对象添加到集中的操作将变ؓ按照某种比较规则其插入到有序的对象?/p> 列中。它实现的是SortedSet接口Q也是加入了对象比较的Ҏ。通过寚w中的对象q代Q我们可以得C个升序的对象集合?/p> (2)列表 列表的主要特征是其对象以U性方式存储,没有特定序Q只有一个开头和一个结,当然Q它与根本没有顺序的集是不同的?/p> 列表在数据结构中分别表现为:数组和向量、链表、堆栈、队列?/p> 关于实现列表的集合类Q是我们日常工作中经常用到的Q将在后边的W记详细介绍?/p> (3)映射 映射与集或列表有明显区别Q映中每个w是成对的。映中存储的每个对象都有一个相关的关键字(KeyQ对象,关键字决定了 对象在映中的存储位|,索对象时必须提供相应的关键字Q就像在字典中查单词一栗关键字应该是唯一的?/p> 关键字本wƈ不能军_对象的存储位|,它需要对q一U散?hashing)技术来处理Q生一个被UC散列?hash code)的整数| 散列码通常用作一个偏|量Q该偏置量是相对于分配给映射的内存区域v始位|的Q由此确定关键字/对象对的存储位置。理x?/p> 下,散列处理应该产生l定范围内均匀分布的|而且每个关键字应得到不同的散列码?/p> 集合cȝ?/p> java.util中共?3个类可用于管理集合对象,它们支持集、列表或映射{集合,以下是这些类的简单介l?/p> 集: HashSetQ?使用HashMap的一个集的实现。虽焉定义成无序,但必d在某U方法能相当高效地找C个对象。用一个HashMap?/p> 象实现集的存储和索操作是在固定时间内实现? TreeSetQ?在集中以升序对对象排序的集的实现。这意味着从一个TreeSet对象获得W一个P代器按升序提供对象。TreeSetcM?/p> 了一个TreeMap. 列表Q?/p> VectorQ?实现一个类似数l一L表,自动增加定w来容U你所需的元素。用下标存储和索对象就象在一个标准的数组中一?/p> 。你也可以用一个P代器从一个Vector中检索对象。Vector是唯一的同步容器类??当两个或多个U程同时讉K时也是性能良好的?/p> Stsck: q个cMVectorz而来Qƈ且增加了Ҏ实现??一U后q先出的存储l构?/p> LinkedList: 实现一个链表。由q个cd义的链表也可以像栈或队列一栯使用?/p> ArrayList: 实现一个数l,它的规模可变q且能像链表一栯讉K。它提供的功能类似VectorcM不同步?/p> 映射Q?/p> HashTableQ?实现一个映象,所有的键必非I。ؓ了能高效的工作,定义键的cdd现hashcode()Ҏ和equal()Ҏ。这个类 是前面java实现的一个承,q且通常能在实现映象的其他类中更好的使用?/p> HashMapQ?实现一个映象,允许存储I对象,而且允许键是I(׃键必L唯一的,当然只能有一个)?/p> WeakHashMapQ?实现q样一个映象:通常如果一个键对一个对象而言不再被引用,?对象对将被舍弃。这与HashMap形成对照Q映?/p> 中的键维持键/对象对的生命周期Q尽用映象的E序不再有对键的引用Qƈ且因此不能检索对象?/p> TreeMapQ?实现q样一个映象,对象是按键升序排列的?/p> Set和List都是由公共接口Collection扩展而来Q所以它们都可以使用一个类型ؓCollection的变量来引用。这意味着M列表?/p> 集构成的集合都可以用q种方式引用Q只有映类除外Q但也不是完全排除在外,因ؓ可以从映获得一个列表。)所以说Q把一?/p> 列表或集传递给Ҏ的标准途径是用Collectioncd的参数?/p> Vector q是ArrayListQ哪一个更好,Z么? 要回{这个问题不能一概而论Q有时候用Vector比较好;有时是ArrayListQ有时候这两个都不是最好的选择。你别指望能够获?/p> 一个简单肯定答案,因ؓq要看你用它们干什么。下面有4个要考虑的因素: (1)API (2)同步处理 (3)数据增长?/p> (4)使用模式 下面针对q?个方面进行一一探讨 API 在由Ken Arnold{编著的《Java Programming Language?Addison-Wesley, June 2000)一书中有这L描述QVectorcM?/p> ArrayList.。所有从API的角度来看这两个c非常相伹{但他们之间也还是有一些主要的区别的?/p> 同步?/p> Vector是同步的。这个类中的一些方法保证了Vector中的对象是线E安全的。而ArrayList则是异步的,因此ArrayList中的对象q不 是线E安全的。因为同步的要求会媄响执行的效率Q所以如果你不需要线E安全的集合那么使用ArrayList是一个很好的选择Q这?/p> 可以避免׃同步带来的不必要的性能开销?/p> 数据增长 从内部实现机制来讲ArrayList和Vector都是使用数组(Array)来控刉合中的对象。当你向q两U类型中增加元素的时候,如果元素 的数目超Z内部数组目前的长度它们都需要扩展内部数l的长度QVector~省情况下自动增长原来一倍的数组长度QArrayList?/p> 原来?0%,所以最后你获得的这个集合所占的I间L比你实际需要的要大。所以如果你要在集合中保存大量的数据那么使用Vector 有一些优势,因ؓ你可以通过讄集合的初始化大小来避免不必要的资源开销?/p> 使用模式 在ArrayList和Vector中,从一个指定的位置Q通过索引Q查找数据或是在集合的末֢加、移除一个元素所p的时间是一LQ?/p> q个旉我们用O(1)表示。但是,如果在集合的其他位置增加或移除元素那么花费的旉会呈UŞ增长QO(n-i)Q其中n代表集合?/p> 元素的个敎ͼi代表元素增加或移除元素的索引位置。ؓ什么会q样呢?以ؓ在进行上q操作的时候集合中Wi和第i个元素之后的所 有元素都要执行位Uȝ操作。这一切意味着什么呢Q?/p> q意味着Q你只是查找特定位置的元素或只在集合的末端增加、移除元素,那么使用Vector或ArrayList都可以。如果是其他操作Q?/p> 你最好选择其他的集合操作类。比如,LinkList集合cd增加或移除集合中M位置的元素所p的时间都是一L—O(1)Q但它在 索引一个元素的使用~比较慢QO(i),其中i是烦引的位置.使用ArrayList也很ҎQ因Z可以单的使用索引来代替创建iterator 对象的操作。LinkList也会为每个插入的元素创徏对象Q所有你要明白它也会带来额外的开销?/p> 最后,在《Practical Java》一书中Peter Haggar使用一个简单的数组QArrayQ来代替Vector或ArrayList。尤其是对于执行?/p> 率要求高的程序更应如此。因Z用数l?Array)避免了同步、额外的Ҏ调用和不必要的重新分配空间的操作?T007)
|
首先建立一个FileAction
package com.action;
import org.apache.struts.action.*;
import javax.servlet.http.*;
import com.actionForm.FileActionForm;
import org.apache.struts.actions.DispatchAction;
import java.util.Date;
import java.text.*;
import org.apache.struts.upload.FormFile;
import java.io.*;
import java.net.URLEncoder;
import com.dao.*;
public class FileAction extends DispatchAction {
private JDBConnection connection =new JDBConnection();
//以下Ҏ实现文g的上?/span>
public ActionForward upLoadFile(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws
Exception {
ActionForward forward=null;
Date date = new Date();
FileActionForm fileActionForm = (FileActionForm) form;
//FormFile用于指定存取文g的类?br />
FormFile file = fileActionForm.getFile(); //获取当前的文?/span>
// 获得pȝ的绝对\?/span> String dir = servlet.getServletContext().getRealPath("/image");
//我上传的文g没有攑֜服务器上。而是存在D:D:\\loadfile\\temp\\
String dir="D:\\loadfile\\temp\\";
int i = 0;
String type = file.getFileName();
while(i!=-1){
//扑ֈ上传文g的类型的位置Q这个地方的?.'
i = type.indexOf(".");
/* System.out.println(i);*/
/*截取上传文g的后~?此时得到了文件的cd*/
type = type.substring(i+1);
}
// 限制上传cd为jpg,txt,rar;
if (!type.equals("jpg") && !type.equals("txt")&& !type.equals("bmp"))
{//当上传的cd不ؓ上述cdӞ跌{到错误页面?/span>
forward=mapping.findForward("error");
}
else
{
// 上传时间加入文件名Q这个地方的是毫U数Q?nbsp;
String times = String.valueOf(date.getTime());
//l合?time.type
String fname = times + "." + type;
//InInputStream是用以从特定的资源读取字节的Ҏ?br />
InputStream streamIn = file.getInputStream(); //创徏d用户上传文g的对?br />
//得到是字节数Q即byte,我们可以直接用file.getFileSize(),也可以在创徏d对象时用streamIn.available();
// int ok=streamIn.available();
int ok=file.getFileSize();
String strFee = null;
//q个地方是处理上传的为M单位计算Ӟ下一个是以kb,在下一个是byte;
if(ok>=1024*1024)
{
float ok1=(((float)ok)/1024f/1024f);
DecimalFormat myformat1 = new DecimalFormat("0.00");
strFee = myformat1.format(ok1)+"M";
System.out.println(strFee+"M");
}
else if(ok>1024 && ok<=1024*1024)
{
double ok2=((double)ok)/1024;
DecimalFormat myformat2=new DecimalFormat("0.00");
strFee = myformat2.format(ok2)+"kb";
System.out.println(strFee+"kb");
}
else if(ok<1024)
{
System.out.println("aaaaaaaaa");
strFee=String.valueOf(ok)+"byte";
System.out.println(strFee);
}
System.out.println( streamIn.available()+"文g大小byte");
//q个是io包下的上传文件类
File uploadFile = new File(dir); //指定上传文g的位|?br />
if (!uploadFile.exists() || uploadFile == null) { //判断指定路径dir是否存在Q不存在则创\?br />
uploadFile.mkdirs();
}
//上传的\?文g?br />
String path = uploadFile.getPath() + "\\" + fname;
//OutputStream用于向某个目标写入字节的抽象c,q个地方写入目标是pathQ通过输出FileOutputStreamd
OutputStream streamOut = new FileOutputStream(path);
int bytesRead = 0;
byte[] buffer = new byte[8192];
//数据读入byte数组的一部分Q其中读入字节数的最大值是8192Q读入的字节存储到Qbuffer[0]到buffer[0+8190-1]的部分中
//streamIn.readҎq回的是实际d字节数目.如果d末尾则返?1.如果bytesReadq回?则表C没有读取Q何字节?br />
while ((bytesRead = streamIn.read(buffer, 0, 8192)) != -1) {
//写入buffer数组的一部分Q从buf[0]开始写入ƈ写入bytesRead个字节,q个writeҎ发生阻塞直臛_节写入完成?br />
streamOut.write(buffer, 0, bytesRead);
}
// 关闭输出输入?销毁File?br />
streamOut.close();
streamIn.close();
file.destroy();
String paths=path;
System.out.println(paths);
String fileName = Chinese.toChinese(fileActionForm.getFileName()); //获取文g的名U?/span>
//String fileSize = String.valueOf(file.getFileSize());
String fileDate = DateFormat.getDateInstance().format(date);
String sql = "insert into tb_file values('" + fileName + "','" +
strFee + "','" + fileDate + "','" + paths + "')";
connection.executeUpdate(sql);
connection.closeConnection();
forward=mapping.findForward("upLoadFileResult");
}
return forward;
}
//实现文g的下?br />
public ActionForward downFile(ActionMapping mapping, ActionForm form,
HttpServletRequest request,
HttpServletResponse response) throws
Exception {
String path = request.getParameter("path");
System.out.println(path+"111");
BufferedInputStream bis = null;
BufferedOutputStream bos = null;
OutputStream fos = null;
InputStream fis = null;
//如果是从服务器上取就用这个获得系l的l对路径Ҏ?nbsp; String filepath = servlet.getServletContext().getRealPath("/" + path);
String filepath=path;
System.out.println("文g路径"+filepath);
File uploadFile = new File(filepath);
fis = new FileInputStream(uploadFile);
bis = new BufferedInputStream(fis);
fos = response.getOutputStream();
bos = new BufferedOutputStream(fos);
//q个就是弹Z载对话框的关键代?/span>
response.setHeader("Content-disposition",
"attachment;filename=" +
URLEncoder.encode(path, "utf-8"));
int bytesRead = 0;
//q个地方的同上传的一栗我׃多说了,都是用输入流q行先读Q然后用输出去写,唯一不同的是我用的是~冲输入输出?br />
byte[] buffer = new byte[8192];
while ((bytesRead = bis.read(buffer, 0, 8192)) != -1) {
bos.write(buffer, 0, bytesRead);
}
bos.flush();
fis.close();
bis.close();
fos.close();
bos.close();
return null;
}
}
FileActionForm
package com.actionForm;
import org.apache.struts.action.*;
import org.apache.struts.upload.*;
public class FileActionForm extends ActionForm {
private String fileName;//上传文g的名U?br />
private String fileSize;//上传文g的大?br />
private String filePath;//上传文g到服务器的\?br />
private String fileDate;//上传文g的日?br />
private FormFile file;//上传文g
public String getFileName() {
return fileName;
}
public FormFile getFile() {
return file;
}
public String getFileSize() {
return fileSize;
}
public String getFilePath() {
return filePath;
}
public String getFileDate() {
return fileDate;
}
public void setFileName(String fileName) {
this.fileName = fileName;
}
public void setFile(FormFile file) {
this.file = file;
}
public void setFileSize(String fileSize) {
this.fileSize = fileSize;
}
public void setFilePath(String filePath) {
this.filePath = filePath;
}
public void setFileDate(String fileDate) {
this.fileDate = fileDate;
}
}
index.jsp 此位|的form是javabeen的对象,q个javabeen中存取的囄的相关信?/span>
<table width="264" height="81" border="0" align="center" cellpadding="0" cellspacing="0">
<tr>
<td width="115" rowspan="4" align="center"><img src="<%=form.getFilePath()%>" width="100" height="100"></td>
<td width="133" align="center">囄名称Q?lt;%=form.getFileName()%></td>
</tr>
<tr align="center">
<td>囄大小Q?lt;%=form.getFileSize()%></td>
</tr>
<tr align="center">
<td>上传日期:<%=form.getFileDate()%></td>
</tr>
<tr>
<td align="center"><a href="fileAction.do?method=downFile&path=<%=form.getFilePath()%>" ><img src="priture/bottond.jpg"></a>
</td>
</tr>
</table>
<html:form action="fileAction.do?method=upLoadFile" enctype="multipart/form-data" onsubmit="return Mycheck()">
<table height="52" border="0" align="center" cellpadding="0" cellspacing="0">
<tr align="center">
<td width="60" height="26">囄名称:</td>
<td width="160"> <html:text property="fileName"/> </td>
<td width="60">囄路径:</td>
<td width="198"> <html:file property="file"/> </td>
</tr>
<tr align="right">
<td height="26" colspan="4"> <html:submit>上传</html:submit> </td>
</tr>
</table>
</html:form>
struts-config.xml
<?xml version="1.0" encoding="UTF-8"?> <struts-config>
<!DOCTYPE struts-config PUBLIC "-//Apache Software Foundation//DTD Struts Configuration 1.2//EN" "
<form-beans>
<form-bean name="fileActionForm" type="com.actionForm.FileActionForm" />
</form-beans>
<action-mappings>
<action name="fileActionForm" parameter="method" path="/fileAction" scope="request" type="com.action.FileAction" validate="true">
<forward name="upLoadFileResult" path="/result.jsp"/>
<forward name="error" path="/fail.jsp"></forward>
</action>
</action-mappings>
<message-resources parameter="ApplicationResources" />
</struts-config>
转自javaEye http://www.javaeye.com/topic/219585
]]>