java - 程序中的 StringTokenizer 与 split()

标签 java string stringtokenizer stringbuffer

我必须将句子中每个单词的第一个字符大写。第一个单词的第一个字符是大写的,句子只能以句号或问号结束。然后我必须计算句子中每个单词的所有元音和辅音。

这是我的代码:

import java.io.*;
import java.util.*;
class ISC_Prac_2015
{
String s;
ISC_Prac_2015()
{
    s="";
}

void input()throws IOException
{
    System.out.println("Enter a sentence :");
    BufferedReader buf=new BufferedReader(new InputStreamReader(System.in));
    s=buf.readLine();
    if(!((s.charAt(s.length()-1)=='.'||s.charAt(s.length()-1)=='?')))
    {
        System.out.println("Invalid input.");
        System.exit(0);
    }
}

char changeToUpper(char c)
{
    return Character.toUpperCase(c);
}

boolean isVowel(char c)
{
    if(c=='a'||c=='e'||c=='i'||c=='o'||c=='u'||c=='A'||c=='E'||c=='I'||c=='O'||c=='U')
        return true;
    else
        return false;
}

void main()throws IOException
{
    input();
    String s2=s.substring(0,s.length()-1);
    StringBuffer s3=new StringBuffer(s2);
    for(int x=0;x<s3.length()-1;x++)
        if(s3.charAt(x)==' ')
            s3.setCharAt(x+1,changeToUpper(s3.charAt(x+1)));
    String s4=s3.toString();
    System.out.println("\n"+s4);
    StringTokenizer st=new StringTokenizer(s4);
    String a[]=new String[st.countTokens()];
    for(int x=0;x<st.countTokens();x++)
    a[x]=st.nextToken();
    /*replace the 4 lines above with String a[]=s4.split(" ");
      and the program works, but why?*/
    System.out.println("Word\t\t"+"Vowels\t\t"+"Consonants");
    int vowel=0,consonant=0;
    for(int x=0;x<a.length;x++)
    {
        for(int y=0;y<a[x].length();y++)
            if(isVowel(a[x].charAt(y)))
                vowel++;
            else
                consonant++;
        if(a[x].length()<8)
            System.out.println(a[x]+"\t\t"+vowel+"\t\t"+consonant);
        else if(a[x].length()>=8&&a[x].length()<16)
            System.out.println(a[x]+"\t"+vowel+"\t\t"+consonant);
        else
            System.out.println(a[x]+vowel+"\t\t"+consonant);
    }
}
}

类(class)名称很奇特,因为这是我计算机考试中的一道题。

该程序可以正常运行,但出于某种原因,我在 main() 的内部 for 循环中遇到了一个 NullPointerException。但是,正如我在程序中评论的那样,如果我使用 split("") 函数,程序将正常运行。

但是为什么? StringTokenizer 不是在做与 split("") 相同的事情吗?

最佳答案

StringTokenizer 的 countTokens 方法的 API 文档说:

Calculates the number of times that this tokenizer's nextToken method can be called before it generates an exception. The current position is not advanced.

您在 for 循环中调用它,就好像您希望它保持不变一样,但每次您前进另一个标记时它都会减少 1。所以如果你的字符串有 4 个标记,你只会得到前两个。您的字符串数组中剩下空值。

您可以使用调试器或将 printlns 添加到您的代码中来检查此类问题。

有几种解决方案。您可以修复代码以预先存储 token 计数,而不是继续调用该方法。更好的是,hasMoreTokens 方法正是针对这种情况,使用它。或者您可以遵循文档中的建议:

StringTokenizer is a legacy class that is retained for compatibility reasons although its use is discouraged in new code. It is recommended that anyone seeking this functionality use the split method of String or the java.util.regex package instead.

查看文档。当某些事情的行为与您假设的不一样时,请仔细检查文档以查看您的假设是否真的有效。

关于java - 程序中的 StringTokenizer 与 split(),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/28537320/

相关文章:

c - C 中未确定的字符串或字符常量

java - 未发现 @Retryable 方法(也是 @Scheduled)的 @Recover 注释方法

java - HTTP/1.1 400 对具有基本身份验证的 httpGet 的错误请求

java - 如何为下载管理器编写测试驱动的 Java 类?

python - 如果 foo 中不存在键,则忽略 str.format(**foo)

C# Stringbuilder 在添加大量文本时损坏内容

java - StringTokenizer错误: incompatible types: Object cannot be converted to String

java - 无法使用逗号和字符串标记器对数字求和

java - 如何将 StringTokenizer 结果带到 Java 中的 ArrayList?

java - 如何从双卡手机 Android 获取运营商名称?