Hi,
I need a Iterator<Character>
from a String
object. Is there any available function in Java that provides me this or do I have to code my own?
Hi,
I need a Iterator<Character>
from a String
object. Is there any available function in Java that provides me this or do I have to code my own?
One option is to use Guava:
ImmutableList<Character> chars = Lists.charactersOf(someString);
UnmodifiableListIterator<Character> iter = chars.listIterator();
This produces an immutable list of characters that is backed by the given string (no copying involved).
If you end up doing this yourself, though, I would recommend not exposing the implementation class for the Iterator
as a number of other examples do. I'd recommend instead making your own utility class and exposing a static factory method:
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();
}
};
}
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())
It doesn't exist, but it's trivial to implement:
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();
}
}
The implementation is probably as efficient as it gets.
Short answer: No, you have to code it.
Long answer: List and Set both have a method for obtaining an Iterator (there are a few other collection classes, but probably not what your looking for). The List and Set interfaces are a part of the Collections Framework which only allow for adding/removing/iterating Objects like Character or Integer (not primitives like char or int). There is a feature in Java 1.5 called auto-boxing that will hide this primitive to Object conversion but I don't recommend it and it won't provide what you want in this case.
An alternative would be to wrap the String in a class of your own that
implements Iterator<Character>
but that might be more work than it is worth.
Here is a code snippet for doing what you want:
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();
No direct way. Not difficult to code, though:
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;
}