Я пытаюсь выполнить сортировку по убыванию столбца, содержащего в строке подчеркивание. Это мой метод сортировки по убыванию.
protected void validateDescendingOrder(Integer column) {
// create a column list
List<String> columnList = getColumnList(column);
// create a new list and sort
List<String> sortedcolumnList = new ArrayList<String>();
sortedcolumnList.addAll(columnList);
Collections.sort(sortedcolumnList, new Comparator<String>() {
public int compare(String o1, String o2) {
if (o1.contains("_") && o2.contains("_")) {
return compare(o1.substring(1), o2.substring(1));
}
if (o1.contains("_")) {
return 1;
}
if (o2.contains("_")) {
return -1;
}
return o1.compareTo(o2);
}
});
// sort the list using the custom comparator
Collections.sort(sortedcolumnList, Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER));
//sortedcolumnList.sort(customComparator);
System.out.println(sortedcolumnList);
System.out.println(columnList);
// compare the original list order with the sorted list to make sure they match
assertEquals(sortedcolumnList, columnList);
Я ожидаю, что мой род вернется Test_jenn, Test_Community, TestRelease, TestCom1, test1, но вместо этого возвращается TestRelease, TestCom1, Test_jenn, Test_Community, test1
Кроме того, я не вижу никаких попыток сделать это спускающимся. У вас это сортировка по возрастанию, поскольку это значение по умолчанию. И вы хотите, чтобы он был нечувствителен к регистру? Тогда вам придется это указать.
пожалуйста, опубликуйте минимальный воспроизводимый пример - опубликованный код ничего не возвращает - а также опубликуйте правильные примеры - я не верю, что sortedcolumnList
имеет test1
в конце
как упоминалось в k314159, if (o1.contains"_") return 1;
означает, что все, что содержит подчеркивание, больше, чем что-то без подчеркивания (и больше сортируется до конца, а не до начала, как вы ожидаете. || o1.compareTo(o2)
также не будет сортироваться в порядке убывания. || запуск опубликованного кода с заданными строками заканчивается на sortedcolumnList = [TestCom1, TestRelease, test1, Test_Community, Test_jenn]
, а не на то, что было опубликовано
Вам будет полезно запустить этот код с помощью отладчика. Отладчик позволит вам установить точку останова и запускать код по одной строке, отслеживая значения переменных. Когда код делает что-то, противоречащее вашему прогнозу? Каковы были значения переменных в то время?
Как вы хотите, чтобы код сравнивал пару строковых объектов, если каждый из них имеет _
, но различается до _
? Например, как следует сравнивать Test_jenn
и Register_jenn
? или Test_jenn
и Quiz_Community
?
@ k314159 k314159, извини, мне не удалось опубликовать часть кода, посвященную обратной сортировке. Я отредактировал сообщение, чтобы оно содержало это.
@ user85421, мне не удалось опубликовать обратную сортировку, но я изменил выше, указав, где я выполняю сортировку. Примеры, которые я привел, - это мой реальный код, который вызывает у меня проблемы и неправильно сортирует.
последний sort
по сути переопределяет предыдущий, то есть просто сортирует записи (в порядке, обратном CASE_INSENSITIVE_ORDER) || возможно, вы хотите Collections.sort(sortedcolumnList, Collections.reverseOrder(new Comparator<String>() { ...
с предыдущим компаратором... или просто добавьте .reversed()
после компаратора (Collections.sort(sortedcolumnList, new Comparator<String>() { ... }.reversed());
)
(другими словами, reversedOrder()
не меняет фактический порядок, он меняет компаратор, заданный в качестве параметра, а затем sort()
начинает новую сортировку, (почти) игнорируя фактический порядок элементов)
(( другая возможность перевернуть компаратор — поменять местами аргументы (o1
<-> o2
)) — также рассмотрите String.compareToIgnoreCase()
Collections.sort()
вызывается дважды, и поскольку вызов Collections.sort()
пересортирует список, предыдущая сортировка (почти)¹ игнорируется.
Опубликованный код в основном:
Collections.sort(list, comparator1);
Collections.sort(list, comparator2);
таким образом, результирующий порядок соответствует тому, который задан компаратором2 - reverseOrder(CASE_INSENSITIVE_ORDER)
.
Сортировка compartor1 — анонимного класса, использующего символы подчеркивания — игнорируется!
То есть сделать что-то вроде:
Collections.sort(list, Collections.reverseOrder(comparator3));
не меняет предыдущий порядок списка; он сортирует, используя заданный comparator3
в обратном порядке. В опубликованном коде компаратор переворачивается — String.CASE_INSENSITIVE_ORDER
, поэтому список сортируется в порядке убывания строк без учета регистра.
Удалить вторую сортировку
Collections.sort(sortedcolumnList, Collections.reverseOrder(String.CASE_INSENSITIVE_ORDER));`
Альтернативы для отмены анонимного компаратора:
Collections#reverseOrder
Collections.reverseOrder( new Comparator<String>() {
public int compare(String o1, String o2) {
if (o1.contains("_") && o2.contains("_")) {
return compare(o21.substring(1), o2.substring(1));
}
if (o2.contains("_")) {
return 1;
}
if (o1.contains("_")) {
return -1;
}
return o2.compareTo(o1);
}
} )
compare
new Comparator<String>() {
public int compare(String o1, String o2) {
if (o1.contains("_") && o2.contains("_")) {
return compare(o21.substring(1), o2.substring(1));
}
if (o2.contains("_")) {
return 1;
}
if (o1.contains("_")) {
return -1;
}
return o2.compareTo(o1);
}
}
new Comparator<String>() {
public int compare(String o1, String o2) {
if (o1.contains("_") && o2.contains("_")) {
return compare(o1.substring(1), o2.substring(1));
}
if (o1.contains("_")) {
return -1;
}
if (o2.contains("_")) {
return 1;
}
return - o1.compareTo(o2);
}
}
Нечувствителен к регистру
Чтобы получить регистронезависимый порядок в приведенных выше кодах, используйте compareToIgnoreCase()
вместо ignoreTo()
.
Рекурсивный вызов
Я не уверен, какова цель рекурсивного вызова compare
. Мне кажется, это дорогой и подверженный ошибкам способ игнорировать все, что находится до подчеркивания в обеих строках. Метод compare
в конечном итоге может быть вызван для сравнения каждого элемента друг с другом, то есть его можно вызывать очень часто, нерекурсивное решение было бы более подходящим. Предложение: вместо contains
используйте indexOf()
для поиска по подчеркиваниям и substring()
для игнорирования всего до этого индекса.
as I wrote, not sure what the exact requirement are.
1 - Collections#sort
«гарантированно стабильный: в результате сортировки порядок одинаковых элементов не будет переупорядочен». (javadoc)
Каков именно ваш предполагаемый порядок, когда обе строки содержат «_»? У вас это получается, вы сравниваете строки, начиная со второй буквы. Это выглядит подозрительно. Вы уверены, что это то, что вы хотите сделать?