Jakarta Commons 笔记,Part I

这本书原本不在我的阅读计划内,在浙图借书的时候偶然发现的,遂借下。
它基本上没讲什么高深的东东,更多的是在日常编写代码过程中非常经常遇到的那些点。
它适合的人群,应该是在每周的工作中都要写上几天Java代码的中级程序员。
特别是,如果你的项目里基本上都会有那么一个utils包来处理那些诸如时间日期对象的代码。
当然,包含但不限于此。
记得自己曾经有把 commons-lang 包的javadoc导出,然后看里面几个常用的,如StringUtils类,不过这个类太长了,最终也没把里面的方法一个个的细读掉。有本书的话就好多了。
这个笔记原本想分两篇,由于看世界杯没把自己的状态调整到最佳,没能完成计划中的章节。所以可能是分三篇了。
Chapter#01 扩展J2SE平台
- toString, hashcode, equals,都有对应的 Builder
- 所有的 SimpleDateFormatter 都应该用 org.apache.commons.lang.time.FastDateFormat 代替
- 注意 Sun 提供的所有 Formatter 类都不是线程安全的
- 参数验证可以用 org.apache.commons.lang.Validate 来做,不符合条件的会抛异常
- 用 org.apache.commons.lang.time.StopWatch 来观察程序执行的时间,而没必要自己去记录前后的 currentTimeMillis 再计算。。。
Chapter#02 处理文本
- 对于 org.apache.commons.lang.StringUtils 提供的,和 java.lang.String 里看起来重复了的方法,应当全部选择使用前者,可以避免很多空指针发生的可能。
- StringUtils 还提供了些实用类方法,如repeat,chomp,reverse。更多的,必须去把相关的javadoc通读细读。(试了一下,isWhitespace对半角全角的空格都返回true),里面有意思的方法有很多。甚至还有getLevenshteinDistance(str1, str2)这种好东东。
- org.apache.commons.lang.WordUtils里的方法就比较少了,会用到比较多的,大概只有将每个单词的首字母大写和单词换行了了。
- commons codec,以前在测试URL的几种编码时用过,大概用途就是处理各种编码的。
Chapter#03 JavaBeans
- 这两个方法还是比较类似的:org.apache.commons.beanutils.PropertyUtils.getSimpleProperty(obj, “prop”), PropertyUtils.getNestedProperty(obj, “subobj.subprop”)
- 取数组下标的方法:PropertyUtils.getIndexedProperty,推荐用三个参数的那个,两个参数的方法不能够这样用:getIndexedPreperty(obj, “list[2].prop”),好吧,会试后面这个,是我太天真了。实际应该用这个:PropertyUtils.getProperty(obj, “list[2].prop”)就OK了。
- PropertyUtils.getMappedProperty和getIndexedProperty的使用方法相似
- BeanCompatator,可以简单用属性进行比较排序,也可以自己去实现Comparator来进行排序:
Comparator sampleCompare = new Comparator() { public int compare(Object o1, Object o2) { ...... return -1; } } Collections.sort(sampleObjectList, new BeanComparator("sampleProperty", sampleCompare)); //print......
- 注意Bean复制方法的参数顺序:PropertyUtils.copyProperties(dest, source),此方法的第二个参数,可以接收Map
- 一个疑问:PropertyUtils.copyProperties和BeanUtils.cloneBean之间有差别么?
- 设置bean属性的方法是:PropertyUtils.setProperty,支持嵌套、下标型(好强大)
- 各种Predicates可以验证Beans的内容,如属性值是否相等、属性的类型(class)。
- 不知原因,Bean和Map绑一块儿去的,总觉得读起来没劲。。。
- 当要处理的“类型”很多而又懒得去为这些类型分别创建class的时候,可以用动态创建Beans的DynaBean来代替。
- BeanUtils.setProperty(obj, “prop”, “value”),不管prop是什么类型的,value都可以传入字符串。
Chapter#04 函子(好奇怪的名字)
几个Comparator:
- ReverseComparator,在原先的返回值上 x -1就是了
- ComparatorChain,这个有点类似于SQL里的排序
- NullComparator
- FixedOrderComparator,方便点使用,稍微看了下源码,就是在那个数组装进它的Map的时候定了一个下标,然后拿这个下标做文章。跟我的第一反应差不多。(好吧,我以前在写游戏里面比大小的时候,直接就把牌的值置成可比大小的数字了,只是显示的时候再换成数字或字母而已,而没有使用这么高级的东东)
这一堆Predicate就单纯列在这,不写介绍了:
- EqualPredicate
- IdentityPredicate(大致上可以理解为==)
- NotPredicate
- InstanceOfPredicate
- NullPredicate/NullIsTruePredicate
- NotNullPredicate/NullIsFalsePredicate
- TruePredicate/FalsePredicate
- UniquePredicate
Predicate的存在意义,在于封装些不是一成不变的、可变的因素。比如多少级的地震,教学楼倒塌了要追究建筑方的责任这种事情。是吧,这事不能细说。所以,也不能随便让人知道,需要封装起来。嗯,你懂的。
或者是,一些复杂的因素,没必要让外界知道的,但只用一两个if-else用搞不定的东东。
类似于FixedOrderComparator,Predicate也可以组合起来:
- AndPredicate(A && B)
- OrPredicate(A || B)
- AllPredicate([A, B, C])
- OnePredicate([A, B, C])
- AnyPredicate([A, B, C])
- NonePredicate([A, B, C])
- OnePredicate([A, B, C])
接收两个作为参数,和接收一个数组作为参数
Transformer
简单的转换就那么回事。
需要注意的是不要改变input对象。
SwitchTransformer比较有意思,书中的代码如下:
Transformer oddTransform = new Transformer() { public Object transform(Object input) { return new Integer(((Integer) input) * 2); } }; Transformer evenTransform = new Transformer() { public Object transform(Object input) { return new Integer(((Integer) input) * 3); } }; Predicate isEven = new Predicate() { public boolean evaluate(Object object) { return ((Integer) object) % 2 == 0; } }; Predicate[] pArray = new Predicate[] {new NotPredicate(isEven), isEven}; Transformer[] tArray = new Transformer[] {oddTransform, evenTransform}; Transformer predicateTransform = new SwitchTransformer(pArray, tArray, NOPTransformer.getInstance()); System.out.println("Transform of 1 = " + predicateTransform.transform(1)); System.out.println("Transform of 2 = " + predicateTransform.transform(2)); System.out.println("Transform of 3 = " + predicateTransform.transform(3)); System.out.println("Transform of 4 = " + predicateTransform.transform(4));
传入的两个数组必须是一一对应的pair,第三个参数是所有的predicate都返回false时调用,这个例子永远跑不到它。
书中的代码,NOPTransfromer用的是new来实例化,是错误的,它是个单例的实现。
Closure
链接多个Closure的办法是:new ChainedClosure(newClosure[]{xxxxxx})。
其它类型的Closure:
- ExceptionClosure,只抛异常
- ForClosure,执行一定的次数
- IfClosure,传一个predicate、两个closure给它,根据predicate的返回决定执行哪个closure
- NOPClosure,啥也不干
- SwitchClosure,它的方法声明是:getInstance(Predicate[] predicates, Closure[] closures, Closure defaultClosure),P数组里的东东和C数组里的东东一一对应
- TransformerClosure,获取方法是:getInstance(Transformer transformer) ,它的execute方法里就调用了transformer.transform(obj),完事
- WhileClosure,满足某个条件的话就一直执行
| anyShare分享到: | |
| |
把你的RSS输出改成其他的吧,不翻墙的话,没法订阅。
[回复]
Black Lee 回复:
六月 28th, 2010 at 16:35
@kyle, 不改了,贵国用RSS的,10有八9是用GoogleReader,这八9个人,一天翻墙的次数,估计比吃饭的次数都多。
[回复]
Black Lee 回复:
六月 28th, 2010 at 16:39
@kyle, 忘了说一下,把RSS或Blog地址直接在GoogleReader里填写,是可以用滴。
[回复]