Мне нужен Iterator<Character>
от объекта String
. Есть ли какая-либо доступная функция в Java, которая предоставляет мне это или мне нужно закодировать свой собственный?
Java: как получить Iterator <Character> из String
Ответ 1
Один из вариантов заключается в использовании Guava:
ImmutableList<Character> chars = Lists.charactersOf(someString);
UnmodifiableListIterator<Character> iter = chars.listIterator();
Это создает неизменный список символов, который поддерживается данной строкой (без копирования).
Если вы в конечном итоге сделаете это сами, я бы рекомендовал не подвергать класс реализации для Iterator
, как это делает ряд других примеров. Я бы рекомендовал вместо этого сделать свой собственный класс утилиты и подвергнуть статическому методу factory:
public static Iterator<Character> stringIterator(final String string) {
// Ensure the error is found as soon as possible.
if (string == null)
throw new NullPointerException();
return new Iterator<Character>() {
private int index = 0;
public boolean hasNext() {
return index < string.length();
}
public Character next() {
/*
* Throw NoSuchElementException as defined by the Iterator contract,
* not IndexOutOfBoundsException.
*/
if (!hasNext())
throw new NoSuchElementException();
return string.charAt(index++);
}
public void remove() {
throw new UnsupportedOperationException();
}
};
}
Ответ 2
Он не существует, но его тривиально реализовать:
class CharacterIterator implements Iterator<Character> {
private final String str;
private int pos = 0;
public CharacterIterator(String str) {
this.str = str;
}
public boolean hasNext() {
return pos < str.length();
}
public Character next() {
return str.charAt(pos++);
}
public void remove() {
throw new UnsupportedOperationException();
}
}
Реализация, вероятно, такая же эффективная, как и она.
Ответ 3
for (char c : myString.toCharArray()) {
}
Ответ 4
Кража от кого-то другого в другом ответе, это, вероятно, лучшая прямая реализация (если вы не собираетесь использовать guava).
/**
* @param string
* @return list of characters in the string
*/
public static List<Character> characters(final String string) {
return new AbstractList<Character>() {
@Override
public Character get(int index) {
return string.charAt(index);
}
@Override
public int size() {
return string.length();
}
};
}
Ответ 5
CharacterIterator it = new StringCharacterIterator("abcd");
// Iterate over the characters in the forward direction
for (char ch=it.first(); ch != CharacterIterator.DONE; ch=it.next())
// Iterate over the characters in the backward direction
for (char ch=it.last(); ch != CharacterIterator.DONE; ch=it.previous())
Ответ 6
Короткий ответ: Нет, вам нужно его закодировать.
Длинный ответ: Список и набор имеют метод получения Iterator (есть несколько других классов коллекции, но, вероятно, не то, что вы ищете). Интерфейсы List и Set являются частью Коллекции Framework, которые разрешают добавлять/удалять/итерировать объекты, такие как Character или Integer (не примитивы типа char или int). Существует функция Java 1.5, называемая auto-boxing, которая скроет этот примитив с Object Object, но я не рекомендую его, и он не будет предоставить то, что вы хотите в этом случае.
Альтернативой было бы обернуть String в собственный класс, который
implements Iterator<Character>
но это может быть больше работы, чем это стоит.
Вот фрагмент кода для выполнения того, что вы хотите:
String s = "";
List<Character> list = new ArrayList<Character>(s.length());
for (int i = 0; i < s.length(); i++) {
// note that Character.valueOf() is preferred to new Character()
// you can omit the Character.valueOf() method
// and Java 1.5+ will auto-box the primitive into an Object
list.add(Character.valueOf(s.charAt(i)));
}
Iterator<Character> iterator = list.iterator();
Ответ 7
Нет прямого пути. Не сложно скопировать код:
public static Iterator<Character> gimmeIterator(final String x) {
Iterator<Character> it = new Iterator<Character>() {
String str = x == null ? "" : x;
int pos = -1; // last read
public boolean hasNext() { return(pos+1 < str.length()); }
public Character next() { pos++; return str.charAt(pos); }
public void remove() {
throw new UnsupportedOperationException("remove unsupported for this iterator");
}
};
return it;
}
Ответ 8
Это можно сделать с небольшой помощью Apache Commons Lang (если вы не хотите использовать Guava и хотите иметь true java.util.Iterator
.
private static Iterator<Character> iterator(String string) {
return Arrays.asList(ArrayUtils.toObject(string.toCharArray())).iterator();
}
Ответ 9
Не уверен, есть ли более прямой путь, но вы можете сделать что-то вроде:
Arrays.asList(string.toCharArray()).iterator();
Забастовкa >
Поцарапайте это; Arrays.asList не делает то, что я, кажется, помню, как он это делает.
Изменить 2: похоже, что последний раз работал таким образом в 1.4
Ответ 10
Iterator перебирать коллекцию или все, что ее реализует. Класс String реализует этот интерфейс. Поэтому нет прямого пути.
Чтобы перебрать строку, вам нужно сначала создать массив char, а затем из этого массива char a Collection.
Ответ 11
С помощью java 8 или new вы можете использовать средство потока. С помощью метода chars()
вы можете получить доступ к IntStream
. IntStream
поддерживает метод iterator()
, который возвращает итератор OfInt
. OfInt
реализует Iterator<Integer>
.
String str = "foobar";
OfInt ofit = str.chars().iterator();
Iterator<Integer> it = ofit;
Это не идеальный ответ, так как вы просили Iterator <Character> .
Btw: С помощью str.codePoints() вы также можете получить доступ к кодовой точке IntStream.
Ответ 12
Это кажется грязным, но вы можете использовать Scanner с пустым разделителем строк:
Scanner scanner = new java.util.Scanner(myInput).useDelimiter("");
Сканер реализует Iterator
, поэтому scanner
теперь является Iterator
строк длиной-1, который близок.
Чтобы продолжить (очень?) грязный, в Java 8 вы можете сделать это, чтобы лаконично перебирать символы:
for (String s: (Iterable<String>)() -> scanner) {
char c = s.charAt(0);
System.out.println(c);
}
Подробнее о том, почему работает () -> scanner
(и почему это может быть опасно, хотя и не в этом случае), см. Объясните, как эту лямбду можно присвоить Iterable.