前面一段时间把commons包过了一遍,倒不是为了全面了解这些包的用法,而是为了能够大致了解这些包的功能,在平时需要用到的时候能够想到用它们而已。包含如下几种常用的commons包:
commons-lang
commons-collections
commons-io
commons-beanutils
对这些包最常用的类都试用了一下,很多方法好用但是都不常用,结合一般写code的经验,把最最常用的几种归纳如下。
1 数组Object-primitive转换问题
尽管jdk1.5之后Object和primitive已经实现了自动装箱拆箱,但是对于数组还是会遇到Object类型数组和primitive数组的转换问题,比如一个Integer[]和int[]的转换问题。
特别是当和list配置使用的时候,list只能够转化为Object类型数组,比如下面是一段常用代码:
List<Integer> intList=new ArrayList<Integer>(); intList.add(1); intList.add(2); Integer[] objectArray=intList.toArray(new Integer[0]); int[] primitiveArray=ArrayUtils.toPrimitive(objectArray); System.out.println(primitiveArray);//输出为[I@109a4c System.out.println("intArray: " + ArrayUtils.toString(primitiveArray));//输出为intArray: {1,2}
这个时候使用ArrayUtils.toPrimitive和ArrayUtils.toObject方法就能够在Object数组和primitive数组之间进行方便的转换,否则也就不得不使用for循环去做转换操作了。
2 数组输出显示问题
在System.out或者写log的时候,和各个Collection类分别覆盖了toString()方法不同,数组的System.out默认就是"[I@109a4c"这种方式的字符串,其中"[I"标识是数组类型,"@109a4c"就是对象标识了。
使用ArrayUtils的toString则能够实现数组的输出,如上面的代码示例。
3 数组的add或者sub操作
对于Object类型数组来说,是很好处理的,比如可以使用泛型操作写一个工具类兼容各种类型,但是对于primitive数组来说,就不能自己写方法了。
ArrayUtils的addAll,subarray方法提供了对primitive数组进行处理的方法。
另外java.util.Arrays类也提供了部分方法。
4 List初始化和赋值问题
new一个List然后接着对其赋值是一个很麻烦的操作,比如写代码的时候很讨厌new一个ArrayList出来,然后不停地add,比如如下的代码:
List<Integer> intList=new ArrayList<Integer>(); intList.add(1); intList.add(2);
因此希望能够向数组那样在new的同时进行初始化,比如:
int[] intArrays=new int[]{1,2};
java.util.Arrays类提供了asList方法,如下:
public static <T> List<T> asList(T... a) { return new ArrayList<T>(a); }
但是使用这个方法的时候需要注意,代码里面return new ArrayList<T>(a);其实返回的是一个java.util.Array.ArrayList类,而不是我们常用的java.util.ArrayList,这个ArrayList是没有实现add方法的,所以说是一个不能扩展的list,使用的时候需要特别小心。
对于这个问题,commons包也没有什么方便方法,但是google collection包倒是提供了Lists.newArrayList方法解决了问题,比如:
List<Integer> intList = Lists.newArrayList(1,2);
因此使用的时候可以使用该方法,或者自己实现一个,也比较简单。
5 输入输出和文件读写
commons-io包中的IOUtils类提供了很多IO的方便方法,最主要的是copy方法,提供输入输出流之间的转换,包含了 inputstream,outputstream,reader,writer这几种常用的类。如下代码所示:
InputStream in = new FileInputStream("NOTICE.txt"); OutputStream out =new FileOutputStream("NOTICE1.txt"); IOUtils.copy(in, out); IOUtils.closeQuietly(in);//完成了文件读写 Reader reader = new FileReader("NOTICE1.txt"); IOUtils.copy(reader, System.out);//完成了文件输出到控制台 IOUtils.closeQuietly(reader);
另外IOUtils.toString则能够很方便地将文件内容返回为String,如下所示:
InputStream in = new FileInputStream("NOTICE.txt"); String content=IOUtils.toString(in);
6 Collection和Map的遍历处理
common-Collections包提供了对Collection进行遍历然后对每个对象进行处理的方法,在实际中很有用。
Closure closure = new Closure() { public void execute(Object input) { StringBuffer sb = (StringBuffer) input; sb.append("append by closure!"); } }; Set<StringBuffer> bufferSet = new HashSet<StringBuffer>(); bufferSet.add(new StringBuffer()); bufferSet.add(new StringBuffer()); CollectionUtils.forAllDo(bufferSet, closure); System.out.println(ArrayUtils.toString(bufferSet));
另外对于Map的遍历,采用了迭代器MapIterator对Map进行迭代访问,而不用采用map.keySet().iterator()这种麻烦的方式,如下所示。
Map bidiMap=new HashMap(); MapIterator it = bidiMap.mapIterator(); while (it.hasNext()) { Object key = it.next(); Object value = it.getValue(); System.out.println(key + "*****" + value); }
此外也提供了OrderedMap来达到FIFO,按照put的顺序自动排序的Map,而不需要构造Compare进行排序。
OrderedMap map = new LinkedMap(); map.put("FIVE", "5"); map.put("SIX", "6"); map.put("SEVEN", "7"); System.out.println(map.firstKey()); // returns "FIVE" System.out.println(map.nextKey("FIVE")); // returns "SIX" System.out.println(map.nextKey("SIX")); // returns "SEVEN"