17

私は最近、Java Collat​​ion がスペースを無視しているように見えることに気付きました。

次の用語のリストがあります。

Amman Jost 
Ammann Heinrich 
Ammanner Josef 
Bär Walter 
Bare Werner 
Barr Burt 
Barraud Maurice

上記の順序は、ドイツの望ましい順序、つまりスペースを考慮した順序を反映しています。ただし、Java Collat​​ion を使用

Collator collator = Collator.getInstance(Locale.GERMANY);
Collections.sort(values, collator);

私に次の順序を与えます:

Amman Jost
Ammanner Josef
Ammann Heinrich
Bare Werner
Barraud Maurice
Barr Burt
Bär Walter

スペースが考慮されていないため、上記の結果は実際には私が期待したものではありません (ここで説明されているケースのように見えます:ウィキペディアのアルファベット順)。

これは、Java Collat​​ion がそのようなユースケースでは使用できないということですか、それともここで何か間違ったことをしているのですか? Java照合スペースを認識させる方法はありますか?

コメントやアドバイスをいただければ幸いです。

4

2 に答える 2

10

照合をカスタマイズできます。この回答で説明されているように、ソース コードを見て、ドイツ語ロケールの Collat​​or がどのように構築されているかを確認してください。

次に、ニーズに合わせて調整します。チュートリアルは出発点を提供します。しかし、すべての作業を行う必要はありません。他の誰かが既に行っています。チェコ語のまったく同じ問題を扱っているこのブログ投稿を参照してください。

上記のリンクのソリューションの本質は次のとおりです。

String rules = ((RuleBasedCollator) Collator.getInstance(Locale.GERMANY)).getRules();
RuleBasedCollator correctedCollator 
    = new RuleBasedCollator(rules.replaceAll("<'\u005f'", "<' '<'\u005f'"));

これにより、アンダースコアのルールの直前にスペース文字のルールが追加されます。

私はこれを個人的にテストしていないことを告白します。

于 2013-05-15T14:34:59.603 に答える
-1

何らかの理由でロケールを変更できない場合は、すべてを自分で作成することをお勧めします。このコードは完全ではなく、機能しませんが、いくつかのアイデアを次に示します。

  • 文字列のリストを持つ代わりに、独自のオブジェクトを作成して、同等のものを実装します。

    public class myString implements Comparable<myString> {
        private String name;
    
        public myString(String name) {
           this.name = name;
        }
    }
    
  • 次に、実装する必要があります (こちらの例を参照してください) 。

    public int compareTo(myString compareMyString) {
        ...
    }
    
  • ここで、よりトリッキーな部分が来ます:

    • 文字列を比較するには、それらを分割する必要があります (これにより、文字列の配列が生成されます)。例えば:

      // Original String
      "Barr Burt"
      
      // Splitted String
      [0]: "Barr"
      [1]: "Burt"
      
    • 単語を次々と比較する必要があります。このような関数を作成します (これは疑似コードです: "this.words[i]" は "this.name" の i 番目の単語を呼び出します)

      public int compareWords(myString compareMyString, int i)
      {
          if (this.words[i] < compareMyString.words[i])
              return -1; // "this" should come before "compareMyString"
      
          if (this.words[i] > compareMyString.words[i])
              return 1; // "this" should come after "compareMyString"
      
          if (this.words[i] == compareMyString.words[i])
              return compareWords(i+1);
      }
      
    • そしてcompareTo

      public int compareTo(myString compareMyString) {
          return compareWords(compareMyString, 0);
      }
      
于 2013-05-16T08:00:14.490 に答える