Java开源工具使用介绍-----Apache Commons Lang

一个优秀的类应该重写toString,hashCode,equals,compareTo方法,我们来看一下apache如何带我们简化这些操作,以下示例支持两种形式,一种是通过逐个参数添加从而精细控制那些参数参与比较和输出,另一种是通过反射让全部参数都参与比较和输出 

Builder系列 

 

 
  1. //ToStringBuilder

  2. @Override

  3. public String toString() {

  4. return new ToStringBuilder(this).append(this.getId())

  5. .append(this.getUsername()).toString();

  6. }

  7.  
  8. @Override

  9. public String toString() {

  10. return ToStringBuilder.reflectionToString(this);

  11. }

  12. // 以上输出格式为 Test@1270b73[<null>,<null>]

  13.  
  14.  
  15.  
  16. // HashCodeBuilder

  17. @Override

  18. public int hashCode() {

  19. return HashCodeBuilder.reflectionHashCode(this);

  20. }

  21.  
  22. @Override

  23. public int hashCode() {

  24. return new HashCodeBuilder(this).append(this.getId())

  25. .append(this.getUsername()).hashCode();

  26. }

  27.  
  28.  
  29.  
  30. // EqulasBuilder

  31. @Override

  32. public boolean equals(Object obj) {

  33. if (this == obj) {

  34. return true;

  35. }

  36. if (obj.getClass() == Test.class) {

  37. Test test = (Test) obj;

  38. return new EqualsBuilder().append(this.getId(), test.getId())

  39. .append(this.getUsername(), test.getUsername()).isEquals();

  40. }

  41. return false;

  42. }

  43. @Override

  44. public boolean equals(Object obj) {

  45. return EqualsBuilder.reflectionEquals(this, obj);

  46. }

  47.  
  48.  
  49. // CompareToBuilder

  50. @Override

  51. public int compareTo(Test o) {

  52. return CompareToBuilder.reflectionCompare(this, o);

  53. }

  54.  
  55. @Override

  56. public int compareTo(Test o) {

  57. return new CompareToBuilder().append(this.getId(), o.getId())

  58. .append(this.getUsername(), o.getUsername()).toComparison();

  59. }

 

使用commons能最大程度的简化代码,实现one-line编程,注意使用反射形式的时候,static和transient不会参与比较或输出,要特别注意 


      有些情况下,Arrays满足不到你对数组的操作?不要紧,ArrayUtils帮你 

      ArrayUtils 

 
  1. public class TestMain {

  2.  
  3. public static void main(String[] args) {

  4. int[] nums1 = { 1, 2, 3, 4, 5, 6 };

  5. // 通过常量创建新数组

  6. int[] nums2 = ArrayUtils.EMPTY_INT_ARRAY;

  7.  
  8. // 比较两个数组是否相等

  9. ArrayUtils.isEquals(nums1, nums2);

  10.  
  11. // 输出数组,第二参数为数组为空时代替输出

  12. ArrayUtils.toString(nums1, "array is null");

  13.  
  14. // 克隆新数组,注意此拷贝为深拷贝

  15. int[] nums3 = ArrayUtils.clone(nums1);

  16.  
  17. // 截取数组

  18. ArrayUtils.subarray(nums1, 1, 2);

  19.  
  20. // 判断两个数组长度是否相等

  21. ArrayUtils.isSameLength(nums1, nums2);

  22.  
  23. // 判断两个数组类型是否相等,注意int和Integer比较时不相等

  24. ArrayUtils.isSameType(nums1, nums2);

  25.  
  26. // 反转数组

  27. ArrayUtils.reverse(nums1);

  28.  
  29. // 查找数组元素位置

  30. ArrayUtils.indexOf(nums1, 5);

  31.  
  32. // 查找数组元素最后出现位置

  33. ArrayUtils.lastIndexOf(nums1, 4);

  34.  
  35. // 查找元素是否存在数组中

  36. ArrayUtils.contains(nums1, 2);

  37.  
  38. // 将基本数组类型转为包装类型

  39. Integer[] nums4 = ArrayUtils.toObject(nums1);

  40.  
  41. // 判断是否为空,length=0或null都属于

  42. ArrayUtils.isEmpty(nums1);

  43.  
  44. // 并集操作,合并数组

  45. ArrayUtils.addAll(nums1, nums2);

  46.  
  47. // 增加元素,在下标5中插入10,注意此处返回是新数组

  48. ArrayUtils.add(nums1, 5, 1111);

  49.  
  50. // 删除指定位置元素,注意返回新数组,删除元素后面的元素会前移,保持数组有序

  51. ArrayUtils.remove(nums1, 5);

  52.  
  53. // 删除数组中值为10的元素,以值计算不以下标

  54. ArrayUtils.removeElement(nums1, 10);

  55. }

  56. }


