Почему не делает Строкового класса в Повторяемой реализации Java?

Много реализаций классов платформы Java Iterable, однако String не делает. Имеет смысл выполнять итерации по символам в a String, так же, как можно выполнить итерации по объектам в эквидистантной антенной решетке.

Есть ли причина почему String не реализует Iterable?

45
задан polygenelubricants 5 May 2010 в 11:28
поделиться

7 ответов

На самом деле хорошего ответа нет. Итератор в Java применяется конкретно к коллекции дискретных элементов (объектов). Можно подумать, что String, который реализует CharSequence, должен быть "коллекцией" дискретных символов. Вместо этого она рассматривается как единое целое, состоящее из символов.

В Java кажется, что итераторы действительно применяются только к коллекциям, но не к строке. Нет никаких причин, почему это так (насколько я могу судить - вам, вероятно, придется поговорить с Гослингом или авторами API); похоже, что это условность или дизайнерское решение. Действительно, ничто не мешает CharSequence реализовать Iterable.

Учитывая это, вы можете перебирать символы в строке следующим образом:

for (int i = 0; i < str.length(); i++) {
  System.out.println(str.charAt(i));
}

Or:

for(char c : str.toCharArray()) {
  System.out.println(c);
}

Or:

"Java 8".chars().forEach(System.out::println);

Также обратите внимание, что вы не можете изменить символ строки на месте, поскольку строки неизменяемы. Мутабельным компаньоном строки является StringBuilder (или более старый StringBuffer).

EDIT

Чтобы уточнить, основываясь на комментариях к этому ответу. Я пытаюсь объяснить возможное обоснование того, почему не существует итератора для String. Я не пытаюсь сказать, что это невозможно; действительно, я думаю, что было бы логично для CharSequence реализовать Iterable.

String предоставляет CharSequence, который, хотя бы концептуально, отличается от String. Строка String обычно рассматривается как единое целое, тогда как CharSequence является именно этим: последовательностью символов. Имеет смысл иметь итератор на последовательности символов (т.е. на CharSequence), но не просто на самой String.

Как справедливо заметил Foxfire в комментариях, String реализует интерфейс CharSequence, поэтому с точки зрения типов, String является CharSequence. Семантически, мне кажется, что это две разные вещи - возможно, я педантичен, но когда я думаю о String, я обычно думаю о ней как о едином объекте, который состоит из символов. Рассмотрим разницу между последовательностью цифр 1, 2, 3, 4 и числом 1234. Теперь рассмотрим разницу между строкой abcd и последовательностью символов a, b, c, d. Я пытаюсь указать на эту разницу.

На мой взгляд, спрашивать, почему у String нет итератора, все равно что спрашивать, почему у Integer нет итератора, чтобы можно было перебирать отдельные цифры.

25
ответ дан 26 November 2019 в 21:27
поделиться

Причина проста: строковый класс намного старше, чем Iterable.

И, очевидно, никто никогда не хотел добавлять интерфейс к String (что несколько странно, потому что он действительно реализует CharSequence, основанный на точно такой же идее).

Однако это было бы несколько несовершенным, потому что Iterable возвращает объект . Так что нужно было бы обернуть каждый возвращенный Char.

Редактировать: Так же, как сравнение: .Net поддерживает перечисление в String, однако в .Net Iterable также работает с собственными типами, поэтому нет необходимости в переносе, как это требовалось бы в Java.

13
ответ дан 26 November 2019 в 21:27
поделиться

Если вы действительно заинтересованы в итерации, вот:

String str = "StackOverflow";

for (char c: str.toCharArray()){
     //here you go
}
0
ответ дан 26 November 2019 в 21:27
поделиться

Мой коллега Джош Блох очень хочет добавить эту функцию в Java 7:

for (char c: aString) {.. .}

и

for (int codePoint: aString) {...}

Это был бы самый простой способ перебрать символы и логические символы (кодовые точки) в цикле. Это не потребовало бы реализации String реализации Iterable , что привело бы к блокировке.

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

10
ответ дан 26 November 2019 в 21:27
поделиться

Iterable чего? Iterable имеет наибольший смысл, если каждый элемент представляет кодовую точку Unicode. Даже Iterable будет медленным и бессмысленным, если у нас есть toCharArray .

-1
ответ дан 26 November 2019 в 21:27
поделиться

Они просто забыли это сделать.

4
ответ дан 26 November 2019 в 21:27
поделиться

Одна из основных причин, по которой String реализует Iterable, - это включение простого цикла for (each), как упоминалось выше. Итак, причиной того, что String не реализует Iterable, может быть внутренняя неэффективность наивной реализации, поскольку она требует упаковки результата. Однако, если реализация итогового Iterator (возвращаемого String.iterator ()) является окончательной, компилятор может обработать его в особом случае и сгенерировать байт-код, свободный от упаковки / распаковки.

2
ответ дан 26 November 2019 в 21:27
поделиться
Другие вопросы по тегам:

Похожие вопросы: