Изучите Java за 5 минут: какой самый элегантный способ распечатать массив Java?

Java

Просматривая Stack Overflow, я нашел несколько вопросов, стоящих выше Анд, таких как этот: Какой самый элегантный способ распечатать массив Java? Количество посещений 220W+ Неожиданно, что столько программистов заморачивается такой простой задачей.

Давайте рассмотрим вопрос спрашивающего:

В Java, несмотря на то, что массив является объектом, такой класс явно не определен, поэтому покрытие отсутствует.toString()возможность метода. Если мы попытаемся распечатать массив напрямую, результат будет не таким, как мы ожидали. Есть какой-то простой и доступный способ?

Если вы были обеспокоены этой проблемой или беспокоитесь, пожалуйста, следуйтеяДавай, давайте разберем этот вопрос рядом, рука об руку и найдем лучший ответ. Дуанг, Дуанг, Дуанг, сражайся с монстрами, чтобы продвинуться вперед!

01. Почему нельзя печатать напрямую

Мне любопытно, не так ли, почему я не могу использовать его напрямуюSystem.out.println()метод серии для печати массива? Давайте рассмотрим такой пример.

String [] cmowers = {"沉默","王二","一枚有趣的程序员"};
System.out.println(cmowers);

Результат, напечатанный программой:

[Ljava.lang.String;@3d075dc0

[Ljava.lang.String;Указывает имя класса массива строк, за которым следует хэш-код в шестнадцатеричном формате — такой вид результата печати слишком «очеловечен», и большинство людей говорят, что это непонятно! Почему это отображается так? Проверьте этоjava.lang.ObjectКатегорияtoString()Метод понятен.

public String toString() {
    return getClass().getName() + "@" + Integer.toHexString(hashCode());
}

PS: хотя массив явно не определен как класс, он действительно является объектом, наследующим все методы класса-предка Object.

Так почему же массив не определяет отдельный класс для его представления? Как насчет класса String?

Правдоподобное объяснение состоит в том, что Java скрывает это. Если есть Array.java, мы также можем представить, как он выглядит, он должен определить контейнер для хранения элементов массива, как и класс String.

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];
}

Но действительно ли необходимо это делать? Не будет ли лишним определить отдельный класс для массива?

02. Используйте поток

Если мы используем JDK8 и выше, мы можем использовать Stream, этот модный и модный способ обхода массива и, кстати, его вывода.

Первое:

Arrays.asList(cmowers).stream().forEach(s -> System.out.println(s));

Секунда:

Stream.of(cmowers).forEach(System.out::println);

Третий:

Arrays.stream(cmowers).forEach(System.out::println);

Результат печати показан ниже.

沉默
王二
一枚有趣的程序员

Да, эти три метода могут легко выполнять свою работу и выглядеть немного высоковатыми, ведь используются Stream и лямбда-выражения. Но на мой взгляд они не самый элегантный способ.

03. Используйте для петель

Конечно, если вам не нравится способ Stream, вы также можете использовать цикл for для вывода переменных массива между прочим или даже для каждого.

for(int i = 0; i < cmowers.length; i++){
    System.out.println(cmowers[i]);
}

for (String s : cmowers) { System.out.println(s); }

Но если вы начинающий программист, вы не можете не чувствовать, что этот метод немного низковат. Итак, каков самый элегантный способ?

04. Используйте Arrays.toString()

Arrays.toString()Вы можете преобразовать любой тип массива в строку, включая массив базового типа и массив ссылочного типа, сделать снимок экрана и пощупать его.

Класс Arrays не нуждается в представлении, верно? Вы понимаете, о чем я, но я не могу не сказать глупости: этот класс содержит различные удобные методы для работы с массивами, и его лучше называть ArrayUtil вместо Arrays.

использоватьArrays.toString()Способ вывода массива не может быть более элегантным, вроде улыбки Моны Лизы.

Ты шутишь, что ли? Приходите, посмотрите на пример кода с хорошим настроением.

String [] cmowers = {"沉默","王二","一枚有趣的程序员"};
System.out.println(Arrays.toString(cmowers));

Программа выводит результат:

[沉默, 王二, 一枚有趣的程序员]