还在使用传统反射吗?还在被反射的样板代码困扰?看commons如何帮助我们简化反射的工作,从样板代码抽身 

      ClassUtils 

 

 
  1. public class TestMain {

  2.  
  3. public static void main(String[] args) {

  4. // 获取Test类所有实现的接口

  5. ClassUtils.getAllInterfaces(Test.class);

  6.  
  7. // 获取Test类所有父类

  8. ClassUtils.getAllSuperclasses(Test.class);

  9.  
  10. // 获取Test类所在的包名

  11. ClassUtils.getPackageName(Test.class);

  12.  
  13. // 获取Test类简单类名

  14. ClassUtils.getShortClassName(Test.class);

  15.  
  16. // 判断是否可以转型

  17. ClassUtils.isAssignable(Test.class, Object.class);

  18.  
  19. // 判断是否有内部类

  20. ClassUtils.isInnerClass(Test.class);

  21.  
  22. }

  23. }

 

ConstructorUtils 

 

 
  1. public class TestMain {

  2.  
  3. public static void main(String[] args) {

  4.  
  5. // 获取参数为String的构造函数

  6. ConstructorUtils.getAccessibleConstructor(Test.class, String.class);

  7.  
  8. // 执行参数为String的构造函数

  9. Test test = (Test) ConstructorUtils.invokeConstructor(Test.class,

  10. "Hello");

  11. }

  12. }


  MethodUtils 

 

 
  1. public static void main(String[] args) throws NoSuchMethodException,

  2. IllegalAccessException, InvocationTargetException {

  3. // 调用无参方法

  4. Test test = new Test();

  5. MethodUtils.invokeMethod(test, "publicHello", null);

  6.  
  7. // 调用一参方法

  8. MethodUtils.invokeMethod(test, "publicHello", "Hello");

  9.  
  10. // 调用多参方法

  11. MethodUtils.invokeMethod(test, "publicHello", new Object[] { "100",

  12. new Integer(10) });

  13.  
  14. // 调用静态方法

  15. MethodUtils.invokeStaticMethod(Test.class, "staticHello", null);

  16. }


FieldUtils 

 

 
  1. public class TestMain {

  2.  
  3. public static void main(String[] args) throws IllegalAccessException {

  4. Test test = new Test("1", "Ray", "hello");

  5.  
  6. // 以下两个方法完全一样,都能获取共有或私有变量,因为第三个参数都设置了不检查

  7. FieldUtils.getDeclaredField(Test.class, "username", true);

  8. FieldUtils.getField(Test.class, "username", true);

  9.  
  10. // 读取私有或公共变量的值

  11. FieldUtils.readField(test, "username", true);

  12.  
  13. // 读取静态变量

  14. FieldUtils.readStaticField(Test.class, "STATIC_FIELD");

  15.  
  16. // 写入私有或共有变量

  17. FieldUtils.writeField(test, "username", "RayRay", true);

  18.  
  19. // 写入静态变量

  20. FieldUtils.writeStaticField(Test.class, "STATIC_FIELD", "static_value");

  21. }

  22. }


 读者在使用时可能会发现,MethodUtils和ConstructUtils在org.apache.commons.lang.reflect和org.apache.commons.beanutils都存在,但FieldUtils和ClassUtils只在reflect当中存在,因为beanutils提供了另外一种名为PropertyUtils的对属性存取更为方便的工具,但PropertyUtils不能获取传统反射的Field对象,笔者建议MethodUtils和ConstructUtils应该倾向使用beanutils,因为beanutils就是为反射而存在,更专业(虽然提供的方法几乎一样),而使用ClassUtils和要获取传统的Field对象时使用reflect中的FieldUtils 

 

很多情况下我们都需要将字符串转换为数字,或判断字符串是否是数字等等操作,NumberUtils帮助我们方便的从字符串转换为数字,在不使用NumberUtils情况下,若然字符串值不是数字,使用Integer.parseInt()时会报出java.lang.NumberFormatException,但在NumberUtils的情况下,只会返回0而不产生错误 

      NumberUtils  and  RandomUtils 

 

 

 
  1. public class TestMain {

  2. public static void main(String[] args) throws IllegalAccessException {

  3. String str = "12.7";

  4. /*

  5. * org.apache.commons.lang.NumberUtils已经被弃用,

  6. * 注意要引入org.apache.commons.lang.math.NumberUtils

  7. */

  8.  
  9. // 判断字符串是否为整数

  10. NumberUtils.isDigits(str);

  11.  
  12. // 判断字符串是否为数字

  13. NumberUtils.isNumber(str);

  14.  
  15. // 获取参数中最大的值,支持传入数组

  16. NumberUtils.max(10, 20, 30);

  17.  
  18. // 获取参数中最小的值,支持传入数组

  19. NumberUtils.min(10, 20, 30);

  20.  
  21. // 将字符串转换为int类型,支持float,long,short等数值类型

  22. NumberUtils.toInt(str);

  23.  
  24. // 通过字符串创建BigDecimal类型 ,支持int,float,long等数值

  25. NumberUtils.createBigDecimal(str);

  26.  
  27.  
  28. /*

  29. * RandomUtils帮助我们产生随机数,不止是数字类型 ,

  30. * 连boolean类型都可以通过RandomUtils产生

  31. */

  32. RandomUtils.nextBoolean();

  33. RandomUtils.nextDouble();

  34. RandomUtils.nextLong();

  35. // 注意这里传入的参数不是随机种子,而是在0~1000之间产生一位随机数

  36. RandomUtils.nextInt(1000);

  37.  
  38. }

  39. }

 

 在开发当中字符串的使用和操作时最为频繁的,而null的字符串经常让我们报出NullPointerException,在使用StringUtils后,将不需要为字符串的null值而烦恼,却又提供了更多的操作让我们更方便的操作字符串 



      StringUtils 

 

 
  1. public class TestMain {

  2. public static void main(String[] args) throws IllegalAccessException {

  3. String str = "Hello World";

  4. /*

  5. * 由于StringUtils拥有100+的方法,笔者不逐一列举用法,

  6. * 只列举笔者认为常用的或笔者使用过的

  7. */

  8.  
  9. // isEmpty和isBlank的区别在于isEmpty不会忽略空格,

  10. // " "<--对于这样的字符串isEmpty会认为不是空,

  11. // 而isBlank会认为是空,isBlank更常用

  12. StringUtils.isEmpty(str);

  13. StringUtils.isNotEmpty(str);

  14. StringUtils.isBlank(str);

  15. StringUtils.isNotBlank(str);

  16.  
  17.  
  18. // strip --> 去除两端的aa

  19. // stripStart --> 去除开始位置的hell

  20. // stripEnd --> 去除结尾位置的orld

  21. StringUtils.strip(str, "aa");

  22. StringUtils.stripStart(str, "hell");

  23. StringUtils.stripEnd(str, "orld");

  24.  
  25.  
  26. // 返回字符串在第三次出现A的位置

  27. StringUtils.ordinalIndexOf(str, "A", 3);

  28.  
  29.  
  30. // 获取str 开始为hello结尾为orld中间的字符串

  31. // 注意此方法返回字符串 -->substringBetween

  32. // 注意此方法返回字符串数组(多了个s) --> substringsBetween

  33. StringUtils.substringBetween(str, "hell", "orld");

  34. StringUtils.substringsBetween(str, "hell", "orld");

  35.  
  36.  
  37. // 重复字符串,第二种重载形式为在重复中用hahah拼接

  38. StringUtils.repeat(str, 3);

  39. StringUtils.repeat(str, "hahah", 2);

  40.  
  41.  
  42. // 统计参数2在字符串中出现的次数

  43. StringUtils.countMatches(str, "l");

  44.  
  45.  
  46. // 判断字符串是否全小写或大写

  47. StringUtils.isAllLowerCase(str);

  48. StringUtils.isAllUpperCase(str);

  49.  
  50.  
  51. // isAlpha --> 全部由字母组成返回true

  52. // isNumeric -->全部由数字组成返回true

  53. // isAlphanumeric -->全部由字母或数字组成返回true

  54. // isAlphaSpace -->全部由字母或空格组成返回true

  55. // isWhitespace -->全部由空格组成返回true

  56. StringUtils.isAlpha(str);

  57. StringUtils.isNumeric(str);

  58. StringUtils.isAlphanumeric(str);

  59. StringUtils.isAlphaSpace(str);

  60. StringUtils.isWhitespace(str);

  61.  
  62.  
  63. // 缩进字符串,第二参数最低为 4,要包含...

  64. // 现在Hello World输出为H...

  65. StringUtils.abbreviate(str, 4);

  66.  
  67.  
  68. // 首字母大写或小写

  69. StringUtils.capitalize(str);

  70. StringUtils.uncapitalize(str);

  71.  
  72.  
  73. // 将字符串数组转变为一个字符串,通过","拼接,支持传入iterator和collection

  74. StringUtils.join(new String[] { "Hello", "World" }, ",");

  75.  
  76.  
  77.  
  78. /*

  79. * 经常性要把后台的字符串传递到前提作为html代码进行解释,

  80. * 可以使用以下方法进行转换,以下方法输出为

  81. * <p>Hello</p>

  82. */

  83. StringEscapeUtils.escapeHtml("Hello

  84. ");

  85. }

  86. }


DateUtils and DateFormatUtils 

 

 
  1. public class TestMain {

  2. public static void main(String[] args) throws IllegalAccessException {

  3. Date day1 = new Date();

  4. /*

  5. * 由于Aache的DateUtils和DateFormatUtils并没有Joda强大,

  6. * 所以在这里只作简单的示例

  7. */

  8.  
  9. // 增加一天

  10. DateUtils.addDays(day1, 1);

  11. // 减少一年

  12. DateUtils.addYears(day1, -1);

  13.  
  14. // 格式化时间,第三参数为国际化,表示按美国时间显示

  15. DateFormatUtils.format(day1, "yyyy-MM-dd", Locale.UK);

  16.  
  17. }

  18. }


总结: 
      commons工具包很多开源组织都有提供,例如google,spring,apache都有各自的工具包,有众多的选择,但最终的目的只是为了方便我们程序的开发和维护,简化我们编写一些常用的逻辑,提升我们开发的效率,从而达到活在开源,善用开源 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值