<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>liulang&#039;s blog &#187; JAVA</title>
	<atom:link href="http://www.liulang.cq.cn/category/java-program/feed" rel="self" type="application/rss+xml" />
	<link>http://www.liulang.cq.cn</link>
	<description>既然选择了远方，便只顾风雨兼程……</description>
	<lastBuildDate>Mon, 05 Dec 2011 15:49:44 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.3.1</generator>
		<item>
		<title>java位操作符小结</title>
		<link>http://www.liulang.cq.cn/20100510/javaweif.html</link>
		<comments>http://www.liulang.cq.cn/20100510/javaweif.html#comments</comments>
		<pubDate>Mon, 10 May 2010 08:39:40 +0000</pubDate>
		<dc:creator>刘 浪</dc:creator>
				<category><![CDATA[JAVA]]></category>

		<guid isPermaLink="false">http://www.liulang.cq.cn/?p=254</guid>
		<description><![CDATA[二进制负数以它正值的补码形式表达 补码：反码+1等于补码 比如：System.out.println(Integer.toBinaryString(-5)); 打印：1111 1111 1111 1111 1111 1111 1111 1011  不用想了肯定是32位 过程是这样的： 一个负数，比如-5，它的二进制在java里面是这样表示 1000 0000 0000 0000 0000 0000 0000 0101 它的正值是： 0000 0000 0000 0000 0000 0000 0000 0101 反码是： 1111 1111 1111 1111 1111 1111 1111 1010 &#8230; <a href="http://www.liulang.cq.cn/20100510/javaweif.html">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div>二进制负数以它正值的补码形式表达</div>
<div id="_mcePaste">补码：反码+1等于补码</div>
<div id="_mcePaste">比如：System.out.println(Integer.toBinaryString(-5));</div>
<div id="_mcePaste">打印：1111 1111 1111 1111 1111 1111 1111 1011  不用想了肯定是32位</div>
<div id="_mcePaste">过程是这样的：<span id="more-254"></span></div>
<div id="_mcePaste">一个负数，比如-5，它的二进制在java里面是这样表示</div>
<div id="_mcePaste">1000 0000 0000 0000 0000 0000 0000 0101</div>
<div id="_mcePaste">它的正值是：</div>
<div id="_mcePaste">0000 0000 0000 0000 0000 0000 0000 0101</div>
<div id="_mcePaste">反码是：</div>
<div id="_mcePaste">1111 1111 1111 1111 1111 1111 1111 1010</div>
<div id="_mcePaste">再加上1是：</div>
<div id="_mcePaste">1111 1111 1111 1111 1111 1111 1111 1011</div>
<div id="_mcePaste">即得到打印的内容</div>
<div id="_mcePaste">java ~ 操作符，对每个二进制位的内容求反，即1变成0，0变成1</div>
<div id="_mcePaste">测试负数：</div>
<div id="_mcePaste">int a = -5;//101;</div>
<div id="_mcePaste">System.out.println(~a);</div>
<div id="_mcePaste">打印：4</div>
<div id="_mcePaste">过程是这样的，首先表示出来这个负数</div>
<div id="_mcePaste">1111 1111 1111 1111 1111 1111 1111 1011（上面已经提到为什么这样表示）</div>
<div id="_mcePaste">各位取反得到</div>
<div id="_mcePaste">0000 0000 0000 0000 0000 0000 0000 0100</div>
<div id="_mcePaste">转为10进制得到4</div>
<div id="_mcePaste">测试正数:</div>
<div id="_mcePaste">int a = 5;//101;</div>
<div id="_mcePaste">System.out.println(~a);</div>
<div id="_mcePaste">打印：-6</div>
<div id="_mcePaste">首先表示出来这个正数：</div>
<div id="_mcePaste">0000 0000 0000 0000 0000 0000 0000 0101</div>
<div id="_mcePaste">各位取反得到：</div>
<div id="_mcePaste">1111 1111 1111 1111 1111 1111 1111 1010</div>
<div id="_mcePaste">这个代表的就是-6了，至于为什么看最上面</div>
<div id="_mcePaste">java &amp; 操作符，对应的二进制位进行与操作，两个都为1才为1，其他情况均为0</div>
<div id="_mcePaste">测试：</div>
<div id="_mcePaste">System.out.println(5&amp;6);</div>
<div id="_mcePaste">打印：4</div>
<div id="_mcePaste">过程：</div>
<div id="_mcePaste">5表示成：0000 0000 0000 0000 0000 0000 0000 0101</div>
<div id="_mcePaste">6表示成：0000 0000 0000 0000 0000 0000 0000 0110</div>
<div id="_mcePaste">进行 &amp; ：0000 0000 0000 0000 0000 0000 0000 0100</div>
<div id="_mcePaste">得到：4</div>
<div id="_mcePaste">java | 操作符，对应的二进制位进行或操作，两个都为0才为0，其他情况均为1</div>
<div id="_mcePaste">测试：</div>
<div id="_mcePaste">System.out.println(5|6);</div>
<div id="_mcePaste">打印：7</div>
<div id="_mcePaste">过程：</div>
<div id="_mcePaste">5表示成：0000 0000 0000 0000 0000 0000 0000 0101</div>
<div id="_mcePaste">6表示成：0000 0000 0000 0000 0000 0000 0000 0110</div>
<div id="_mcePaste">进行 | ：0000 0000 0000 0000 0000 0000 0000 0111</div>
<div id="_mcePaste">得到：7</div>
<div id="_mcePaste">java ^ 操作符 当对应二进制位值相同，该位为0 否则为1</div>
<div id="_mcePaste">测试：</div>
<div id="_mcePaste">System.out.println(5^6);</div>
<div id="_mcePaste">打印：3</div>
<div id="_mcePaste">过程：</div>
<div id="_mcePaste">5表示成：0000 0000 0000 0000 0000 0000 0000 0101</div>
<div id="_mcePaste">6表示成：0000 0000 0000 0000 0000 0000 0000 0110</div>
<div id="_mcePaste">进行 ^ ：0000 0000 0000 0000 0000 0000 0000 0011</div>
<div id="_mcePaste">得到：3</div>
<div id="_mcePaste">java &lt;&lt; 操作符，左边移动，右面填充0</div>
<div id="_mcePaste">测试：</div>
<div id="_mcePaste">System.out.println(5&lt;&lt;1);</div>
<div id="_mcePaste">打印：10</div>
<div id="_mcePaste">5表示成：0000 0000 0000 0000 0000 0000 0000 0101</div>
<div id="_mcePaste">进行 &lt;&lt;1 操作：0000 0000 0000 0000 0000 0000 0000 1010</div>
<div id="_mcePaste">java &gt;&gt; 操作符，左边移动，右面填充0</div>
<div id="_mcePaste">测试：</div>
<div id="_mcePaste">System.out.println(5&gt;&gt;&gt;1);</div>
<div id="_mcePaste">打印：2</div>
<div id="_mcePaste">5表示成：0000 0000 0000 0000 0000 0000 0000 0101</div>
<div id="_mcePaste">进行 &gt;&gt;&gt;1 操作：0000 0000 0000 0000 0000 0000 0000 0010</div>
<div id="_mcePaste">左移动一位相当乘以2 右移动一位相当处以2</div>
]]></content:encoded>
			<wfw:commentRss>http://www.liulang.cq.cn/20100510/javaweif.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Java异常分析</title>
		<link>http://www.liulang.cq.cn/20091110/javaexceptionanalyze.html</link>
		<comments>http://www.liulang.cq.cn/20091110/javaexceptionanalyze.html#comments</comments>
		<pubDate>Tue, 10 Nov 2009 09:33:33 +0000</pubDate>
		<dc:creator>刘 浪</dc:creator>
				<category><![CDATA[JAVA]]></category>

		<guid isPermaLink="false">http://www.liulang.cq.cn/?p=182</guid>
		<description><![CDATA[算术异常类：ArithmeticExecption 空指针异常类：NullPointerException 类型强制转换异常：ClassCastException 数组负下标异常：NegativeArrayException 数组下标越界异常：ArrayIndexOutOfBoundsException 违背安全原则异常：SecturityException 文件已结束异常：EOFException 文件未找到异常：FileNotFoundException 字符串转换为数字异常：NumberFormatException 操作数据库异常：SQLException 输入输出异常：IOException 方法未找到异常：NoSuchMethodException java.lang.AbstractMethodError 抽象方法错误。当应用试图调用抽象方法时抛出。 java.lang.AssertionError 断言错。用来指示一个断言失败的情况。 java.lang.ClassCircularityError 类循环依赖错误。在初始化一个类时，若检测到类之间循环依赖则抛出该异常。 java.lang.ClassFormatError 类格式错误。当Java虚拟机试图从一个文件中读取Java类，而检测到该文件的内容不符合类的有效格式时抛出。 java.lang.Error 错误。是所有错误的基类，用于标识严重的程序运行问题。这些问题通常描述一些不应被应用程序捕获的反常情况。 java.lang.ExceptionInInitializerError 初始化程序错误。当执行一个类的静态初始化程序的过程中，发生了异常时抛出。静态初始化程序是指直接包含于类中的static语句段。 java.lang.IllegalAccessError 违法访问错误。当一个应用试图访问、修改某个类的域（Field）或者调用其方法，但是又违反域或方法的可见性声明，则抛出该异常。 java.lang.IncompatibleClassChangeError 不兼容的类变化错误。当正在执行的方法所依赖的类定义发生了不兼容的改变时，抛出该异常。一般在修改了应用中的某些类的声明定义而没有对整个应用重新编译而直接运行的情况下，容易引发该错误。 java.lang.InstantiationError 实例化错误。当一个应用试图通过Java的new操作符构造一个抽象类或者接口时抛出该异常. java.lang.InternalError 内部错误。用于指示Java虚拟机发生了内部错误。 java.lang.LinkageError 链接错误。该错误及其所有子类指示某个类依赖于另外一些类，在该类编译之后，被依赖的类改变了其类定义而没有重新编译所有的类，进而引发错误的情况。 java.lang.NoClassDefFoundError 未找到类定义错误。当Java虚拟机或者类装载器试图实例化某个类，而找不到该类的定义时抛出该错误。 java.lang.NoSuchFieldError 域不存在错误。当应用试图访问或者修改某类的某个域，而该类的定义中没有该域的定义时抛出该错误。 java.lang.NoSuchMethodError 方法不存在错误。当应用试图调用某类的某个方法，而该类的定义中没有该方法的定义时抛出该错误。 &#8230; <a href="http://www.liulang.cq.cn/20091110/javaexceptionanalyze.html">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>算术异常类：ArithmeticExecption<br />
空指针异常类：NullPointerException<br />
类型强制转换异常：ClassCastException<br />
数组负下标异常：NegativeArrayException<br />
数组下标越界异常：ArrayIndexOutOfBoundsException<br />
违背安全原则异常：SecturityException<br />
文件已结束异常：EOFException<br />
文件未找到异常：FileNotFoundException<br />
字符串转换为数字异常：NumberFormatException</p>
<p><span id="more-182"></span></p>
<p>操作数据库异常：SQLException</p>
<p>输入输出异常：IOException</p>
<p>方法未找到异常：NoSuchMethodException<br />
java.lang.AbstractMethodError<br />
抽象方法错误。当应用试图调用抽象方法时抛出。<br />
java.lang.AssertionError<br />
断言错。用来指示一个断言失败的情况。<br />
java.lang.ClassCircularityError<br />
类循环依赖错误。在初始化一个类时，若检测到类之间循环依赖则抛出该异常。<br />
java.lang.ClassFormatError<br />
类格式错误。当Java虚拟机试图从一个文件中读取Java类，而检测到该文件的内容不符合类的有效格式时抛出。<br />
java.lang.Error<br />
错误。是所有错误的基类，用于标识严重的程序运行问题。这些问题通常描述一些不应被应用程序捕获的反常情况。<br />
java.lang.ExceptionInInitializerError<br />
初始化程序错误。当执行一个类的静态初始化程序的过程中，发生了异常时抛出。静态初始化程序是指直接包含于类中的static语句段。<br />
java.lang.IllegalAccessError<br />
违法访问错误。当一个应用试图访问、修改某个类的域（Field）或者调用其方法，但是又违反域或方法的可见性声明，则抛出该异常。<br />
java.lang.IncompatibleClassChangeError<br />
不兼容的类变化错误。当正在执行的方法所依赖的类定义发生了不兼容的改变时，抛出该异常。一般在修改了应用中的某些类的声明定义而没有对整个应用重新编译而直接运行的情况下，容易引发该错误。<br />
java.lang.InstantiationError<br />
实例化错误。当一个应用试图通过Java的new操作符构造一个抽象类或者接口时抛出该异常.<br />
java.lang.InternalError<br />
内部错误。用于指示Java虚拟机发生了内部错误。<br />
java.lang.LinkageError<br />
链接错误。该错误及其所有子类指示某个类依赖于另外一些类，在该类编译之后，被依赖的类改变了其类定义而没有重新编译所有的类，进而引发错误的情况。<br />
java.lang.NoClassDefFoundError<br />
未找到类定义错误。当Java虚拟机或者类装载器试图实例化某个类，而找不到该类的定义时抛出该错误。<br />
java.lang.NoSuchFieldError<br />
域不存在错误。当应用试图访问或者修改某类的某个域，而该类的定义中没有该域的定义时抛出该错误。<br />
java.lang.NoSuchMethodError<br />
方法不存在错误。当应用试图调用某类的某个方法，而该类的定义中没有该方法的定义时抛出该错误。<br />
java.lang.OutOfMemoryError<br />
内存不足错误。当可用内存不足以让Java虚拟机分配给一个对象时抛出该错误。<br />
java.lang.StackOverflowError<br />
堆栈溢出错误。当一个应用递归调用的层次太深而导致堆栈溢出时抛出该错误。<br />
java.lang.ThreadDeath<br />
线程结束。当调用Thread类的stop方法时抛出该错误，用于指示线程结束。<br />
java.lang.UnknownError<br />
未知错误。用于指示Java虚拟机发生了未知严重错误的情况。<br />
java.lang.UnsatisfiedLinkError<br />
未满足的链接错误。当Java虚拟机未找到某个类的声明为native方法的本机语言定义时抛出。<br />
java.lang.UnsupportedClassVersionError<br />
不支持的类版本错误。当Java虚拟机试图从读取某个类文件，但是发现该文件的主、次版本号不被当前Java虚拟机支持的时候，抛出该错误。<br />
java.lang.VerifyError<br />
验证错误。当验证器检测到某个类文件中存在内部不兼容或者安全问题时抛出该错误。<br />
java.lang.VirtualMachineError<br />
虚拟机错误。用于指示虚拟机被破坏或者继续执行操作所需的资源不足的情况。</p>
<p>java.lang.ArithmeticException<br />
算术条件异常。譬如：整数除零等。<br />
java.lang.ArrayIndexOutOfBoundsException<br />
数组索引越界异常。当对数组的索引值为负数或大于等于数组大小时抛出。<br />
java.lang.ArrayStoreException<br />
数组存储异常。当向数组中存放非数组声明类型对象时抛出。<br />
java.lang.ClassCastException<br />
类造型异常。假设有类A和B（A不是B的父类或子类），O是A的实例，那么当强制将O构造为类B的实例时抛出该异常。该异常经常被称为强制类型转换异常。<br />
java.lang.ClassNotFoundException<br />
找不到类异常。当应用试图根据字符串形式的类名构造类，而在遍历CLASSPAH之后找不到对应名称的class文件时，抛出该异常。<br />
java.lang.CloneNotSupportedException<br />
不支持克隆异常。当没有实现Cloneable接口或者不支持克隆方法时,调用其clone()方法则抛出该异常。<br />
java.lang.EnumConstantNotPresentException<br />
枚举常量不存在异常。当应用试图通过名称和枚举类型访问一个枚举对象，但该枚举对象并不包含常量时，抛出该异常。<br />
java.lang.Exception<br />
根异常。用以描述应用程序希望捕获的情况。<br />
java.lang.IllegalAccessException<br />
违法的访问异常。当应用试图通过反射方式创建某个类的实例、访问该类属性、调用该类方法，而当时又无法访问类的、属性的、方法的或构造方法的定义时抛出该异常。<br />
java.lang.IllegalMonitorStateException<br />
违法的监控状态异常。当某个线程试图等待一个自己并不拥有的对象（O）的监控器或者通知其他线程等待该对象（O）的监控器时，抛出该异常。<br />
java.lang.IllegalStateException<br />
违法的状态异常。当在Java环境和应用尚未处于某个方法的合法调用状态，而调用了该方法时，抛出该异常。<br />
java.lang.IllegalThreadStateException<br />
违法的线程状态异常。当县城尚未处于某个方法的合法调用状态，而调用了该方法时，抛出异常。<br />
java.lang.IndexOutOfBoundsException<br />
索引越界异常。当访问某个序列的索引值小于0或大于等于序列大小时，抛出该异常。<br />
java.lang.InstantiationException<br />
实例化异常。当试图通过newInstance()方法创建某个类的实例，而该类是一个抽象类或接口时，抛出该异常。<br />
java.lang.InterruptedException<br />
被中止异常。当某个线程处于长时间的等待、休眠或其他暂停状态，而此时其他的线程通过Thread的interrupt方法终止该线程时抛出该异常。<br />
java.lang.NegativeArraySizeException<br />
数组大小为负值异常。当使用负数大小值创建数组时抛出该异常。<br />
java.lang.NoSuchFieldException<br />
属性不存在异常。当访问某个类的不存在的属性时抛出该异常。<br />
java.lang.NoSuchMethodException<br />
方法不存在异常。当访问某个类的不存在的方法时抛出该异常。<br />
java.lang.NullPointerException<br />
空指针异常。当应用试图在要求使用对象的地方使用了null时，抛出该异常。譬如：调用null对象的实例方法、访问null对象的属性、计算null对象的长度、使用throw语句抛出null等等。<br />
java.lang.NumberFormatException<br />
数字格式异常。当试图将一个String转换为指定的数字类型，而该字符串确不满足数字类型要求的格式时，抛出该异常。<br />
java.lang.RuntimeException<br />
运行时异常。是所有Java虚拟机正常操作期间可以被抛出的异常的父类。<br />
java.lang.SecurityException<br />
安全异常。由安全管理器抛出，用于指示违反安全情况的异常。<br />
java.lang.StringIndexOutOfBoundsException<br />
字符串索引越界异常。当使用索引值访问某个字符串中的字符，而该索引值小于0或大于等于序列大小时，抛出该异常。<br />
java.lang.TypeNotPresentException<br />
类型不存在异常。当应用试图以某个类型名称的字符串表达方式访问该类型，但是根据给定的名称又找不到该类型是抛出该异常。该异常与ClassNotFoundException的区别在于该异常是unchecked（不被检查）异常，而ClassNotFoundException是checked（被检查）异常。<br />
java.lang.UnsupportedOperationException<br />
不支持的方法异常。指明请求的方法不被支持情况的异常。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liulang.cq.cn/20091110/javaexceptionanalyze.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>JDBC备忘</title>
		<link>http://www.liulang.cq.cn/20090916/jdbcbak.html</link>
		<comments>http://www.liulang.cq.cn/20090916/jdbcbak.html#comments</comments>
		<pubDate>Wed, 16 Sep 2009 13:22:01 +0000</pubDate>
		<dc:creator>刘 浪</dc:creator>
				<category><![CDATA[JAVA]]></category>

		<guid isPermaLink="false">http://www.liulang.cq.cn/?p=150</guid>
		<description><![CDATA[在JavaEE应用中，使用ORM操作数据库虽然简单快捷（参考“高效使用JavaEE ORM”），但是毕竟是对JDBC的封装，很多时候，ORM还是不能满足我们的需求，主要是两个问题： 1. 速度不如JDBC，毕竟是封装JDBC，有额外的开销； 2. ORM提供的xQL很多时候无法满足需求，还需要数据库相关的SQL，这时，必须使用JDBC。 使用JDBC虽然麻烦点，但是，按照软件设计的思想，一步一步封装必要的代码，还是可以做到性能与开发效率并存。 首先，要坚决避免的就是不断重复编写try&#8230; catch&#8230; finally&#8230;。对于查询、更新、插入和删除操作，每一种操作只允许编写一次try&#8230; catch&#8230; finally&#8230;。如何实现？有两个方法。 第一个办法是找一个现成的封装了这些JDBC操作的框架，最好的方案当然就是Spring的JDBC框架了，顺便可以参考JdbcTemplate的源码，以便提升自己的JavaEE功力。 如果不使用Spring，那就采用第二个办法，自己造轮子，封装一个JDBC框架。 很多人反对自己造轮子，原因不外乎费事。不过很多时候，造轮子并不麻烦，而且可以满足特定的需求。今天要造的轮子就是一个封装JDBC的框架：Express-Persist。 Express-Persist是ExpressMe的持久化子项目，目标是封装JDBC并提供简单的数据库操作接口。 为什么不使用Spring JDBC呢？主要原因只有一个：Spring的JDBC目前还是1.4兼容的，不支持1.5的泛型。Express-Persist要提供的接口除了基本的数据库操作外，还要实现： 1. 简单的ORM映射，注意是简单的，没有Hibernate那样完整而强悍，本质上就是把ResultSet的每一条记录变成一个JavaBean，可以参考Spring JDBC的RowMapper，实现非常容易； 2. 充分利用Java 5泛型支持，都是类型安全的参数和返回值，不用做强制转化； 3. 利用Java 5的注解（Annotation）把SQL标记在接口方法上，比如： 1.@Query("select * from User where u.id=:id") 2.public User get(String id); 4. 最后，最重要的，只编写接口，没有实现类！ 没有实现类，那JDBC代码写在哪？当然由Express-Persist框架自动生成了。如何自动生成？运行一个命令自动生成Java类？在“高效使用JavaEE &#8230; <a href="http://www.liulang.cq.cn/20090916/jdbcbak.html">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<div>
<p><span style="font-family: Georgia;"></p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">在JavaEE应用中，使用ORM操作数据库虽然简单快捷（参考“<a style="color: #366799; text-decoration: none;" href="http://www.liaoxuefeng.com/it-b913d28602a04a2880fc61d895791da1-1" target="_blank">高效使用JavaEE ORM</a>”），但是毕竟是对JDBC的封装，很多时候，ORM还是不能满足我们的需求，主要是两个问题：</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">1. 速度不如JDBC，毕竟是封装JDBC，有额外的开销；</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">2. ORM提供的xQL很多时候无法满足需求，还需要数据库相关的SQL，这时，必须使用JDBC。</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;"><span id="more-150"></span></p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">使用JDBC虽然麻烦点，但是，按照软件设计的思想，一步一步封装必要的代码，还是可以做到性能与开发效率并存。</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">首先，要坚决避免的就是不断重复编写try&#8230; catch&#8230; finally&#8230;。对于查询、更新、插入和删除操作，每一种操作只允许编写一次try&#8230; catch&#8230; finally&#8230;。如何实现？有两个方法。</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">第一个办法是找一个现成的封装了这些JDBC操作的框架，最好的方案当然就是Spring的JDBC框架了，顺便可以参考JdbcTemplate的源码，以便提升自己的JavaEE功力。</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">如果不使用Spring，那就采用第二个办法，自己造轮子，封装一个JDBC框架。</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">很多人反对自己造轮子，原因不外乎费事。不过很多时候，造轮子并不麻烦，而且可以满足特定的需求。今天要造的轮子就是一个封装JDBC的框架：<a style="color: #366799; text-decoration: none;" href="http://code.google.com/p/express-me/wiki/ExpressPersist" target="_blank">Express-Persist</a>。</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">Express-Persist是<a style="color: #366799; text-decoration: none;" href="http://express-me.googlecode.com/" target="_blank">ExpressMe</a>的持久化子项目，目标是封装JDBC并提供简单的数据库操作接口。</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">为什么不使用Spring JDBC呢？主要原因只有一个：Spring的JDBC目前还是1.4兼容的，不支持1.5的泛型。Express-Persist要提供的接口除了基本的数据库操作外，还要实现：</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">1. 简单的ORM映射，注意是简单的，没有Hibernate那样完整而强悍，本质上就是把ResultSet的每一条记录变成一个JavaBean，可以参考Spring JDBC的RowMapper，实现非常容易；</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">2. 充分利用Java 5泛型支持，都是类型安全的参数和返回值，不用做强制转化；</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">3. 利用Java 5的注解（Annotation）把SQL标记在接口方法上，比如：</p>
<div id="highlighter_693750">
<div>
<div><code>1.</code><span><span><code>@Query</code><code>(</code><code>"select * from User where u.id=:id"</code><code>)</code></span></span></div>
<div><code>2.</code><span><span><code>public</code> <code>User get(String id);</code></span></span></div>
</div>
</div>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">4. 最后，最重要的，只编写接口，没有实现类！</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">没有实现类，那JDBC代码写在哪？当然由Express-Persist框架自动生成了。如何自动生成？运行一个命令自动生成Java类？在“<a style="color: #366799; text-decoration: none;" href="http://www.liaoxuefeng.com/it-b913d28602a04a2880fc61d895791da1-1" target="_blank">高效使用JavaEE ORM</a>”一文中我们已经对JDO的这种静态增强方式表示了强烈的鄙视和唾弃，因此绝不可重蹈覆辙。Express-Persist会在启动时根据接口动态创建出类，不过我们不采用Hibernate使用的CGLIB库，而是直接通过JDK的动态代理功能实现动态类。</p>
<h3 style="color: red;">如何绑定SQL参数</h3>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">DAO接口的方法参数要自动绑定到SQL参数中，由于方法参数的顺序与SQL参数的顺序可能不一致，因此，只能使用命名参数来绑定，即：SQL参数定义为:xxx，对应的方法参数用@Param(“xxx”)标记。</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">当SQL参数很多的时候（尤其是INSERT语句），方法参数也非常多，调用起来非常不方便，比如：</p>
<div id="highlighter_164145">
<div>
<div><code>1.</code><span><span><code>@Update</code><code>(</code><code>"insert into User values(:id, :email, :password, :name)"</code><code>)</code></span></span></div>
<div><code>2.</code><span><span><code>public</code> <code>int</code> <code>create(</code><code>@Param</code><code>(</code><code>"id"</code><code>) String id, </code><code>@Param</code><code>(</code><code>"email"</code><code>) String email,</code><code>@Param</code><code>(</code><code>"password"</code><code>) String password, </code><code>@Param</code><code>(</code><code>"name"</code><code>) String name);</code></span></span></div>
</div>
</div>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">而且都是String类型，调用起来容易出错。</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">因此，Express-Persist允许使用JavaBean绑定，把上述代码变为：</p>
<div id="highlighter_339653">
<div>
<div><code>1.</code><span><span><code>@Update</code><code>(</code><code>"insert into User values(:u.id, :u.email, :u.password, :u.name)"</code><code>)</code></span></span></div>
<div><code>2.</code><span><span><code>public</code> <code>int</code> <code>create(</code><code>@Param</code><code>(</code><code>"u"</code><code>) User u);</code></span></span></div>
</div>
</div>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">这样，调用起来只需要传入一个User对象即可，简单且不易出错。</p>
<h3 style="color: red;">如何分页查询</h3>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">绝大多数数据库支持分页 查询，但语法各不相同。如果让开发者自己写分页SQL语句，难度较大，而且不易复用。因此，Express-Persist仿照Hibernate的做 法，为每一种数据库定义一个Dialect，处理分页，这样，无需考虑数据库的特定分页语法，只需额外添加@FirstResult和 @MaxResults这两个注解，以便传入分页参数：</p>
<div id="highlighter_145426">
<div>
<div><code>1.</code><span><span><code>@Query</code><code>(</code><code>"select * from User u order by id"</code><code>)</code></span></span></div>
<div><code>2.</code><span><span><code>List&lt;User&gt; queryAll(</code><code>@FirstResult</code> <code>int</code> <code>first, </code><code>@MaxResults</code> <code>int</code> <code>max);</code></span></span></div>
</div>
</div>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">Express-Persist已经内置HSQLDB、MySQL和Oracle的Dialect支持，也可以编写其他数据库的Dialect，只需实现Dialect接口即可。</p>
<h3 style="color: red;">如何把ResultSet映射为Java对象</h3>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">要把ResultSet映射为Java对象，我们采用Spring JDBC使用的RowMapper方案，改进之处在于采用了泛型，并且，提供一个BeanRowMapper，实现ResultSet到JavaBean的转换，因为大部分的转换都是到JavaBean。</p>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">利用Java 5的泛型支持，可以非常容易地生成一个BeanRowMapper，而无需编写任何方法：</p>
<div id="highlighter_640695">
<div>
<div><code>1.</code><span><span><code>public</code> <code>class</code> <code>UserRowMapper </code><code>extends</code> <code>BeanRowMapper&lt;User&gt; {}</code></span></span></div>
</div>
</div>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">@MappedBy用于告诉Express-Persist如何映射ResultSet：</p>
<div id="highlighter_147796">
<div>
<div><code>1.</code><span><span><code>@MappedBy</code><code>(UserRowMapper.</code><code>class</code><code>)</code></span></span></div>
<div><code>2.</code><span><span><code>@Query</code><code>(</code><code>"select * from User u order by id"</code><code>)</code></span></span></div>
<div><code>3.</code><span><span><code>List&lt;User&gt; queryAll(</code><code>@FirstResult</code> <code>int</code> <code>first, </code><code>@MaxResults</code> <code>int</code> <code>max);</code></span></span></div>
</div>
</div>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">如果返回结果仅有一个，例如根据主键查询，则必须加上一个@Unique注解，这样，Express-Persist将自动检查返回的记录数，如果不为1，则抛出异常：</p>
<div id="highlighter_929780">
<div>
<div><code>1.</code><span><span><code>@Unique</code></span></span></div>
<div><code>2.</code><span><span><code>@MappedBy</code><code>(UserRowMapper.</code><code>class</code><code>)</code></span></span></div>
<div><code>3.</code><span><span><code>@Query</code><code>(</code><code>"select * from User u where id=:id"</code><code>)</code></span></span></div>
<div><code>4.</code><span><span><code>User queryById(</code><code>@Param</code><code>(</code><code>"id"</code><code>) String id);</code></span></span></div>
</div>
</div>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">如果返回结果允许多个，则返回值应该定义为泛型List，如List&lt;User&gt;。</p>
<h3 style="color: red;">Batch支持</h3>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">批量插入或修改时，使用和不使用JDBC Batch，其性能将有数量级的差距。Express-Persist提供Batch支持，通过继承BatchSupport接口：</p>
<div id="highlighter_857597">
<div>
<div><code>1.</code><span><span><code>public</code> <code>class</code> <code>UserDao </code><code>extends</code> <code>BatchSupport {</code></span></span></div>
<div><code>2.</code><span><span><code>@Update</code><code>(</code><code>"update User set name=:name where id=:id"</code><code>)</code></span></span></div>
<div><code>3.</code><span><span><code>void</code> <code>updateUserName(</code><code>@Param</code><code>(</code><code>"id"</code><code>) String id, </code><code>@Param</code><code>(</code><code>"name"</code><code>) String name);</code></span></span></div>
<div><code>4.</code><span><span><code>}</code></span></span></div>
</div>
</div>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">Batch操作的代码稍微复杂一点，必须用try&#8230; finally执行，以便正确释放资源：</p>
<div id="highlighter_546237">
<div>
<div><code>01.</code><span><span><code>try</code> <code>{</code></span></span></div>
<div><code>02.</code><span><span><code>dao.prepareBatch();</code></span></span></div>
<div><code>03.</code><span><span><code>// now the batch prepared:</code></span></span></div>
<div><code>04.</code><span><span><code>dao.updateUserName(</code><code>"id-1"</code><code>, </code><code>"change A's name"</code><code>);</code></span></span></div>
<div><code>05.</code><span><span><code>dao.updateUserName(</code><code>"id-2"</code><code>, </code><code>"change B's name"</code><code>);</code></span></span></div>
<div><code>06.</code><span><span><code>dao.updateUserName(</code><code>"id-3"</code><code>, </code><code>"change C's name"</code><code>);</code></span></span></div>
<div><code>07.</code><span><span><code>// execute:</code></span></span></div>
<div><code>08.</code><span><span><code>int</code><code>[] results = dao.executeBatch();</code></span></span></div>
<div><code>09.</code><span><span><code>}</code></span></span></div>
<div><code>10.</code><span><span><code>finally</code> <code>{</code></span></span></div>
<div><code>11.</code><span><span><code>dao.closeBatch();</code></span></span></div>
<div><code>12.</code><span><span><code>}</code></span></span></div>
</div>
</div>
<h3 style="color: red;">事务控制</h3>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">Express-Persist仅支持JDBC事务，因此无法远程传播事务。事务代码通常写在Web应用程序的Filter或Interceptor中，只需编写一次：</p>
<div id="highlighter_778462">
<div>
<div><code>01.</code><span><span><code>TransactionManager txManager = ...;</code></span></span></div>
<div><code>02.</code><span><span><code>Transaction tx = txManager.beginTransaction();</code></span></span></div>
<div><code>03.</code><span><span><code>try</code> <code>{</code></span></span></div>
<div><code>04.</code><span><span><code>// TODO: DAO operations here...</code></span></span></div>
<div><code>05.</code><span><span><code>tx.commit();</code></span></span></div>
<div><code>06.</code><span><span><code>}</code></span></span></div>
<div><code>07.</code><span><span><code>catch</code> <code>(Exception e) {</code></span></span></div>
<div><code>08.</code><span><span><code>tx.rollback();</code></span></span></div>
<div><code>09.</code><span><span><code>}</code></span></span></div>
</div>
</div>
<p style="margin: 8px; line-height: 18px; text-indent: 2em;">如果你想体验一下Express-Persist带来的全新Java持久化方案，可以从<a style="color: #366799; text-decoration: none;" href="http://express-me.googlecode.com/files/express-persist.jar" target="_blank">http://express-me.googlecode.com/files/express-persist.jar</a>下载Jar包（含源代码）。完整的文档请参考<a style="color: #366799; text-decoration: none;" href="http://code.google.com/p/express-me/wiki/ExpressPersist" target="_blank">http://code.google.com/p/express-me/wiki/ExpressPersist</a>。</p>
<p></span></div>
<table cellpadding="0" cellspacing="0" bgcolor="#FFFFFF" style="width:290px;border: 1px solid #E6E6E6;">
<tr>
<td rowspan="2" align="center">
<div style="margin:5px auto; width: 80px;height:80px;"><a target="_blank" href="http://s.click.taobao.com/t_1?i=qvewKb98NWo51Q%3D%3D&#038;p=mm_14126698_0_0&#038;n=12" style="width: 80px; margin:0px;padding:0px;height: 80px; overflow:hidden;"><img style="margin:0px;border:none;" src="http://img08.taobaocdn.com/bao/uploaded/i8/T1VLXkXoumzdQZA_s9_074635.jpg_sum.jpg"></a></div>
<div class="clearing"></div>
</td>
<td colspan="2" ><a target="_blank" href="http://s.click.taobao.com/t_1?i=qvewKb98NWo51Q%3D%3D&#038;p=mm_14126698_0_0&#038;n=12" style="height:40px;width:180px;margin:5px;line-height:20px;color:#0000FF">高仿豪华七件套雷朋\Rayban3025四色蛤蟆镜太阳镜墨镜太阳眼镜</a></td>
</tr>
<tr>
<td nowrap="nowrap" > <span style="font-weight:600;margin:5px;line-height:30px;color:#CC0000;">39.9元</span>&nbsp;</td>
<td nowrap="nowrap" width="100px" ><a target="_blank"href="http://s.click.taobao.com/t_1?i=qvewKb98NWo51Q%3D%3D&#038;p=mm_14126698_0_0&#038;n=12"><img name="" style="margin:0px; pandding:0px;line-height:24px;vertical-align: text-bottom;border:none;" src="http://img.alimama.cn/images/tbk/cps/fgetccode_btn.gif"></a></td>
</tr>
</table>
]]></content:encoded>
			<wfw:commentRss>http://www.liulang.cq.cn/20090916/jdbcbak.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>8个常用正则表达式</title>
		<link>http://www.liulang.cq.cn/20090815/8%e4%b8%aaregex.html</link>
		<comments>http://www.liulang.cq.cn/20090815/8%e4%b8%aaregex.html#comments</comments>
		<pubDate>Sat, 15 Aug 2009 06:50:47 +0000</pubDate>
		<dc:creator>刘 浪</dc:creator>
				<category><![CDATA[JAVA]]></category>

		<guid isPermaLink="false">http://www.liulang.cq.cn/?p=108</guid>
		<description><![CDATA[1.匹配用户名：/^[a-z0-9_-]{3,16}$/ 2.匹配密码：/^[a-z0-9_-]{6,18}$/  3.匹配一个Hex值：/^#?([a-f0-9]{6}&#124;[a-f0-9]{3})$/   4.匹配一个Slug：/^[a-z0-9-]+$/   5.匹配一个Email：/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/   6.匹配一个URL：/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/  7.匹配IP地址：/^(?:(?:25[0-5]&#124;2[0-4][0-9]&#124;[01]?[0-9][0-9]?)\.){3}(?:25[0-5]&#124;2[0-4][0-9]&#124;[01]?[0-9][0-9]?)$/  8.匹配HTML Tag：   1. /^&#60;([a-z]+)([^&#60;]+)*(?:&#62;(.*)&#60;\/\1&#62;&#124;\s+\/&#62;)$/]]></description>
			<content:encoded><![CDATA[<p>1.<strong>匹配用户名</strong>：/^[a-z0-9_-]{3,16}$/</p>
<p><span id="more-108"></span></p>
<p><img title="01" src="http://www.liulang.cq.cn/wp-content/uploads/2009/08/01.jpg" alt="01" width="500" height="350" /></p>
<p>2.<strong>匹配密码</strong>：/^[a-z0-9_-]{6,18}$/ <br />
<img title="01" src="http://www.liulang.cq.cn/wp-content/uploads/2009/08/02.jpg" alt="02" width="500" height="350" /></p>
<p>3.<strong>匹配一个Hex值</strong>：/^#?([a-f0-9]{6}|[a-f0-9]{3})$/  <br />
<img title="01" src="http://www.liulang.cq.cn/wp-content/uploads/2009/08/03.jpg" alt="03" width="500" height="350" /></p>
<p>4.<strong>匹配一个Slug</strong>：/^[a-z0-9-]+$/  <br />
<img title="01" src="http://www.liulang.cq.cn/wp-content/uploads/2009/08/04.jpg" alt="04" width="500" height="350" /></p>
<p>5.<strong>匹配一个Email</strong>：/^([a-z0-9_\.-]+)@([\da-z\.-]+)\.([a-z\.]{2,6})$/  <br />
<img title="01" src="http://www.liulang.cq.cn/wp-content/uploads/2009/08/05.jpg" alt="05" width="500" height="350" /></p>
<p>6.<strong>匹配一个URL</strong>：/^(https?:\/\/)?([\da-z\.-]+)\.([a-z\.]{2,6})([\/\w \.-]*)*\/?$/ <br />
<img title="01" src="http://www.liulang.cq.cn/wp-content/uploads/2009/08/06.jpg" alt="06" width="500" height="350" /></p>
<p>7.<strong>匹配IP地址</strong>：/^(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)$/ <br />
<img title="01" src="http://www.liulang.cq.cn/wp-content/uploads/2009/08/07.jpg" alt="07" width="500" height="350" /><br />
8.<strong>匹配HTML Tag</strong>：   1. /^&lt;([a-z]+)([^&lt;]+)*(?:&gt;(.*)&lt;\/\1&gt;|\s+\/&gt;)$/<br />
<img title="01" src="http://www.liulang.cq.cn/wp-content/uploads/2009/08/08.jpg" alt="08" width="500" height="350" /></p>
]]></content:encoded>
			<wfw:commentRss>http://www.liulang.cq.cn/20090815/8%e4%b8%aaregex.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>junit中的assert方法备忘</title>
		<link>http://www.liulang.cq.cn/20090810/junitassertfun.html</link>
		<comments>http://www.liulang.cq.cn/20090810/junitassertfun.html#comments</comments>
		<pubDate>Mon, 10 Aug 2009 14:38:11 +0000</pubDate>
		<dc:creator>刘 浪</dc:creator>
				<category><![CDATA[JAVA]]></category>

		<guid isPermaLink="false">http://www.liulang.cq.cn/?p=85</guid>
		<description><![CDATA[1.assertTrue/False([String message,]boolean condition);     判断一个条件是true还是false。感觉这个最好用了，不用记下来那么多的方法名。 2.fail([String message,]);     失败，可以有消息，也可以没有消息。 3.assertEquals([String message,]Object expected,Object actual);     判断是否相等，可以指定输出错误信息。     第一个参数是期望值，第二个参数是实际的值。     这个方法对各个变量有多种实现。在JDK1.5中基本一样。     但是需要主意的是float和double最后面多一个delta的值，可能是误差范围，不确定这个    单词什么意思，汗一个。 4.assertNotNull/Null([String message,]Object obj);     判读一个对象是否非空(非空)。 5.assertSame/NotSame([String message,]Object expected,Object actual);     判断两个对象是否指向同一个对象。看内存地址。 7.failNotSame/failNotEquals(String message, Object expected, Object actual)     &#8230; <a href="http://www.liulang.cq.cn/20090810/junitassertfun.html">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>1.assertTrue/False([String message,]boolean condition);<br />
    判断一个条件是true还是false。感觉这个最好用了，不用记下来那么多的方法名。<br />
2.fail([String message,]);<br />
    失败，可以有消息，也可以没有消息。</p>
<p><span id="more-85"></span><br />
3.assertEquals([String message,]Object expected,Object actual);<br />
    判断是否相等，可以指定输出错误信息。<br />
    第一个参数是期望值，第二个参数是实际的值。<br />
    这个方法对各个变量有多种实现。在JDK1.5中基本一样。<br />
    但是需要主意的是float和double最后面多一个delta的值，可能是误差范围，不确定这个    单词什么意思，汗一个。<br />
4.assertNotNull/Null([String message,]Object obj);<br />
    判读一个对象是否非空(非空)。<br />
5.assertSame/NotSame([String message,]Object expected,Object actual);<br />
    判断两个对象是否指向同一个对象。看内存地址。<br />
7.failNotSame/failNotEquals(String message, Object expected, Object actual)<br />
    当不指向同一个内存地址或者不相等的时候，输出错误信息。<br />
    注意信息是必须的，而且这个输出是格式化过的。</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liulang.cq.cn/20090810/junitassertfun.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>java util常用数据类型</title>
		<link>http://www.liulang.cq.cn/20090802/javautildatatype.html</link>
		<comments>http://www.liulang.cq.cn/20090802/javautildatatype.html#comments</comments>
		<pubDate>Sun, 02 Aug 2009 09:28:06 +0000</pubDate>
		<dc:creator>刘 浪</dc:creator>
				<category><![CDATA[JAVA]]></category>

		<guid isPermaLink="false">http://www.liulang.cq.cn/?p=75</guid>
		<description><![CDATA[java.util就相当于c++的STL，是Java的一个非常重要的包，有很多常用的数据类型，不同数据类型有不同的用途，而有些数据类似乎很相似，怎样选择应用，就需要对它们进行辨析。 下面列出了这些数据类型的特点，根据这些特点，就可以有针对性的选用 * 缩进的层次结构，就是implement或extend的层次关系 * 每个接口或类都具备其所有上层接口、类的特性 Collection &#8230;&#8230;..&#124;&#8212;&#8212;&#8211;List &#8230;&#8230;..&#124;&#8230;&#8230;&#8230;.&#124;&#8212;&#8212;&#8212;-ArrayList &#8230;&#8230;..&#124;&#8230;&#8230;&#8230;.&#124;&#8212;&#8212;&#8212;-Vector &#8230;&#8230;..&#124;&#8230;&#8230;&#8230;.&#124;&#8230;&#8230;&#8230;&#8230;.&#124;&#8212;&#8211;Stack &#8230;&#8230;..&#124;&#8230;&#8230;&#8230;.&#124;&#8212;&#8212;&#8212;-LinkedList &#8230;&#8230;..&#124;&#8212;&#8212;&#8211;Set &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.&#124;&#8212;&#8212;&#8212;-HashSet. &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.&#124;&#8230;&#8230;&#8230;&#8230;.&#124;&#8212;&#8211;LinkedHashSet &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.&#124;&#8212;&#8212;&#8212;-SortedSet &#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#124;&#8212;&#8211;TreeSet Iterator &#8230;..&#124;&#8212;&#8212;-ListIterator Map &#8230;..&#124;&#8212;&#8212;Hashtable &#8230;..&#124;&#8230;&#8230;&#8230;.&#124;&#8212;&#8212;Properties &#8230;..&#124;&#8212;&#8212;HashMap &#8230;..&#124;&#8230;&#8230;&#8230;.&#124;&#8212;&#8212;LinkedHashMap &#8230;..&#124;&#8212;&#8212;WeakHashMap &#8230;..&#124;&#8212;&#8212;SortedMap &#8230;&#8230;&#8230;&#8230;&#8230;.&#124;&#8212;&#8212;TreeMap Collection. ●..实现该接口及其子接口的所有类都可应用clone()方法，并是序列化类. &#8230;..List. &#8230;..●..可随机访问包含的元素 &#8230;..●..元素是有序的 &#8230;..●..可在任意位置增、删元素 &#8230;..●..不管访问多少次，元素位置不变 &#8230;..●..允许重复元素 &#8230;..●..用Iterator实现单向遍历，也可用ListIterator实现双向遍历 &#8230;&#8230;&#8230;.ArrayList &#8230;&#8230;&#8230;.●..用数组作为根本的数据结构来实现List &#8230;&#8230;&#8230;.●..元素顺序存储 &#8230;&#8230;&#8230;.●..新增元素改变List大小时，内部会新建一个数组，在将添加元素前将所有数据拷贝到新数组中 &#8230; <a href="http://www.liulang.cq.cn/20090802/javautildatatype.html">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p><span style="color: #003366;">java.util就相当于c++的STL，是Java的一个非常重要的包，有很多常用的数据类型，不同数据类型有不同的用途，而有些数据类似乎很相似，怎样选择应用，就需要对它们进行辨析。<br />
下面列出了这些数据类型的特点，根据这些特点，就可以有针对性的选用<span id="more-75"></span><br />
</span></p>
<p><span style="color: #003366;">* 缩进的层次结构，就是implement或extend的层次关系<br />
* 每个接口或类都具备其所有上层接口、类的特性 </span></p>
<p><span style="color: #003366;">Collection<br />
&#8230;&#8230;..|&#8212;&#8212;&#8211;List<br />
&#8230;&#8230;..|&#8230;&#8230;&#8230;.|&#8212;&#8212;&#8212;-ArrayList<br />
&#8230;&#8230;..|&#8230;&#8230;&#8230;.|&#8212;&#8212;&#8212;-Vector<br />
&#8230;&#8230;..|&#8230;&#8230;&#8230;.|&#8230;&#8230;&#8230;&#8230;.|&#8212;&#8211;Stack<br />
&#8230;&#8230;..|&#8230;&#8230;&#8230;.|&#8212;&#8212;&#8212;-LinkedList<br />
&#8230;&#8230;..|&#8212;&#8212;&#8211;Set<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.|&#8212;&#8212;&#8212;-HashSet.<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.|&#8230;&#8230;&#8230;&#8230;.|&#8212;&#8211;LinkedHashSet<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;.|&#8212;&#8212;&#8212;-SortedSet<br />
&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;&#8230;|&#8212;&#8211;TreeSet </span></p>
<p><span style="color: #003366;">Iterator<br />
&#8230;..|&#8212;&#8212;-ListIterator </span></p>
<p><span style="color: #003366;">Map<br />
&#8230;..|&#8212;&#8212;Hashtable<br />
&#8230;..|&#8230;&#8230;&#8230;.|&#8212;&#8212;Properties<br />
&#8230;..|&#8212;&#8212;HashMap<br />
&#8230;..|&#8230;&#8230;&#8230;.|&#8212;&#8212;LinkedHashMap<br />
&#8230;..|&#8212;&#8212;WeakHashMap<br />
&#8230;..|&#8212;&#8212;SortedMap<br />
&#8230;&#8230;&#8230;&#8230;&#8230;.|&#8212;&#8212;TreeMap </span></p>
<p><span style="color: #003366;">Collection.<br />
●..实现该接口及其子接口的所有类都可应用clone()方法，并是序列化类. </span></p>
<p><span style="color: #003366;">&#8230;..List.<br />
&#8230;..●..可随机访问包含的元素<br />
&#8230;..●..元素是有序的<br />
&#8230;..●..可在任意位置增、删元素<br />
&#8230;..●..不管访问多少次，元素位置不变<br />
&#8230;..●..允许重复元素<br />
&#8230;..●..用Iterator实现单向遍历，也可用ListIterator实现双向遍历 </span></p>
<p><span style="color: #003366;">&#8230;&#8230;&#8230;.ArrayList<br />
&#8230;&#8230;&#8230;.●..用数组作为根本的数据结构来实现List<br />
&#8230;&#8230;&#8230;.●..元素顺序存储<br />
&#8230;&#8230;&#8230;.●..新增元素改变List大小时，内部会新建一个数组，在将添加元素前将所有数据拷贝到新数组中<br />
&#8230;&#8230;&#8230;.●..随机访问很快，删除非头尾元素慢，新增元素慢而且费资源<br />
&#8230;&#8230;&#8230;.●..较适用于无频繁增删的情况<br />
&#8230;&#8230;&#8230;.●..比数组效率低，如果不是需要可变数组，可考虑使用数组<br />
&#8230;&#8230;&#8230;.●..非线程安全<br />
.<br />
&#8230;&#8230;&#8230;.Vector.<br />
&#8230;&#8230;&#8230;.●..另一种ArrayList，具备ArrayList的特性<br />
&#8230;&#8230;&#8230;.●..所有方法都是线程安全的（双刃剑，和ArrayList的主要区别）<br />
&#8230;&#8230;&#8230;.●..比ArrayList效率低 </span></p>
<p><span style="color: #003366;">&#8230;&#8230;&#8230;&#8230;&#8230;Stack<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..LIFO的数据结构 </span></p>
<p><span style="color: #003366;">&#8230;&#8230;&#8230;.LinkedList.<br />
&#8230;&#8230;&#8230;.●..链接对象数据结构（类似链表）<br />
&#8230;&#8230;&#8230;.●..随机访问很慢，增删操作很快，不耗费多余资源<br />
&#8230;&#8230;&#8230;.●..非线程安全 </span></p>
<p><span style="color: #003366;">&#8230;..Set.<br />
&#8230;..●..不允许重复元素，可以有一个空元素<br />
&#8230;..●..不可随机访问包含的元素<br />
&#8230;..●..只能用Iterator实现单向遍历 </span></p>
<p><span style="color: #003366;">&#8230;&#8230;&#8230;.HashSet<br />
&#8230;&#8230;&#8230;.●..用HashMap作为根本数据结构来实现Set<br />
&#8230;&#8230;&#8230;.●..元素是无序的<br />
&#8230;&#8230;&#8230;.●..迭代访问元素的顺序和加入的顺序不同<br />
&#8230;&#8230;&#8230;.●..多次迭代访问，元素的顺序可能不同<br />
&#8230;&#8230;&#8230;.●..非线程安全 </span></p>
<p><span style="color: #003366;">&#8230;&#8230;&#8230;&#8230;&#8230;LinkedHashSet<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..基于HashMap和链表的Set实现<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..迭代访问元素的顺序和加入的顺序相同<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..多次迭代访问，元素的顺序不便<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..因此可说这是一种有序的数据结构<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..性能比HashSet差<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..非线程安全 </span></p>
<p><span style="color: #003366;">&#8230;&#8230;&#8230;.SortedSet<br />
&#8230;&#8230;&#8230;.●..加入SortedSet的所有元素必须实现Comparable接口<br />
&#8230;&#8230;&#8230;.●..元素是有序的 </span></p>
<p><span style="color: #003366;">&#8230;&#8230;&#8230;&#8230;&#8230;TreeSet.<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..基于TreeMap实现的SortedSet<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..排序后按升序排列元素<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..非线程安全 </span></p>
<p><span style="color: #003366;">－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－ </span></p>
<p><span style="color: #003366;">Iterator..<br />
●..对Set、List进行单向遍历的迭代器 </span></p>
<p><span style="color: #003366;">&#8230;&#8230;&#8230;.ListIterator.<br />
&#8230;&#8230;&#8230;.●..对List进行双向遍历的迭代器 </span></p>
<p><span style="color: #003366;">－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－－ </span></p>
<p><span style="color: #003366;">Map<br />
●..键值对，键和值一一对应<br />
●..不允许重复的键. </span></p>
<p><span style="color: #003366;">&#8230;..Hashtable.<br />
&#8230;..●..用作键的对象必须实现了hashcode()、equals()方法，也就是说只有Object及其子类可用作键<br />
&#8230;..●..键、值都不能是空对象<br />
&#8230;..●..多次访问，映射元素的顺序相同<br />
&#8230;..●..线程安全的 </span></p>
<p><span style="color: #003366;">&#8230;&#8230;&#8230;.Properties<br />
&#8230;&#8230;&#8230;.●..键和值都是字符串 </span></p>
<p><span style="color: #003366;">&#8230;..HashMap<br />
&#8230;..●..键和值都可以是空对象<br />
&#8230;..●..不保证映射的顺序<br />
&#8230;..●..多次访问，映射元素的顺序可能不同<br />
&#8230;..●..非线程安全 </span></p>
<p><span style="color: #003366;">&#8230;&#8230;&#8230;&#8230;&#8230;LinkedHashMap<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..多次访问，映射元素的顺序是相同的<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..性能比HashMap差 </span></p>
<p><span style="color: #003366;">&#8230;..WeakHashMap..<br />
&#8230;..●..当某个键不再正常使用时，垃圾收集器会移除它，即便有映射关系存在<br />
&#8230;..●..非线程安全 </span></p>
<p><span style="color: #003366;">&#8230;..SortedMap.<br />
&#8230;..●..键按升序排列<br />
&#8230;..●..所有键都必须实现.Comparable.接口. </span></p>
<p><span style="color: #003366;">&#8230;&#8230;&#8230;&#8230;&#8230;TreeMap.<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..基于红黑树的SortedMap实现<br />
&#8230;&#8230;&#8230;&#8230;&#8230;●..非线程安全 </span></p>
]]></content:encoded>
			<wfw:commentRss>http://www.liulang.cq.cn/20090802/javautildatatype.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Nutch1.0配置笔记</title>
		<link>http://www.liulang.cq.cn/20090714/nutch1-0config.html</link>
		<comments>http://www.liulang.cq.cn/20090714/nutch1-0config.html#comments</comments>
		<pubDate>Tue, 14 Jul 2009 15:33:24 +0000</pubDate>
		<dc:creator>刘 浪</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[搜索引擎]]></category>

		<guid isPermaLink="false">http://www.liulang.cq.cn/?p=12</guid>
		<description><![CDATA[配置软件： 1、 Java jdk-1.6 1.1 下载安装 from: http://www.sun.com 安装目录：C:\Java\jdk1.6.0_03 1.2 修改环境变量 JAVA_HOME=C:\Java\jdk1.6.0_03\bin CLASSPATH＝C:\Java\jdk1.6.0_03\lib\dt.jar；C:\Java\jdk1.6.0_03\lib\tools.jar 1.3 测试 java -version 2、tomcat-6.0 2.1 下载 from: http://tomcat.apache.org/ 2.2 解压到C盘目录并改名 安装目录：C:\tomcat6 2.3 修改配置 conf/server.xml QUOTE:   &#60;!&#8211; Define a non-SSL HTTP/1.1 Connector on port 8080 &#8211;&#62;     &#60;Connector port=”8080&#8243; maxHttpHeaderSize=”8192&#8243;             maxThreads=”150&#8243; minSpareThreads=”25&#8243; maxSpareThreads=”75&#8243;                enableLookups=”false” redirectPort=”8443&#8243; acceptCount=”100&#8243;                c disableUploadTimeout=”true”                URIEncoding=”UTF-8&#8243; useBodyEncodingForURI=”true” /&#62;      默认服务端口为8080，若有冲突（如Apache），则可通过此配置文件更改端口(蓝色)如果配置后nutch出现中文乱码问题，则增加编码配置(红色) 2.4 启动服务 startup 测试：http://localhost:8080/ 3、安装Cygwin from:http://www.cygwin.cn/ 由于运行Nutch自带的脚本命令需要Linux的环境，所以必须首先安装Cygwin来模拟这种环境 4、 nutch-1.0 4.1 下载 http://www.apache.org/dyn/closer.cgi/lucene/nutch/ 4.2  解压后到C盘根目录 C:\nutch-1.0 建 url.txt文件，指定爬取列表 在文件中写入如下内容： 例如：http://cqllang.javaeye.com/blog 4.3  指定爬虫规则 &#8230; <a href="http://www.liulang.cq.cn/20090714/nutch1-0config.html">继续阅读 <span class="meta-nav">&#8594;</span></a>]]></description>
			<content:encoded><![CDATA[<p>配置软件：<br />
1、 Java jdk-1.6</p>
<p>1.1 下载安装</p>
<p>from: <a href="http://www.sun.com/">http://www.sun.com</a></p>
<p>安装目录：C:\Java\jdk1.6.0_03<br />
1.2 修改环境变量<br />
JAVA_HOME=C:\Java\jdk1.6.0_03\bin</p>
<p>CLASSPATH＝C:\Java\jdk1.6.0_03\lib\dt.jar；C:\Java\jdk1.6.0_03\lib\tools.jar<br />
1.3 测试<br />
java -version</p>
<p><img title="更多..." src="http://www.liulang.cq.cn/wp-includes/js/tinymce/plugins/wordpress/img/trans.gif" alt="" /><span id="more-12"></span></p>
<p>2、tomcat-6.0</p>
<p>2.1 下载<br />
from: <a href="http://tomcat.apache.org/">http://tomcat.apache.org/</a></p>
<p>2.2 解压到C盘目录并改名</p>
<p>安装目录：C:\tomcat6</p>
<p>2.3 修改配置<br />
conf/server.xml</p>
<p>QUOTE:</p>
<p>  &lt;!&#8211; Define a non-SSL HTTP/1.1 Connector on port 8080 &#8211;&gt;<br />
    &lt;Connector port=”8080&#8243; maxHttpHeaderSize=”8192&#8243;<br />
            maxThreads=”150&#8243; minSpareThreads=”25&#8243; maxSpareThreads=”75&#8243;<br />
               enableLookups=”false” redirectPort=”8443&#8243; acceptCount=”100&#8243;<br />
               c disableUploadTimeout=”true”<br />
               <span style="color: #ff0000;">URIEncoding=”UTF-8&#8243; useBodyEncodingForURI=”true”</span> /&gt;   </p>
<p> </p>
<p>默认服务端口为8080，若有冲突（如Apache），则可通过此配置文件更改端口(蓝色)如果配置后nutch出现中文乱码问题，则增加编码配置(红色)</p>
<p>2.4 启动服务<br />
startup</p>
<p>测试：<a href="http://localhost:8080/">http://localhost:8080/</a></p>
<p>3、安装Cygwin</p>
<p>from:<a href="http://www.cygwin.cn/">http://www.cygwin.cn/</a></p>
<p>由于运行Nutch自带的脚本命令需要Linux的环境，所以必须首先安装Cygwin来模拟这种环境<br />
4、 nutch-1.0<br />
4.1 下载 <a href="http://www.apache.org/dyn/closer.cgi/lucene/nutch/">http://www.apache.org/dyn/closer.cgi/lucene/nutch/</a><a href="http://lucene.apache.org/nutch/"></a></p>
<p>4.2  解压后到C盘根目录</p>
<p>C:\nutch-1.0</p>
<p>建 url.txt文件，指定爬取列表<br />
在文件中写入如下内容：<br />
例如：<a href="http://cqllang.javaeye.com/blog">http://cqllang.javaeye.com/blog</a><br />
4.3  指定爬虫规则<br />
修改 conf/crawl-urlfilter.txt</p>
<p> </p>
<p>QUOTE:</p>
<p># accept hosts in MY.DOMAIN.NAME<br />
#+^<a href="http://(/">http://(</a>[a-z0-9]*\.)*MY.DOMAIN.NAME/<br />
把这里改成你要的域名<br />
如 +^<a href="http://cqllang.javaeye.com/blog">http://cqllang.javaeye.com/blog</a></p>
<p> </p>
<p>4.4 修改 conf/nutch-site.xml</p>
<p>QUOTE:</p>
<p>&lt;configuration&gt;<br />
        &lt;property&gt;<br />
                &lt;name&gt;http.agent.name&lt;/name&gt;<br />
                &lt;value&gt;my nutch agent&lt;/value&gt;<br />
        &lt;/property&gt;<br />
        &lt;property&gt;<br />
                &lt;name&gt;http.agent.version&lt;/name&gt;<br />
                &lt;value&gt;1.0&lt;/value&gt;<br />
        &lt;/property&gt;<br />
&lt;/configuration&gt;</p>
<p>如果没有配置此agent，爬取时会出现 Agent name not configured! 的错误。</p>
<p>4.5 开始爬取</p>
<p>打开Cygwin,</p>
<p>在命令行窗口中输入：  <br />
 　　cd /cygdrive/c/nutch-1.0<br />
执行命令：</p>
<p>bin/nutch crawl url.txt -dir crawled -depth 3 -threads 4 &gt;&amp; crawl.log</p>
<p>在这里</p>
<p>dir指定抓取内容所存放的目录，depth表示以要抓取网站顶级网址为起点的爬行深度，threads指定并发的线程数。</p>
<p>4.6 部署web前端<br />
将 nutch-1.0.war 拷贝到webapps目录下<br />
通过浏览器访问<a href="http://localhost:8080/nutch-0.9/">http://localhost:8080/nutch-1.0/</a> 后，war包自解压。<br />
4.7 修改nutch的web配置<br />
c:\tomcat6\webapps\nutch-1.0\WEB-INF\classes\nutch-site.xml<br />
将内容更改为索引生成的目录。<br />
QUOTE:</p>
<p>&lt;nutch-conf&gt;<br />
        &lt;property&gt;<br />
                &lt;name&gt;searcher.dir&lt;/name&gt;<br />
                &lt;value&gt;c:/nutch-1.0/crawled&lt;/value&gt;<br />
        &lt;/property&gt;<br />
&lt;/nutch-conf&gt;</p>
]]></content:encoded>
			<wfw:commentRss>http://www.liulang.cq.cn/20090714/nutch1-0config.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>自己动手搭建搜索引擎(基于Nutch1.0)</title>
		<link>http://www.liulang.cq.cn/20090714/myselfconfignutch1-0.html</link>
		<comments>http://www.liulang.cq.cn/20090714/myselfconfignutch1-0.html#comments</comments>
		<pubDate>Tue, 14 Jul 2009 15:27:41 +0000</pubDate>
		<dc:creator>刘 浪</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[搜索引擎]]></category>

		<guid isPermaLink="false">http://www.liulang.cq.cn/?p=7</guid>
		<description><![CDATA[网上发现很多关于Nutch配置搜索引擎的文章，但我觉得对于很多新手来说。配置的话有时往往不知如何下手，下面推荐两个视频。帮助大家可以一步一步搭建自己的搜索引擎。    自己动手搭建搜索引擎 &#8211; 1 在线观看： http://www.boobooke.com/v/bbk2817 自己动手搭建搜索引擎 &#8211; 2 在线观看： http://www.boobooke.com/v/bbk2818   希望能帮助入门。有兴趣的可能研究nutch1.0源码。]]></description>
			<content:encoded><![CDATA[<div>
<p>网上发现很多关于Nutch配置搜索引擎的文章，但我觉得对于很多新手来说。配置的话有时往往不知如何下手，下面推荐两个视频。帮助大家可以一步一步搭建自己的搜索引擎。</p>
<p>  </p>
<p>自己动手搭建搜索引擎 &#8211; 1</p>
<p>在线观看： <a href="http://www.boobooke.com/v/bbk2817" target="_blank">http://www.boobooke.com/v/bbk2817</a></p>
<p>自己动手搭建搜索引擎 &#8211; 2</p>
<p>在线观看： <a href="http://www.boobooke.com/v/bbk2818" target="_blank">http://www.boobooke.com/v/bbk2818</a></p>
<p> </p>
<p>希望能帮助入门。有兴趣的可能研究nutch1.0源码。</p></div>
]]></content:encoded>
			<wfw:commentRss>http://www.liulang.cq.cn/20090714/myselfconfignutch1-0.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
		<item>
		<title>Android开发环境搭建及第一个HelloWorld程序</title>
		<link>http://www.liulang.cq.cn/20090714/androidconfigandhelloworld.html</link>
		<comments>http://www.liulang.cq.cn/20090714/androidconfigandhelloworld.html#comments</comments>
		<pubDate>Tue, 14 Jul 2009 15:26:31 +0000</pubDate>
		<dc:creator>刘 浪</dc:creator>
				<category><![CDATA[JAVA]]></category>
		<category><![CDATA[移动开发]]></category>

		<guid isPermaLink="false">http://www.liulang.cq.cn/?p=3</guid>
		<description><![CDATA[Android开发环境搭建 http://www.boobooke.com/v/bbk2635 Android上第一个HelloWorld程序 http://www.boobooke.com/v/bbk2636]]></description>
			<content:encoded><![CDATA[<p>Android开发环境搭建</p>
<p><a href="http://www.boobooke.com/v/bbk2635" target="_blank">http://www.boobooke.com/v/bbk2635</a></p>
<p>Android上第一个HelloWorld程序</p>
<p><a href="http://www.boobooke.com/v/bbk2636" target="_blank">http://www.boobooke.com/v/bbk2636</a></p>
]]></content:encoded>
			<wfw:commentRss>http://www.liulang.cq.cn/20090714/androidconfigandhelloworld.html/feed</wfw:commentRss>
		<slash:comments>0</slash:comments>
		</item>
	</channel>
</rss>

