Home > database >  Sort java arraylist omitting leading whitespace
Sort java arraylist omitting leading whitespace

Time:10-23

I have a content of text file stored in ArrayList. Some items in the ArrayList might have leading blank spaces. I want to sort this list omitting the leading blanks, however I can't just trim beginning of some items in the list (by some RegEx) as when I print out the sorted Arrays, I need to print it including the blank spaces.

For instance:

a
c
  b

should result in

a
  b
c

(without exclusion of the whitespaces, natively the letter c would end up at first place after sorting)

Any ideas? Thank you!

CodePudding user response:

ArrayList<String> yourList = ....

yourList.sort(Comparator.comparing(String::trim));

CodePudding user response:

List<String> list = Arrays.asList("a", "c", "  b");

SortedMap<String, Integer> map = new TreeMap<>();
for(int a = 0; a < list.size(); a  ) {
    map.put(list.get(a).trim(), a);
}

map.keySet().stream().sorted(Comparator.naturalOrder()).forEach(item -> {
    System.out.println(list.get(map.get(item)));
});

CodePudding user response:

It may be better to create a method dealing with chars instead of using String::trim function just to skip the whitespaces to avoid creation of multiple trimmed strings especially if the input file is large enough:

public static int compareTrimmed(String s1, String s2) {
    int start1 = firstNonwhitespace(s1);
    int start2 = firstNonwhitespace(s2);
    
    if (start1 == -1 && start2 == -1) return 0;
    if (start1 == -1) return -1;
    if (start2 == -1) return 1;
    
    char[] v1 = s1.toCharArray(), v2 = s2.toCharArray();
    int i1 = start1, i2 = start2;
    
    for (; i1 < v1.length && i2 < v2.length; i1  , i2  ) {
        if (v1[i1] != v2[i2]) {
            return v1[i1] - v2[i2];
        }
    }
    return v1.length - i1 - v2.length   i2;
}

private static int firstNonwhitespace(String s) {
    if (null == s || s.isEmpty()) return -1;
    int i = 0;
    while (i < s.length() && Character.isWhitespace(s.charAt(i  )));
    return i - 1;
}

Test (comparing to less verbose String::trim solution)

List<String> data = Arrays.asList(
    "",
    "      ",
    "   c   ",
    "      b   ",
    "  a   ",
    "  ",
    "    1",
    "  b a  ",
    "b",
    "000"
);
data.sort(MyClass::compareTrimmed);
data.forEach(s -> System.out.printf("'%s'%n", s));
System.out.println("-----");
data.sort(Comparator.comparing(String::trim));
data.forEach(s -> System.out.printf("'%s'%n", s));

Output:

''
'      '
'  '
'000'
'    1'
'  a   '
'b'
'      b   '
'  b a  '
'   c   '
----- 
''
'      '
'  '
'000'
'    1'
'  a   '
'b'
'      b   '
'  b a  '
'   c   '
  • Related