我需要来自Iterator<Character>
对象的String
。 Java中是否有任何可用的功能可以为我提供这个功能,还是我必须自己编写代码?
答案 0 :(得分:30)
一种选择是使用Guava:
ImmutableList<Character> chars = Lists.charactersOf(someString);
UnmodifiableListIterator<Character> iter = chars.listIterator();
这会产生一个由给定字符串支持的不可变字符列表(不涉及复制)。
如果您最终自己这样做,我建议不要像其他一些示例那样公开Iterator
的实现类。我建议改为创建自己的实用程序类并公开静态工厂方法:
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();
}
};
}
答案 1 :(得分:18)
它不存在,但实施起来很简单:
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();
}
}
实施可能和它一样有效。
答案 2 :(得分:11)
for (char c : myString.toCharArray()) {
}
答案 3 :(得分:4)
在另一个答案中从其他人那里窃取,这可能是最好的直接实现(如果你不打算使用番石榴)。
/**
* @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();
}
};
}
答案 4 :(得分:2)
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())
答案 5 :(得分:2)
简短回答: 不,你必须编码。
答案很长: List和Set都有一个获取Iterator的方法(还有一些其他的集合类,但可能不是你想要的)。 List和Set接口是Collections Framework的一部分,它只允许添加/删除/迭代像Character或Integer这样的对象(不是像char或int这样的原语)。 Java 1.5 called auto-boxing中有一个功能会将此原语隐藏到对象转换中,但我不推荐它,在这种情况下它不会提供您想要的内容。
另一种方法是将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();
答案 6 :(得分:1)
没有直接的方法。不过难以编码:
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;
}
答案 7 :(得分:1)
这可以通过Apache Commons Lang的一些帮助来完成(如果你不想使用Guava,并且想要一个真正的java.util.Iterator
。
private static Iterator<Character> iterator(String string) {
return Arrays.asList(ArrayUtils.toObject(string.toCharArray())).iterator();
}
答案 8 :(得分:0)
不确定是否有更直接的方式,但你可以做类似的事情;
Arrays.asList(string.toCharArray()).iterator();
击> <击> 撞击>
抓一点; Arrays.asList没有做我似乎记得它做的事情。
编辑2:似乎它最后在1.4中以这种方式工作
答案 9 :(得分:0)
Iterator迭代集合或其他任何实现它的集合。 String类没有实现此接口。所以没有直接的方法。
要遍历字符串,您必须首先从中创建一个char数组,然后从此char数组中创建一个Collection。
答案 10 :(得分:0)
使用java 8或更新版本,您可以使用流设施。使用chars()
方法,您可以访问IntStream
。 IntStream
支持返回iterator()
迭代器的方法OfInt
。 OfInt
实施Iterator<Integer>
。
String str = "foobar";
OfInt ofit = str.chars().iterator();
Iterator<Integer> it = ofit;
这不是一个完美的答案,因为你要求Iterator&lt; Character&gt;。
Btw:使用str.codePoints(),您还可以访问代码点IntStream。
答案 11 :(得分:0)
这感觉很脏,但你可以使用带有空字符串分隔符的Scanner:
Scanner scanner = new java.util.Scanner(myInput).useDelimiter("");
扫描程序实现Iterator
,因此scanner
现在是Iterator
长度为1的字符串,它们已接近。
要继续使用(非常?)脏,在Java 8中,您可以通过chars简洁地迭代:
for (String s: (Iterable<String>)() -> scanner) {
char c = s.charAt(0);
System.out.println(c);
}
有关() -> scanner
工作原因的详细信息(以及为什么它可能有危险,但不在此用例中),请参阅Explain how this lambda can be assigned to an Iterable。