2017-11-17 7 views
1

ArrayListを昇順でソートする際に問題が発生しています。ComparatorとCollat​​or Of Collectionクラスを使用しています。ヘルプは非常に感謝しています。アルゴリズムによって計算Javaのコンパレータを使用したArrayListの並べ替え

昇順順序は次のとおりです。

[AutomationRejectNotification|,AutomationRejectNotification1011, AutomationRejectNotification1021,AutomationTestNotification1, AutomationTestNotification100,AutomationTestNotification2,testDisplay Template, Testing Chrome, Testing Field, Test Notfication, testnotif, Test Notification #1] 

期待昇順ソート順序は次のとおりです。

[AutomationRejectNotification1011, AutomationRejectNotification1021, AutomationRejectNotification|,AutomationTestNotification1, AutomationTestNotification2,AutomationTestNotification100,Test Notfication, Test Notification #1, testDisplay Template, Testing Chrome, Testing Field, testnotif] 

Javaコード:

public static void listSort(List<String> o1, boolean order) { 
     final Pattern p = Pattern.compile("^\\d+"); 
     Comparator<String> c = new Comparator<String>() { 
      public int compare(String object1, String object2) { 
       Collator collator = Collator.getInstance(Locale.US); 
       Matcher m = p.matcher(object1); 

       if (!m.find()) { 
        return collator.compare(object1, object2); 
       } else { 
        Long number2 = null; 
        Long number1 = Long.parseLong(m.group()); 

        m = p.matcher(object2); 
        if (!m.find()) { 
         return collator.compare(object1, object2); 
        } else { 

         number2 = Long.parseLong(m.group()); 

         int comparison = number1.compareTo(number2); 
         if (comparison != 0) { 
          return comparison; 
         } else { 
          return collator.compare(object1, object2); 
         } 
        } 
       } 


      } 
     }; 
     o1.sort(c); 
+0

これはCollat​​orが動作する方法です。この記事を見てください:https://documentation.progress.com/output/Corticon/5.3.2/suite_prototype/rfi1341263753418.html – WinterN

+0

いいえ、@WinterN、それはCollat​​orの仕組みではありません。特に、米国ロケールでは、 '|'文字は10進数字の後ろに来るので、 '' AutomationRejectNotification | ""はOPで報告された順序に反して、 "" AutomationRejectNotification1011 "'の後に照合することに注意してください。 –

+0

@kaps - 予想される出力の例を1つ提供するのではなく、任意の入力リストに適用されるソート規則を指定できますか? –

答えて

2

あなたComparatorが正常の契約を実装していませんComparatorインターフェイスです。したがって、すべてのベットはf。 compare()メソッドには、次のプロパティがすべて含まれている必要があります。

sgn(compare(x, y)) == -sgn(compare(y, x))すべてのxとy。

((compare(x, y)>0) && (compare(y, z)>0))compare(x, z)>0を意味します。

compare(x, y)==0すべてのzのためのそのsgn(compare(x, z))==sgn(compare(y, z))ことを意味します。比較される両方の文字列が空でない10進数シーケンスを含む場合、少なくとも1つの文字列は、次に任意の数字なしであるかどうかを介して比較一方

API docs

、あなたは、数字によってのみ比較します照合器。その結果は次のようになります。

compare("z1", "y") > 0 

compare("y", "x3") > 0 

compare("z1", "x3") < 0 

これは第2の必須プロパティ(過渡性)に適合しません。

おそらくあなたがしたいことは、最初の基準として最長の先頭のdigitless部分文字列を比較し、末尾の数字があればそれを比較することによって任意の結び目を破ることです。あなたが提示され、予想される順序と一致するであろう

public static void listSort(List<String> o1, boolean order) { 
    final Pattern p = Pattern.compile("([^0-9]*)([0-9]+)?"); 
    final Collator collator = Collator.getInstance(Locale.US); 
    Comparator<String> c = new Comparator<String>() { 
     public int compare(String object1, String object2) { 
      Matcher m1 = p.matcher(object1); 
      Matcher m2 = p.matcher(object2); 

      if (!m1.lookingAt() || !m2.lookingAt()) { 
       assert false : "Should never happen"; 
      } 

      int result = collator.compare(m1.group(1), m2.group(1)); 

      if (result == 0) { 
       String digits1 = m1.group(2); 
       String digits2 = m2.group(2); 

       if (digits1 != null && digits2 != null) { 
        Long number1 = Long.valueOf(digits1); 
        Long number2 = Long.valueOf(digits2); 
        result = number1.compareTo(number2); 
       } else if (digits1 != null) { 
        result = 1; 
       } else if (digits2 != null) { 
        result = -1; 
       } 
      } 

      return result; 
     } 
    }; 
    o1.sort(c); 
} 

をするだけでなく、それらの特定の要素に同じ結果を生成する他の順序付けスキームがあります。それは次のようになります。

+0

こんにちは@ジョンボリンジャー:あなたの入力をありがとう。エラー:.java.lang.NumberFormatExceptionをスローします。入力文字列: "Test-AutomationTestNotification" at java.lang.NumberFormatException.forInputString(NumberFormatException。java:65) at java.lang.Long.parseLong(Long.java:589) at java.lang.Long.valueOf(Long.java:803) – kaps

+0

私はいくつかのテストデータにすべての特殊文字を持っています。テストモチーフ#1、テストMotifcaiotn @ 34 – kaps

+0

@kaps、私はあなた自身が問題を解決することができたと思うが、それにもかかわらず、私はそれを修正した。 –

関連する問題