Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/string/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
在Java中迭代字符串字符的最简单/最好/最正确的方法是什么?_Java_String_Iteration_Character_Tokenize - Fatal编程技术网

在Java中迭代字符串字符的最简单/最好/最正确的方法是什么?

在Java中迭代字符串字符的最简单/最好/最正确的方法是什么?,java,string,iteration,character,tokenize,Java,String,Iteration,Character,Tokenize,StringTokenizer?将字符串转换为char[]并对其进行迭代?还有什么?我使用for循环来迭代字符串,并使用charAt()来获取每个字符来检查它。由于字符串是用数组实现的,因此charAt()方法是一个常量时间操作 String s = "...stuff..."; for (int i = 0; i < s.length(); i++){ char c = s.charAt(i); //Process char } String s=“…

StringTokenizer
?将
字符串
转换为
char[]
并对其进行迭代?还有什么?

我使用for循环来迭代字符串,并使用
charAt()
来获取每个字符来检查它。由于字符串是用数组实现的,因此
charAt()
方法是一个常量时间操作

String s = "...stuff...";

for (int i = 0; i < s.length(); i++){
    char c = s.charAt(i);        
    //Process char
}
String s=“…东西…”;
对于(int i=0;i
这就是我要做的。对我来说这似乎是最简单的


就正确性而言,我认为这里不存在这种情况。这一切都基于您的个人风格。

我不会使用
StringTokenizer
,因为它是JDK中遗留的类之一

javadoc说:

StringTokenizer
是一个遗留类 出于兼容性原因保留 尽管在纽约不鼓励使用它 代码。建议任何人 使用
字符串的拆分方法
java.util.regex
package

公共类StringDemo{
公共静态void main(字符串[]args){
String palindrome=“Dot saw I was Tod”;
int len=回文长度();
char[]tempcharray=新字符[len];
char[]charArray=新字符[len];
//将原始字符串放入字符数组中
对于(int i=0;i

将长度放入
int len
中,并将
用于
循环。

有一些专门的类用于此:

import java.text.*;

final CharacterIterator it = new StringCharacterIterator(s);
for(char c = it.first(); c != CharacterIterator.DONE; c = it.next()) {
   // process c
   ...
}
两种选择

for(int i = 0, n = s.length() ; i < n ; i++) { 
    char c = s.charAt(i); 
}

第一个可能更快,第二个可能更可读

StringTokenizer完全不适合将字符串拆分为单个字符。使用
String#split()
您可以通过使用不匹配的正则表达式轻松做到这一点,例如:

String[] theChars = str.split("|");
但是StringTokenizer不使用正则表达式,并且没有可以指定的分隔符字符串与字符之间的nothing匹配。有一个可爱的小技巧可以用来完成同样的事情:使用字符串本身作为分隔符字符串(使其中的每个字符都成为分隔符),并让它返回分隔符:

StringTokenizer st = new StringTokenizer(str, str, true);

然而,我提到这些选项只是为了排除它们。这两种技术都将原始字符串分解为一个字符串,而不是字符原语,并且在对象创建和字符串操作方面都涉及大量开销。将其与在for循环中调用charAt()进行比较,后者几乎不产生任何开销

我同意StringTokenizer在这里做得过火了。事实上,我尝试了上面的建议并花了时间

我的测试相当简单:创建一个包含大约一百万个字符的StringBuilder,将其转换为字符串,并在转换为字符数组/使用CharacterIterator一千次后使用charAt()/遍历每个字符串(当然要确保对字符串执行某些操作,以便编译器无法优化整个循环:-))

在我的2.6 GHz Powerbook(即mac:-)和JDK 1.5上的结果:

  • 测试1:字符+字符串-->3138毫秒
  • 测试2:字符串转换为数组-->9568毫秒
  • 测试3:StringBuilder字符-->3536毫秒
  • 测试4:字符计数器和字符串-->12151毫秒
由于结果明显不同,最直接的方法似乎也是最快的方法。有趣的是,StringBuilder的charAt()似乎比String的稍慢

我建议不要使用字符迭代器,因为我认为滥用“ufff”字符为“迭代结束”是一个非常糟糕的黑客攻击。在大型项目中,总是有两个人为了两个不同的目的使用同一种黑客,代码会神秘地崩溃

以下是其中一个测试:

    int count = 1000;
    ...

    System.out.println("Test 1: charAt + String");
    long t = System.currentTimeMillis();
    int sum=0;
    for (int i=0; i<count; i++) {
        int len = str.length();
        for (int j=0; j<len; j++) {
            if (str.charAt(j) == 'b')
                sum = sum + 1;
        }
    }
    t = System.currentTimeMillis()-t;
    System.out.println("result: "+ sum + " after " + t + "msec");
int count=1000;
...
System.out.println(“测试1:字符+字符串”);
long t=System.currentTimeMillis();
整数和=0;

对于(int i=0;i请注意,如果您处理的是BMP(Unicode)之外的字符,则此处描述的大多数其他技术都会出现故障,即超出u0000 uFFFF范围。这种情况很少发生,因为超出此范围的代码点主要分配给死语言。但在此之外还有一些有用的字符,例如用于数学记数法的一些代码点,以及用于中文专有名称编码的一些代码点

在这种情况下,您的代码将是:

String str = "....";
int offset = 0, strLen = str.length();
while (offset < strLen) {
  int curChar = str.codePointAt(offset);
  offset += Character.charCount(curChar);
  // do something with curChar
}
String str=“…”;
int offset=0,strLen=str.length();
while(偏移量
Character.charCount(int)
方法需要Java5+

来源:

如果您的类路径上有,那么下面是一个非常可读的替代方案。对于这种情况,Guava甚至有一个相当合理的自定义列表实现,因此这应该不会是低效的

for(char c : Lists.charactersOf(yourString)) {
    // Do whatever you want     
}
更新:正如@Alex所指出的,Java 8也可以使用。即使类型是IntStream,也可以将其映射到如下字符:

yourString.chars()
        .mapToObj(c -> Character.valueOf((char) c))
        .forEach(c -> System.out.println(c)); // Or whatever you want

如果您需要遍历
字符串的代码点(请参见此),一种更短/更可读的方法是使用Java 8中添加的方法:

for(int c : string.codePoints().toArray()){
    ...
}
或者直接使用流而不是for循环:

string.codePoints().forEach(c -> ...);
若你们想要一个字符流(尽管它是一个
IntStream
,因为并没有
CharStream
),也有一个

以上答案指出了专业的
for(int c : string.codePoints().toArray()){
    ...
}
string.codePoints().forEach(c -> ...);
    String supplementary = "Some Supplementary: This Example Code will Help you out!

import java.util.Comparator;
import java.util.HashMap;
import java.util.Map;
import java.util.TreeMap;

public class Solution {
    public static void main(String[] args) {
        HashMap<String, Integer> map = new HashMap<String, Integer>();
        map.put("a", 10);
        map.put("b", 30);
        map.put("c", 50);
        map.put("d", 40);
        map.put("e", 20);
        System.out.println(map);

        Map sortedMap = sortByValue(map);
        System.out.println(sortedMap);
    }

    public static Map sortByValue(Map unsortedMap) {
        Map sortedMap = new TreeMap(new ValueComparator(unsortedMap));
        sortedMap.putAll(unsortedMap);
        return sortedMap;
    }

}

class ValueComparator implements Comparator {
    Map map;

    public ValueComparator(Map map) {
        this.map = map;
    }

    public int compare(Object keyA, Object keyB) {
        Comparable valueA = (Comparable) map.get(keyA);
        Comparable valueB = (Comparable) map.get(keyB);
        return valueB.compareTo(valueA);
    }
}
String str = "xyz";
str.chars().forEachOrdered(i -> System.out.print((char)i));
str.codePoints().forEachOrdered(i -> System.out.print((char)i));
int tmp = 0;
String s = new String(new byte[64*1024]);
{
    long st = System.nanoTime();
    for(int i = 0, n = s.length(); i < n; i++) {
        tmp += s.charAt(i);
    }
    st = System.nanoTime() - st;
    System.out.println("1 " + st);
}

{
    long st = System.nanoTime();
    char[] ch = s.toCharArray();
    for(int i = 0, n = ch.length; i < n; i++) {
        tmp += ch[i];
    }
    st = System.nanoTime() - st;
    System.out.println("2 " + st);
}
{
    long st = System.nanoTime();
    for(char c : s.toCharArray()) {
        tmp += c;
    }
    st = System.nanoTime() - st;
    System.out.println("3 " + st);
}
System.out.println("" + tmp);
1 10349420
2 526130
3 484200
0
1 9122107
2 13486911
3 12700778
0
String s = sc.next() // assuming scanner class is defined above
for(int i=0; i<s.length; i++){
     s.charAt(i)   // This being the first way and is a constant time operation will hardly add any overhead
  }

char[] str = new char[10];
str = s.toCharArray() // this is another way of doing so and it takes O(n) amount of time for copying contents from your string class to character array