How to sort a list of objects in Java with comparator of type String?

50 Views Asked by At

The code creates Test Result objects (String name, enumeration) with a for loop and adds them to a list, and I try to sort them based on their names. The name of the objects should be something like this Test1, Test2, ...Test200. Problem is with above Test9. For example Test10 will be put between Test1 and Test2, not after Test9. Or Test20 would be between Test2 and Test3.

This is my code:

List<TestResult> testResultList = new ArrayList<>();
        
        
        for (int i = 0; i < 100; i++)
        {
            
            testResultList.add(i,  new TestResult(randomTestResultName(), TestStatus.randomEnumTestStatus())); 
               
        }

  //method1 of sorting
   testResultList.sort(Comparator.comparing(TestResult::getTestName));
        
  //method2 of sorting
        testResultList.sort((trl1, trl2)
                -> trl1.getTestName().compareTo(
                    trl2.getTestName()));

and the method that I used to create random names and enums:

private static String randomTestResultName() {
        String t1="Test";
        int randomNum = ThreadLocalRandom.current().nextInt(1, 10 + 1);
        String t2 = Integer.toString(randomNum);
        return t1+t2;
    }




 public static TestStatus randomEnumTestStatus() {
            return TestStatus.values()[new Random().nextInt(TestStatus.values().length)];
        }

UPDATE!: For anyone who has problems with it Strings with numbers at the end, use this method that you will use it as a comparator to sort it with lambda expression:

public static int compareNatural(String testResultName1, String testResultName2) {
        int lengthOfTestResultName1 = testResultName1.length();
        int lengthOfTestResultName2 = testResultName2.length();
        int browseTestResultName1 = 0;
        int browseTestResultName2 = 0;
        while (true) {
            if (browseTestResultName1 == lengthOfTestResultName1)
                return browseTestResultName2 == lengthOfTestResultName2 ? 0 : -1;
            if (browseTestResultName2 == lengthOfTestResultName2)
                return 1;
            if (testResultName1.charAt(browseTestResultName1) >= '0' && testResultName1.charAt(browseTestResultName1) <= '9' && testResultName2.charAt(browseTestResultName2) >= '0' && testResultName2.charAt(browseTestResultName2) <= '9') {
                int na = 0;
                int nb = 0;
                while (browseTestResultName1 < lengthOfTestResultName1 && testResultName1.charAt(browseTestResultName1) == '0')
                    browseTestResultName1++;
                while (browseTestResultName1 + na < lengthOfTestResultName1 && testResultName1.charAt(browseTestResultName1 + na) >= '0' && testResultName1.charAt(browseTestResultName1 + na) <= '9')
                    na++;
                while (browseTestResultName2 < lengthOfTestResultName2 && testResultName2.charAt(browseTestResultName2) == '0')
                    browseTestResultName2++;
                while (browseTestResultName2 + nb < lengthOfTestResultName2 && testResultName2.charAt(browseTestResultName2 + nb) >= '0' && testResultName2.charAt(browseTestResultName2 + nb) <= '9')
                    nb++;
                if (na > nb)
                    return 1;
                if (nb > na)
                    return -1;
                if (browseTestResultName1 == lengthOfTestResultName1)
                    return browseTestResultName2 == lengthOfTestResultName2 ? 0 : -1;
                if (browseTestResultName2 == lengthOfTestResultName2)
                    return 1;

            }
            if (testResultName1.charAt(browseTestResultName1) != testResultName2.charAt(browseTestResultName2))
                return testResultName1.charAt(browseTestResultName1) - testResultName2.charAt(browseTestResultName2);
            browseTestResultName1++;
            browseTestResultName2++;
        }
    }

and the new lambda expression for sorting :

testResultList.sort((trl1, trl2)
                -> compareNatural(trl1.getTestName(),trl2.getTestName()) );
0

There are 0 best solutions below