Вау, не печатайте слишком идеально, ни больше, ни меньше! Именно то, что мы ожидали:[]указывает массив,,Точки и пробелы используются для разделения элементов.

Просто взгляните еще разtoString()Исходный код метода.

public static String toString(Object[] a) {
    if (a == null)
        return "null";
    int iMax = a.length - 1;
    if (iMax == -1)
        return "[]";
    StringBuilder b = new StringBuilder();
    b.append('[');
    for (int i = 0; ; i++) {
        b.append(String.valueOf(a[i]));
        if (i == iMax)
            return b.append(']').toString();
        b.append(", ");
    }
}

1) Если массив нулевой, то вернуть "нулевую" строку, что очень продуманно, избавляя от необходимостиNullPointerExceptionБеда.

2) Если длина массива равна 0, то вернуть строку "[]". Обратите внимание, что здесь он не используетсяa.length == 0Чтобы провести суждение о нулевом, но использоватьa.length - 1 == -1, и для следующего цикла for вi == iMaxПредзнаменование было заложено, а ресурсы потрачены совсем не зря.

3) Склейка строк в цикле for еще хитрее, и в условиях цикла for нет сужденияi < a.length, а внутри тела цикла используетсяi == iMax, какая от этого польза?

Вообще говоря, это то, что средний программист делает при конкатенации строк.

StringBuilder b = new StringBuilder();
b.append('[');
for (int i = 0; i < cmowers.length; i++) {
    b.append(cmowers[i]);
    b.append(", ");
}
b.delete(b.length()-2, b.length());
b.append(']');

Да, очень хорошо себя вел, но по сравнению сtoString()Метод записи в исходном коде метода будет затмеваться этим. Не могу не вздохнуть:Чтобы стать великим программистом, а не просто обычным программистом, самый быстрый путь — изучить исходный код Java..

05. ИспользованиеArrays.deepToString()

Если вам нужно напечатать многомерный массив кода,Arrays.toString()Вы ничего не можете с этим поделать.

String[][] deepArray = new String[][] {{"沉默", "王二"}, {"一枚有趣的程序员"}};
System.out.println(Arrays.toString(deepArray));

Результат печати показан ниже.

[[Ljava.lang.String;@7ba4f24f, [Ljava.lang.String;@3b9a45b3]

Нет нет нет, это не то, что мы ожидали, что нам делать? использоватьArrays.deepToString(), предназначенный для многомерных массивов.

String[][] deepArray = new String[][] {{"沉默", "王二"}, {"一枚有趣的程序员"}};
System.out.println(Arrays.deepToString(deepArray));

Результат печати показан ниже.

[[沉默, 王二], [一枚有趣的程序员]]

Отлично! Что касаетсяdeepToString()Исходный код , в этой статье анализировать больше не буду, если вам интересно, посмотрите сами. (Если вы хотите совершенства, вы должны его посмотреть)

06. Спасибо

Ну что же, читатели и друзья, вышеизложенное и есть все содержание этой статьи. Здесь вы видите всех лучших программистов, именно вы получаете повышение и прибавку 👍. Если вам это не нравится и вы хотите увидеть больше, я порекомендую вам еще несколько статей.

Изучите Java за 5 минут: почему бы вам не использовать примитивные типы Java?

Пять минут на изучение Java: почему возникает ArrayIndexOutOfBoundsException?

Пять минут на изучение Java: почему возникает ArrayIndexOutOfBoundsException?

Пять минут на изучение Java: передается ли Java по значению или по ссылке?

Изучите Java за 5 минут: что такое NullPointerException?

Изучите Java за пять минут: как сравнивать строки в Java?

Ежедневные операции здесь! Если вы заядлый читатель второго брата, пожалуйста, не скупитесь на рукизаглянутьиВпередСила Мингрена не говорит тайно, мне нравится ощущение, что меня балуют большие парни.

PS: Недавно ломал голову и придумал волшебное пропагандистское слово, давайте вместе прочитаем вслух:

Это официальный аккаунт "Silent King II", кто обращает внимание на тех, кто зарабатывает состояние, кто обращает внимание на тех, у кого светлая кожа..

Я не мог не рассмеяться (хахаха).