Apache Commons Lang предоставляет класс ArrayUtils, который включает метод toString (Object), который «выводит массив в виде строки». В этой статье я рассмотрю ситуации, в которых этот метод все еще может быть полезен, когда JDK предоставляет метод Arrays.toString (Object []) [и несколько перегруженных версий этого метода в классе Arrays для массивов примитивных типов].
В какой-то момент причиной использования метода Apache Commons Lang ArrayUtils.toString(Object)
могло быть то, что в JDK не было альтернативы. Arrays.toString(Object[])
был представлен в J2SE 5 ( конец 2004 года ), где, как и у Apache Commons Lang, ArrayUtils.toString(Object)
имел как минимум Lang 2.0 ( конец 2003 года ). Хотя разница между этими выпусками составляет чуть больше года, многие организации более склонны обновлять библиотеки, чем версии JDK, поэтому некоторые организации решили использовать Lang API, потому что они еще не приняли JDK даже после выпуска General Availability. Однако на сегодняшний день, вероятно, лишь очень и очень небольшой процент развертываний Java не используют JDK 5 или более поздней версии, поэтому это больше не является причиной для использования метода Apache Commons Lang вместо метода JDK во вновь создаваемом коде. ,
Другая причина, по которой Apache Commons Lang ArrayUtils.toString(Object)
может быть выбран поверх Arrays.toString(Object[])
— это формат строки, Arrays.toString(Object[])
из массива элементов. Это не кажется очень убедительной мотивацией, потому что соответствующие результаты не настолько различны.
Для моих примеров в этом посте я предполагаю массив String
определенных следующим образом:
1
2
3
|
/** Array of {@code String}s used in these demonstrations. */ private static final String[] strings = { "Dustin" , "Inspired" , "Actual" , "Events" }; |
Когда определенный выше массив передается в Arrays.toString(Object[])
JDK и в Arrays.toString(Object[])
Apache Commons Lang, соответственно генерируется 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
передаваемого методам. Оба метода возвращают непустую, непустую String
когда передают значение null
, но содержимое этой строки различается в зависимости от вызванной реализации. Arrays.toString(Object[])
JDK возвращает строку "null"
когда ему передается null
в то время как ArrayUtils.toString(Object)
Apache Commons Lang возвращает строку "{}"
когда ему передается null
.
"{}"
Возвращаемый ArrayUtils.toString(Object)
, легко понять, и в некоторых случаях это более эстетично для представления строковой версии null
предоставленной для массива. Тем не менее, можно утверждать, что "{}"
подразумевает пустой массив вместо null
. Версия Apache Commons Language действительно возвращает ту же "{}"
для пустого массива (и это точно соответствует тому, как можно было бы объявить пустой массив с инициализатором массива ). Метод JDK Arrays.toString(Object[])
предоставляет строку "null"
для null
ввода и "[]"
для ввода пустого массива.
Можно утверждать, что подход JDK представления строковой версии параметра null
массива как "null"
более соответствует тому, что разработчик Java может ожидать, учитывая другие подобные ситуации, в которых обеспечивается String
представление null
. И неявное преобразование String
в null
(см. Раздел 5.1.11 спецификации языка Java SE 10 для получения более подробной информации) и String
возвращаемая путем вызова String.valueOf (Object) для null
параметра, представляют строку "null"
. Неявное преобразование String
в null
для типа массива также приводит к появлению строки "null"
.
Другое различие между ArrayUtils.toString(Object)
и Arrays.toString(Object[])
заключается в типе параметра, ожидаемого каждым методом. Реализация ArrayUtils.toString(Object)
ожидает объект и поэтому принимает практически все, что ему нужно предоставить. Arrays.toString(Object[])
JDK заставляет массив (или null
) быть предоставленным ему, и типы не-массива не могут быть предоставлены ему. Это спорно, какой подход лучше, но лично я вообще предпочитаю более строго типизированных API, которые позволяют только то, что они рекламируют (помощь в жизнь свой контракт). В этом случае, поскольку желаемая функциональность заключается в передаче массива и возвращении String
представления этого массива, я предпочитаю метод с более точной типизацией, который ожидает массив. С другой стороны, можно утверждать, что они предпочитают метод, который принимает общий Object
потому что тогда любой произвольный объект (например, коллекция Java ) может быть передан методу.
В общем, мне не нравится идея использования метода класса ArrayUtils
для создания представления String
чего-либо, кроме массива. Я видел, как этот метод используется в коллекциях Java, но в этом нет необходимости, поскольку коллекции Java уже предоставляют разумные реализации toString()
(массивы не могут переопределять toString()
Object
и поэтому им требуются эти внешние методы, чтобы сделать это для них). Также нет необходимости использовать ArrayUtils.toString(Object)
чтобы гарантировать, что null
обрабатывается без NullPointerException, поскольку Objects.toString (Object) прекрасно обрабатывает этот сценарий и не претендует на то, чтобы быть методом «массива» (на самом деле это не так. не очень помогает с массивами).
Разница в параметрах, ожидаемая каждой реализацией, которая обеспечивает представление String
предоставленного массива, приводит к мотивации, которая, как я считаю, является наиболее убедительной для выбора стороннего предоставленного библиотекой ArrayUtils.toString(Object)
Arrays.toString(Object[])
встроенного Arrays.toString(Object[])
, но для одного конкретного случая это существенное преимущество: многомерные массивы Java. Arrays.toString(Object[])
JDK предназначен только для одномерного массива Java. Однако Apache Commons Lang ArrayUtils.toString(Object)
прекрасно поддерживает представление единственного представления String
даже для многомерных массивов Java. Его Javadoc уровня методов рекламирует это преимущество: «Многомерные массивы обрабатываются правильно, включая многомерные примитивные массивы». Чтобы проиллюстрировать различия в выводе этих методов для многомерного массива, я буду использовать этот нелепо надуманный пример:
1
2
3
|
/** Two-dimensional array of {@code String}s used in demonstrations. */ private static final String[][] doubleDimStrings = {{ "Dustin" }, { "Inspired" , "Actual" , "Events" }}; |
Результат передачи этого двумерного массива String
s соответствующим методам показан в следующей таблице.
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}} |
Только что показанная таблица демонстрирует, что Arrays.toString()
JDK не особенно полезен, когда массив Java имеет более одного измерения. ArrayUtils.toString(Object)
Apache Commons Lang может представить красивое одиночное String
представление даже многомерного массива.
Я намеренно избежал сравнения двух альтернатив, описанных в этом посте, с точки зрения производительности, потому что я редко обнаруживал разницу в производительности этих методов в моей повседневной работе. Однако, если эта функциональность необходима в случае, когда отсчитывается каждая миллисекунда, то, возможно, стоит попробовать каждый в реалистичных сценариях выбрать тот, который работает лучше всего. Моя интуиция говорит мне, что реализация JDK в целом будет работать лучше (особенно если работать с массивами примитивов и иметь возможность использовать один из перегруженных методов массива toString (), предназначенных для примитивов), но моя интуиция раньше была неправильной, когда дело доходит до вопросы производительности.
Следующая таблица суммирует обсуждение моего поста о характеристиках ArrayUtils.toString (Object) Apache Commons Lang и Arrays.toString (Object []) JDK (JDK 10 ) .
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" |
"{}" |
Пустой одномерный массив | "[]" |
"{}" |
В этом посте рассматриваются некоторые возможные мотивы выбора стороннего Apache Commons Lang ArrayUtils.toString (Object) вместо встроенного в JDK Arrays.toString (Object []) для генерации одиночных String
представлений массивов. Я нахожу наиболее очевидную ситуацию, когда выбор именно этой сторонней библиотеки вместо встроенной альтернативы предназначен для многомерных массивов.
Опубликовано на Java Code Geeks с разрешения Дастина Маркса, партнера нашей программы JCG . См. Оригинальную статью здесь: Apace Commons ArrayUtils.toString (Object) против JDK Arrays.toString (Object)
Мнения, высказанные участниками Java Code Geeks, являются их собственными. |