Search code examples
androidandroid-cursor

How does the SortCursor from the AOSP repository sort it's values


I'm trying to use the SortCursor class from the AOSP mentioned in How to represent 2 cursors as 1 sorted cursor?. However it doesn't seem to sort the cursors I give at all. How does the sorting work?

Example code:

String[] columnNames = {"name", "value"};

MatrixCursor matrixCursor1 = new MatrixCursor(columnNames);
matrixCursor1.addRow(new String[]{"cursor 1 value A", "9"});
matrixCursor1.addRow(new String[]{"cursor 1 value B", "2"});
matrixCursor1.addRow(new String[]{"cursor 1 value C", "1"});

MatrixCursor matrixCursor2 = new MatrixCursor(columnNames);
matrixCursor2.addRow(new String[]{"cursor 2 value A", "70"});
matrixCursor2.addRow(new String[]{"cursor 2 value B", "8"});
matrixCursor2.addRow(new String[]{"cursor 2 value C", "6"});

Cursor sortCursor = new SortCursor(new Cursor[]{matrixCursor1, matrixCursor2}, columnNames[1]);
while (sortCursor.moveToNext()) {
    String name = sortCursor.getString(sortCursor.getColumnIndexOrThrow(columnNames[0]));
    String value = sortCursor.getString(sortCursor.getColumnIndexOrThrow(columnNames[1]));;
    Log.v("SortCursor", "Name: " + name + ", Value: " + value);
}
sortCursor.close();

Output when I run this code:

V/SortCursor: Name: cursor 2 value A, Value: 70
V/SortCursor: Name: cursor 2 value B, Value: 8
V/SortCursor: Name: cursor 2 value C, Value: 6
V/SortCursor: Name: cursor 1 value A, Value: 9
V/SortCursor: Name: cursor 1 value B, Value: 2
V/SortCursor: Name: cursor 1 value C, Value: 1

As you can see the values are completely unsorted. I would expect 1, 2, 6, 8, 9, 70.


Solution

  • There are two important things to know about the SortCursor.

    1. It reads values from the cursors as strings and not numbers so the string "70" is smaller than the string "8".

    2. It only compares the next value of each cursor when it is looking for the smallest value. So each individual cursor have to be sorted before it's given to the SortCursor.

    So with the given example "70" is smaller than "9" so that goes first, then "8" is smaller than "9" so that goes next, "6" is smaller than "9" so that goes next. Then only the values in the first cursor remains.

    As you see the cursor you used is actually sorted, its just not sorted in the way you expect it to be sorted.

    If you sort your individual cursors before you create the SortCursor and use strings instead of numbers you will get the expected result.

    MatrixCursor matrixCursor1 = new MatrixCursor(columnNames);
    matrixCursor1.addRow(new String[]{"cursor 1 value C", "01"});
    matrixCursor1.addRow(new String[]{"cursor 1 value B", "02"});
    matrixCursor1.addRow(new String[]{"cursor 1 value A", "09"});
    
    MatrixCursor matrixCursor2 = new MatrixCursor(columnNames);
    matrixCursor2.addRow(new String[]{"cursor 2 value C", "06"});
    matrixCursor2.addRow(new String[]{"cursor 2 value B", "08"});
    matrixCursor2.addRow(new String[]{"cursor 2 value A", "70"});
    

    Will give you

    V/SortCursor: Name: cursor 1 value C, Value: 01
    V/SortCursor: Name: cursor 1 value B, Value: 02
    V/SortCursor: Name: cursor 2 value C, Value: 06
    V/SortCursor: Name: cursor 2 value B, Value: 08
    V/SortCursor: Name: cursor 1 value A, Value: 09
    V/SortCursor: Name: cursor 2 value A, Value: 70