- 1 环视基础
环视只进行子表达式的匹配,不占有字符,匹配到的内容不保存到最终的匹配结果,是零宽度的。环视匹配的最终结果就是一个位置。
环视的作用相当于对所在位置加了一个附加条件,只有满足这个条件,环视子表达式才能匹配成功。
环视按照方向划分有顺序和逆序两种,按照是否匹配有肯定和否定两种,组合起来就有四种环视。顺序环视相当于在当前位置右侧附加一个条件,而逆序环视相当于在当前位置左侧附加一个条件。表达式
说明
(?<=Expression)
逆序肯定环视,表示所在位置左侧能够匹配Expression
(?<!Expression)
逆序否定环视,表示所在位置左侧不能匹配Expression
(?=Expression)
顺序肯定环视,表示所在位置右侧能够匹配Expression
(?!Expression)
顺序否定环视,表示所在位置右侧不能匹配Expression
Read More - 元组类型,即 Tuple 常在脚本语言中出现,例如 Scala 的 ("Unmi", "fantasia@sina.com", "blahbla")。元组可认为是象数组一样的容器,它的目的是让你方便构造和引用,例如 Pair 可认为是一个只能存两个元素的元组,像是个 Map; 真正的元组应该是可以任意多个元素的容器,绕来绕去,它还是数组,或列表,所以我们实现上还是要借助于数组或是列表。
先看 Scala 中什么是元组:1val tuple = ("Unmi", "fantasia@sina.com", "blahblah...") 2println(tuple._1) //输出 Unmi
Scala 中访问从 1 开始,用 ._1 方式来访问其中的元素。
参照于此,写出一个 Java 版本的 Tuple,为增长你的键盘的使用寿命,我们把方法名也缩短了,例如 make 缩写为 mk,引用元素的方法名为 _,仍然保持 Java 的习惯,索引从 0 开始: Read More - 我们在 Java 中经常会碰到如何把 InputStream 转换成 String 的情形,比如从文件或网络得到一个 InputStream,需要转换成字符串输出或赋给别的变量。
未真正关注这个问题之前我常用的办法就是按字节一次次读到缓冲区,或是建立 BufferedReader 逐行读取。其实大可不必费此周折,我们可以用 Apache commons IOUtils,或者是 JDK 1.5 后的 Scanner,还可用 Google Guava 库的 CharStreams。到了 JDK7,若要从文件中直接得到字符串还能用 java.nio.file.Files#readAllLines 和 java.nio.file.Files#readAllBytes 方法。
下面看各个例子,为能够实际用运,例子写在 main 方法里,并从文件获得一个 InputStream,代码中把可能要捕获的异常抛出来。再就是注意处理输入输出流时有涉及到字符集,字符集乱了就乱码了,默认字符集是 System.getProperty("file.encoding"),通常我们都用 UTF-8,异常 UnsupportedEncodingException 继承自 IOException。
下面的 6 个方法中应该有一个你能看得上的吧,用 Groovy,Scala 的除外,若未找到一个遂意的,告诉我,你有好办法更应该告诉我。
1. 使用 JDK 5 的 Scanner
Read More - Scala 在处理字符串方面终于也与时俱进了,引入了字符串插件,这在许多脚本语言中就早已这么做了。有了这个特性,字面量字符串和变量连接可以不需要总是用加号进行丑陋的连接了。有些脚本语言会是只对双引号字符串解析其中的变量,单引号的不会,当然Scala 是要区分字符串和字符类型。
直白的讲字符串插值就是,val name="Unmi"; val greeting=s"Hello $name"; greeting 的值就是 "Hello name"。产生效应的就是那个 s 方法。
Scala 2.10.0 为我们提供了三种字符串插值的方式,分别是 s, f 和 raw。它们都是定义在 StringContext 中的方法。
s 字符串插值器
可以解析字符串中的变量,可以调用方法,还能进行计算。实际调用的是 StringContext 中的 s 方法。 Read More - 最早的介绍 Scala 语言的书都是以 Scala 的静态类型系统为傲。Scala 也算是个脚本语言,却不像其他许多脚本语言那样类型是动态的,只有执行时才确定,而 Scala 在执行前就确定了类型,比如依赖于比 Java 更强大的类型推断行为。
静态类型不光是变量类型是确定的,还有比如在使用 qual.sel 时,sel 这个属性或是方法(Scala 的访问一致性,属性和方法有时候并没有那么大的区别)必须在 qual 的类型中声明了的。
Scala 思考再三还是加入了 Dynamic Types,这个特性在 Scala 2.9 中是试验性的,必须用 -Xexperimental 进行开启,到了 Scala 2.10.0 中,只有代码中 import scala.language.dynamics 就可用了,或是编译时加 -language:dynamics 选项。
虽然 Scala 2.10.0 加进了 Dynamic Types 特性,但 Scala 仍然是静态类型的语言,因为在编译器同样会检查多出来的类型。
有了 Dynamic Types 之后,Scala 又可更 DSL 了,方法名的动态上可以让它随时包括深刻的业务含义。相比 Java 的 DSL 的能力就太逊了,我们几乎无法在 Java 面前提 DSL 这回事。 Read More - 原来 Java 项目中用的 JSON 组件库主要是 Gson 和 json-lib,Gson 算是很错的库,json-lib 略显寒碜。好啦,最近 Play 2.x 中弃用了 Gson 而采纳了 Jackson,所以现在就来打探一下 Jackson,踩个点吧。
Jackson 号称非常高的性能,听说比另两位兄弟 Gson 和 json-lib 高出一大截,我没有亲测,可是有心人做了,看这个链接 两款JSON类库Jackson与JSON-lib的性能对比(新增第三款测试) 中的数据。2010 年 8 月份的测试结果,不知现在随着版本的变更是否仍然保持着这种悬殊。
通常我会在把文章开头塞丰满,做足前戏,并不是因为在天涯混习惯了的缘故,况且我在天涯总是讷于言的; 在这里,自己的地盘自己作主,不会有要求码足多少字才能发表的自虐性需求,仅仅是让本文在主页上显示时的的概要不空洞而已,可以简单粗暴的称之为废话。
了了,先了解 Jacson 最贴近实际应用场景的应用,即 Jackson 怎么把一个 Java 生成对应的 JSON 字符串,看看前面的文字有这么多了,直接上一段代码吧,而后再慢慢假设与分解: Read More - 前一篇介绍了 JavaDoc 编程,书写自定义的 Taglet 支持 @unmi 等, 那时提到了 Doclet,但是差点无视了 Doclet,现在才知道 Doclet 真是太强大了,有了它你会觉得 javadoc 已经不是原本的那个 javadoc 了,别再把 javadoc 看作只会生成一大堆 HTML 文件的工具了。尤其是搭配上自定义的 Taglet,那可是,自已体验吧。
Doclet 是 JavaDoc 的一个很隆重的扩展点,可以在执行 javadoc 时用 -doclet 来指定自己的 Doclet,那么 doclet 可以为我们做些什么呢?
可以为我们生成 HTML 的 JavaDoc API 文档,这就是默认的 com.sun.tools.doclets.standard.Standard 为我们做的事,还可以像以前那样从源文件中抽取信息生成各种 XML 文件,或是 PDF, Excel, UML 图等等任何可能的内容,或做任何有作为的事情。总之在 doclet 中可以感知道对任何包,类,方法,字段等的遍历。这里 Doclet.com 有大量的第三方的 doclet 供你选择,如:
AntDoclet, API Guide Doclet, EJBGen, Java2Rose Doclet, JDiff, JUnitDoclet, LaTeXtaglet, PDFDoclet, PublishedApiDoclet, ServletDoclet, Spell Check Doclet, UMLGraph, VelocityDoclet, XDoclet, xml-doclet 等数十种 Doclet, 还可以找到别的,所以你要是不想自定义 Doclet 的话,有第三方可用就直接用人家的就行。
总有特殊需求的时候,总有要自定义 Doclet 的时候。说那么多总要来看看 Doclet 可以用来做什么,见如下 DocumentDoclet: Read More - javadoc 可为我们的 Java 项目生成 API 文档,别人的应该是看得多了,自己的可能不好意思晾出来看。那 Java 源代码里的 @author, @see, @param 等应该是司空见惯了吧。除此之外我们还可以自定义自己的 tag,并让它们的内容按照我们需要的格式生成到 javadoc 文档中,或作他用。还记得没有 Maven 的时代我们是怎样用 XDoclet 生映射文件的吗?现在的 Taglet 定制想要做的事情大抵如此。
执行一下 javadoc 命令看看,一堆的参数可以指定,又有学问在里头,且看:
-tag <name>:<locations>:<header> Specify single argument custom tags
-taglet The fully qualified name of Taglet to register
-tagletpath The path to Taglets
和
-doclet <class> Generate output via alternate doclet
-docletpath <path> Specify where to find doclet class files
关于 doclet 部份这儿暂且不说,单讲 tag 部分的东西。
对于自定义 tag,简单的时候,用参数 -tag 都可以不写自己的 taglet 类,例如有这样一个代码: Read More - 寻求了很久关于如何在 Java 中实现多行字符串,即 Here Document。因为在测试中准备大的字符串数据是不得不用加号去拼接,甚至是麻烦。稍好就是用 http://www.htmlescape.net/javaescape_tool.html 把你输入的大段文字生成 Java 的字符串。
找过一些介绍 Java 实现 Here Document 的方法,首先大家无一不是把这个多行字符串塞在注释里,有些实现在运行还在依赖于 Java 源文件中的注释,这不太可取。聪明的做法应该要去打编译器的主意,让编译后体现在 Class 文件中,变量就被赋上了多行字符串值,这就是 JDK1.5 引入的 APT(Annotation Processing Tool),到 JDK1.6 后可操作性更强了,可以 javac 的时候带上 -processor 参数。
单单从语法特性上来讲,我觉得 Java 与现今流行的语言还是有差距,不过它一直在成长,像 JDK 1.5 和 1.7 这两个版本就带来了不少好东西。想要见识一下其他些个语言,如 Perl, PHP, Ruby, C++11 怎么实现 Here Document 还是请看 http://en.wikipedia.org/wiki/Here_document。
就连 Java 最亲密的战友 C# 都早实现了 Here Document,用 @ 符号: Read More - Java 的 Properties 加载属性文件后是无法保证输出的顺序与文件中一致的,因为 Properties 是继承自 Hashtable 的, key/value 都是直接存在 Hashtable 中的,而 Hashtable 是不保证进出顺序的。
总有时候会有关心顺序一致的需求,恰如有 org.apache.commons.collections.OrderdMap(其实用 LinkedHashMap 就是保证顺序) 一样,我们也想要有个 OrderdProperties。网上查了下还真有:
http://livedocs.adobe.com/jrun/4/javadocs/jrunx/util/OrderedProperties.html
http://www.openrdf.org/doc/alibaba/2.0-rc4/apidocs/org/openrdf/repository/object/composition/helpers/OrderedProperties.html
不过没找到源码,其实自己写一个 OrderedProperties 也不难,并不需要重头写起,只要继承自 Properties,覆盖原来的 put/keys,keySet,stringPropertyNames 即可,其中用一个 LinkedHashSet 来保存它的所有 key。完整代码如下: Read More