web-dev-qa-db-ja.com

Java StringTokenizer.nextToken()は空のフィールドをスキップします

区切り文字としてタブ(/ t)を使用していますが、データに空のフィールドがいくつかあることを知っています。例:

one->two->->three

ここで、->はタブと同じです。ご覧のとおり、空のフィールドはまだタブで正しく囲まれています。データはループを使用して収集されます:

 while ((strLine = br.readLine()) != null) {
    StringTokenizer st = new StringTokenizer(strLine, "\t");
    String test = st.nextToken();
    ...
    }

しかし、Javaはこの「空の文字列」を無視し、フィールドをスキップします。

この動作を回避し、とにかく空のフィールドを読み取るようにJavaを強制する方法はありますか?

15
FireFox

どうもありがとうございました。最初のコメントのために私は解決策を見つけることができました:はい、あなたは正しいです、あなたの参照に感謝します:

 Scanner s = new Scanner(new File("data.txt"));
 while (s.hasNextLine()) {
      String line = s.nextLine();
      String[] items= line.split("\t", -1);
      System.out.println(items[5]);
      //System.out.println(Arrays.toString(cols));
 }
9
FireFox

SunのバグデータベースのRFE このStringTokenizerの問題についてステータス_Will not fix_があります。

このRFEの評価は、次のように述べています。

_Java.util.regex_に_1.4.0_パッケージが追加されたことで、基本的にStringTokenizerの必要性がなくなりました。互換性の理由からクラスを削除しません。しかし、regexは単に必要なものを提供します。

そして、 String#split(String) メソッドの使用を提案します。

16
npe

Apache Commons StringUtils.splitPreserveAllTokens() を使用できます。それはまさにあなたが必要とすることをします。

4
adranale

Guava's Splitter を使用します。これは、すべての大きな正規表現機構を必要とせず、Stringのsplit()メソッドよりも動作が優れています。

Iterable<String> parts = Splitter.on('\t').split(string);
1
JB Nizet

Java Doc http://docs.Oracle.com/javase/6/docs/api/Java/util/StringTokenizer.html あなたに見られるようにコンストラクタpublic StringTokenizer(String str, String delim, boolean returnDelims)returnDelimstrueとともに使用できます

したがって、各区切り文字を個別の文字列として返します。

編集:

しないでください @npeはすでに入力されているため、この方法を使用してください。StringTokenizerはこれ以上使用しないでください。 JavaDocを参照してください。

StringTokenizerはレガシークラスであり、互換性の理由で保持されます使用されますが新しいコードでは推奨されません。この機能をお探しの方は、代わりにsplitまたはJava.util.regexパッケージのStringメソッドを使用することをお勧めします。

0
itshorty