2017-11-17 15 views
1

ArrayList를 오름차순으로 정렬하는 데 문제가 있습니다. Comparator와 Collator Of Collection 클래스를 사용하고 있습니다. 예상되는 정렬 순서를 어떻게 잡을 수 있습니까? 도움을 많이 주시면 감사하겠습니다. 알고리즘에 의해 계산Java에서 Comparator를 사용하여 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] 

자바 코드 :

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

그건 Collator가 작동하는 방식입니다. 이 기사를 보시기 바랍니다 : https://documentation.progress.com/output/Corticon/5.3.2/suite_prototype/rfi1341263753418.html – WinterN

+0

아니요, @WinterN, Collator가 작동하는 방식이 아닙니다. 특히 미국 지역에서는 '|'문자가 10 진수 뒤 * 뒤에옵니다. 따라서 "AutomationRejectNotification |"은 "AutomationRejectNotification1011"뒤에 콜리 전되며 OP에 의해보고 된 순서와는 반대입니다. –

+0

@kaps - 예상 출력의 단일 예제를 제공하는 대신 임의의 입력 목록에 적용 할 정렬 규칙을 지정할 수 있습니까? –

답변

2

귀하의 Comparator 제대로 계약을 구현하지 않습니다 Comparator 인터페이스이므로 모든 베팅은 다음과 같습니다. 에프. 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))있다. 비교되는 두 문자열이 비어 있지 않은 진수 시퀀스를 포함하면 적어도 하나 개의 문자열이 다음 자릿수없이 경우를 통해 비교 반면

(API docs)

, 당신은 숫자에 의해 비교 콜레이터 결과는 다음과 같습니다.

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

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

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

이 두 번째 필수 속성 (transitivity)을 따르지 않습니다.

아마도 당신이 원하는 것은 가장 긴 선행 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

안녕하세요 @ 존 Bollinger : 귀하의 의견을 보내 주셔서 감사합니다. 오류 아래에 throw됩니다. .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

일부 테스트 데이터에는 모든 특수 문자가 있습니다. 즉 Test Motification # 1, Test Motifcaiotn @ 34 – kaps

+0

@kaps를 사용하면 문제를 직접 해결할 수 있다고 생각되지만 그럼에도 불구하고 해결했습니다. –