Java:如何从String </character>获取Iterator <character>

时间:2010-10-13 15:06:31

标签: java string iterator

我需要来自Iterator<Character>对象的String。 Java中是否有任何可用的功能可以为我提供这个功能,还是我必须自己编写代码?

12 个答案:

答案 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()方法,您可以访问IntStreamIntStream支持返回iterator()迭代器的方法OfIntOfInt实施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