这本书原本不在我的阅读计划内,在浙图借书的时候偶然发现的,遂借下。
它基本上没讲什么高深的东东,更多的是在日常编写代码过程中非常经常遇到的那些点。
它适合的人群,应该是在每周的工作中都要写上几天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,满足某个条件的话就一直执行

Jakarta Commons 笔记,Part II

anyShare分享到:
          

没准儿您会对以下内容感兴趣: