Apache Commons ArrayUtils.toString(Object)与JDK Arrays.toString(Object)

Apache Commons Lang提供了一个ArrayUtils类,其中包含toString(Object)方法,该方法“将数组作为字符串输出”。 在本文中,我将研究当JDK提供Arrays.toString(Object [])方法[以及原始类型数组的Arrays类上该方法的多个重载版本]时,该方法仍然有用的情况。

ArrayUtils.toString(Object) ,使用Apache Commons Lang ArrayUtils.toString(Object)方法的原因可能是JDK没有提供替代方法。 Arrays.toString(Object[])是在J2SE 52004年末 Arrays.toString(Object[])中引入的,因为Apache Commons Lang自至少Lang 2.02003年末 ArrayUtils.toString(Object)以来就拥有ArrayUtils.toString(Object) )。 尽管这些发行版之间只有一年多的差异,但是许多组织比JDK版本更愿意升级库,因此有些组织之所以选择使用Lang API是因为他们甚至在其通用发行版之后仍未采用JDK。 但是,到今天,可能只有极少数的Java部署未使用JDK 5或更高版本,因此这似乎不再是在新编写的代码中使用Apache Commons Lang方法而不是JDK方法的原因。 。

相对于JDK的Arrays.toString(Object[]) ArrayUtils.toString(Object)可能选择Apache Commons Lang的ArrayUtils.toString(Object)另一个原因是从元素数组构造的字符串的格式。 这似乎不是很吸引人的动机,因为各自的输出没有太大的不同。

对于本文中的示例,我假设定义了一个String数组,如下所示:

/** Array of {@code String}s used in these demonstrations. */
private static final String[] strings
   = {"Dustin", "Inspired", "Actual", "Events"};

将上面定义的数组传递给JDK的Arrays.toString(Object[])和Apache Commons Lang的ArrayUtils.toString(Object) ,下面将分别比较每个数组分别生成的String表示形式。

JDK Arrays.toString(Object[])与ACL ArrayUtils.toString(Object)
比较典型Java数组的单字符串输出
输入数组 JDK Arrays.toString(Object[]) Apache Commons Lang ArrayUtils.toString(Object)
{"Dustin", "Inspired", "Actual", "Events"} [Dustin, Inspired, Actual, Events] {Dustin,Inspired,Actual,Events}

该表说明了这两种方法的生成的字符串在实质意义上非常相似,但是它们的输出存在外观差异。 JDK版本用方括号将生成的字符串的数组内容括起来,而Apache Commons Lang版本用花括号将数组内容括起来。 另一个明显的区别是,JDK数组元素在字符串中用定界符表示,该定界符由逗号和空格组成,而Apache Commons Lang表示的数组元素只用逗号定界而没有空格。

如果Apache Commons Lang ArrayUtils.toString(Object)允许自定义其输出的“样式”,则可能会进一步证明其表示样式是一种优势。 但是, 从方法的实现中可以看出 ,它始终使用ToStringStyle.SIMPLE_STYLE

这里讨论的将Java数组表示为单个String表示形式的两种方法之间的另一个小区别是对传递给方法的null的处理。 两种方法在传递null时都返回一个非null非空String ,但是该字符串的内容根据所调用的实现而有所不同。 JDK的Arrays.toString(Object[])返回字符串"null"时, null传递给它,而阿帕奇共享郎的ArrayUtils.toString(Object)返回字符串"{}"null传递给它。

ArrayUtils.toString(Object)返回的"{}"很容易理解,并且在某种程度上, ArrayUtils.toString(Object)为呈现为数组提供的null的字符串版本,这种方法在美学上更令人愉悦。 但是,可以说"{}"表示一个空数组而不是null 。 实际上,Apache Commons Language版本确实为空数组返回了相同的"{}"字符串(并且与使用数组初始值设定项声明空数组的方式完全匹配)。 JDK的Arrays.toString(Object[])方法为null输入提供字符串"null" ,为空数组输入提供"[]"

可以说,将null数组参数的字符串版本表示为"null"的JDK方法与Java开发人员在给定其他类似情况下提供null String表示的情况下可能期望的一致。 null的隐式String转换 (有关更多详细信息,请参见Java SE 10语言规范的 5.1.11节 )和通过对null参数调用String.valueOf(Object)返回的String表示字符串"null" 。 数组类型的隐式String转换为null也会导致"null"字符串。

ArrayUtils.toString(Object)Arrays.toString(Object[])之间的另一个区别是每种方法所需的参数类型。 ArrayUtils.toString(Object)实现需要一个Object ,因此可以接受几乎任何想要提供给它的东西。 JDK的Arrays.toString(Object[])强制向其提供数组(或null ),而不能向其提供非数组类型。 哪种方法更好是有争议的,但是我个人通常更喜欢使用严格类型化的API,这些API仅允许其宣传(有助于执行合同)。 在这种情况下,因为所需的功能是传递一个数组并返回该数组的String表示形式,所以我更希望使用更确定类型的方法来期望一个数组。 另一方面,可能有人争辩说他们更喜欢接受通用Object的方法,因为这样可以将任何任意对象(例如Java collection )传递给该方法。

通常,我不喜欢在名为ArrayUtils的类上使用方法来构建除数组以外的任何内容的String表示的想法。 我已经见过此方法在Java集合上使用,但是没有必要,因为Java集合已经提供了合理的toString()实现(数组不能覆盖ObjecttoString() ,这就是为什么它们需要这些外部方法来这样做)。 也不必使用ArrayUtils.toString(Object)来确保在没有NullPointerException的情况下处理null因为Objects.toString(Object)可以很好地处理该情况,并且不会假装为“数组”方法(实际上,它不会对数组没有太大帮助)。

通过提供每个实现预期参数的差异String所提供的阵列引线表示进入的动机,我认为是最有说服力的选择第三方库提供的ArrayUtils.toString(Object)在内置Arrays.toString(Object[]) ,但是对于一种特定情况,这是一个显着的优势: 多维 Java数组。 JDK的Arrays.toString(Object[])仅设计用于一维Java数组。 但是,Apache Commons Lang ArrayUtils.toString(Object)很好地支持呈现单个String表示形式,甚至是多维Java数组。 它的方法级Javadoc宣传了这一优势:“多维数组得到正确处理,包括多维基本数组。” 为了说明这些方法在多维数组输出中的差异,我将使用这个可笑的示例:

/** Two-dimensional array of {@code String}s used in demonstrations. */
private static final String[][] doubleDimStrings
   = {{"Dustin"}, {"Inspired", "Actual", "Events"}};

下表显示了将String的二维数组传递给相应方法的输出。

JDK Arrays.toString(Object[])与ACL ArrayUtils.toString(Object)
比较二维数组的单字符串输出
输入数组 JDK Arrays.toString(Object[]) Apache Commons Lang ArrayUtils.toString(Object)
{{"Dustin"}, {"Inspired", "Actual", "Events"}} [[Ljava.lang.String;@135fbaa4, [Ljava.lang.String;@45ee12a7] {{Dustin},{Inspired,Actual,Events}}

刚刚显示的表证明,一旦Java数组具有多个维,JDK的Arrays.toString()并不会特别有用。 Apache Commons Lang的ArrayUtils.toString(Object)甚至可以呈现多维数组的漂亮的单个String表示形式。

我有意避免在性能方面对本文中涉及的两种选择进行比较,因为我很少在日常工作中发现这些类型方法的性能差异很重要。 但是,如果在每毫秒计数的情况下需要此功能,那么可能有必要在实际情况下尝试每种功能,选择效果最好的一种。 我的直觉告诉我,JDK实现通常会更好(特别是如果使用基元数组,并且能够使用Arrays用于基元的重载toString()方法之一),但是我的直觉在涉及到之前是错误的。性能问题。

下表总结了我的帖子对Apache Commons Lang(版本3.7) ArrayUtils.toString(Object)和JDK(JDK 10) Arrays.toString(Object [])的特性的讨论

JDK Arrays.toString(Object[])与ACL ArrayUtils.toString(Object)
输入类型 JDK Arrays.toString(Object[]) Apache Commons Lang ArrayUtils.toString(Object)
一维数组 "[Dustin, Inspired, Actual, Events]" "{Dustin,Inspired,Actual,Events}"
二维数组 "[[Ljava.lang.String;@135fbaa4, [Ljava.lang.String;@45ee12a7]" "{{Dustin},{Inspired,Actual,Events}}"
null "null" "{}"
空一维数组 "[]" "{}"

这篇文章探讨了一些可能的动机,它们选择了内置JDK的Arrays.toString(Object [])来选择第三方Apache Commons Lang的ArrayUtils.toString(Object 来生成数组的单个String表示形式。 我发现最明显的情况是,对于多维数组,选择此特定的第三方库而不是内置替代方法。

翻译自: https://www.javacodegeeks.com/2018/08/apache-commons-versus-jdk.html

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值