2013-05-15 8 views
12

私は最近、Javaの照合がスペースを無視するように見えるようになりました。Javaの照合はスペースを無視します

私は、次の用語のリストを持っている:

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

上記の順番はすなわちACOUNTにスペースを取ってドイツのために所望の順序を反映しています。 はしかし、

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

を使用してJava照合は私に次の順序与える:スペースは考慮されませんので、上記の結果は、私が期待しているもの、実際にはない

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

を(上記の場合のように見えますここに:Wikipedia Alphabetical order)。

これはJavaの照合がこのようなケースでは使用できないということですか、ここで何か間違っていますか? Java照合領域を認識させる方法はありますか?

私は任意のコメントや推奨事項がうれしいです。

+0

も参照してください:http://stackoverflow.com/questions/15230339/collat​​or-compares-strings-weird – assylias

答えて

7

照合をカスタマイズすることができます。 this answerで説明されているように、ソースコードを見て、Collat​​or for Germanのロケールがどのように構築されているか調べてみてください。

あなたのニーズに合わせて調整してください。 tutorialは出発点です。しかし、すべての作業を行う必要はありません、他の誰かがすでにそれを行っています:このblog post dealing with the exact same problem for Czechを参照してください。

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

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

これはちょうど、下線のルールの前に空白文字のためのルールを追加します。

私はこれを個人的にテストしていません。

+1

あなたの答えと役に立つリンクをありがとう 大きな問題は、ユーザーのロケールによって照合されるはずのWebベースのアプリケーションで、潜在的に多くのロケールを強化する必要があることです。 – jhasenbe

+0

それであなたはあなた自身で書くべきです:下の私の提案が助けることができるかどうかを確認してください – JonesV

+0

@jhasenbeはい、満足できません。同じようなルールを使って同じロケールで同じ変更を行うために何かをハックする可能性がありますが、ハック –

0

何らかの理由でロケールを変更できない場合は、自分ですべてを書くことを提案します。このコードは完全ではないと動作しませんが、ここではいくつかのアイデアは、以下のとおりです。

  • 代わりに文字列のリストを有していると、独自のオブジェクトを作成し、同等の実装:

    public class myString implements Comparable<myString> { 
        private String name; 
    
        public myString(String name) { 
         this.name = name; 
        } 
    } 
    
  • 次にあなたがします

    :今すぐトリッキー部分が来る

    public int compareTo(myString compareMyString) { 
        ... 
    } 
    
  • (例hereを参照)を実装する必要があります

    • 文字列を比較するには、文字列を分割する必要があります(結果的に文字列の配列になります)。たとえば、

      // Original String 
      "Barr Burt" 
      
      // Splitted String 
      [0]: "Barr" 
      [1]: "Burt" 
      
    • 単語を順番に比較する必要があります。このようなことをする関数を作成します(これは疑似コードです: "this.words [i]"は "this"の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); 
      } 
      
関連する問題