проблема, с которой я столкнулся, не является чем-то особенным, однако, будучи относительно новичком в программировании, я оказываюсь в ситуации, когда мне нужна помощь более продвинутых программистов. Проблема, с которой я столкнулся, заключается в сортировке списка объектов различного размера в зависимости от их определенного элемента. У меня есть набор данных на картинке ниже.
Как видите, данные состоят из 8 строк с разным количеством строковых элементов. Моя цель - отсортировать эти строковые объекты по столбцам.
Что я имею в виду - сначала строки сортируются по первому элементу каждой строки. Таким образом, если исходное расположение строк согласно первым элементам каждой строки равно [-2.2, 2.2, 2.2, -22, -22, -22, -1.1, qqqq], отсортированное расположение будет выглядеть как [-22, -22, -22, - 2.2, -1.1, 2.2, 2.2, qqqq]. Затем, поскольку есть несколько строк с одинаковыми элементами (0,1,2 строка) и (5,6 строка), эти строки будут отсортированы по второй элемент - в этом случае эти вторые элементы равны 1234234, 11, -3. для строк с первым элементом -22 и 12345q, 12345q для строк с первым элементом 2.2.
После этого две строки, содержащие 12345q в качестве второго элемента, будут отсортированы по третьему элементу, который для обоих 69, и будет достигнут 4-й элемент (-afg и -asdf), который затем будет отсортирован. Окончательный результат должен выглядеть как на картинке ниже.
Я провел обширный поиск по stackoverflow, и ближе всего к моему случаю был Сортировка в Java по двум столбцам. Я понимаю шаги, которые мне нужно предпринять, чтобы решить проблему (создать список, создать компаратор и т. д.), Но только теоретически.
У меня есть List of Strings[] named rowObject, который содержит все строки с соответствующими строковыми элементами, количество которых, как я упоминал ранее, варьируется от строки к строке. У меня также есть компаратор, который выполняет работу по сортировке именно так, как это необходимо, однако это записано в методе сравнения:
public class ComparatorClass {
public List compare(List<String> listOfValues) {
Comparator<String> c = new Comparator<String>() {
@Override
public int compare(String s1, String s2) {
boolean b1 = s1.matches(".*[^0-9.\\-].*");
boolean b2 = s2.matches(".*[^0-9.\\-].*");
// if both are gonna find doubles
if (!b1 && !b2) {
Double d1 = Double.parseDouble(s1);
Double d2 = Double.parseDouble(s2);
return d1.compareTo(d2);
}
// if both are text, then compare as strings
else if (b1 && b2) {
return s1.compareTo(s2);
}
// otherwise return one or the other, depending on which is text/number
else return b2 ? -1 : 1;
}
};
Collections.sort(listOfValues, c);
return listOfValues;
}
Следовательно, у меня есть список объектов, которые мне нужно отсортировать по их значениям, у меня есть компаратор, но я не знаю, как собрать их все вместе, чтобы все упорядочить плавно и аккуратно. Я также не знаю, как правильно получить доступ к определенному значению этих объектов, например, String firstvalue = rowObject.get(i)[0] довольно хромает. Любая помощь, советы, примеры того, как склеить все вместе и произвести необходимый результат, приветствуются, заранее спасибо.
В чем именно является ваша проблема?
В предложенной теме daniu, вероятно, есть конструкторы, связанные с геттерами, я не знаю, нужно ли мне делать что-то подобное или мой случай может быть решен каким-либо другим способом @Hbo. Потому что, если бы мне пришлось устанавливать конструкторы для каждой строки с разными элементами, это бы меня запутало.




Это отчасти зависит от выбранной вами структуры данных. Например, использование массивов может быть немного сложнее реализовать с использованием шаблона Comparator. Но если у вас есть список списков, вы можете сделать это так:
public class ComparatorClass implements Comparator<List<String>>{
private int compare(String s1, String s2) {
boolean b1 = s1.matches(".*[^0-9.\\-].*");
boolean b2 = s2.matches(".*[^0-9.\\-].*");
// if both are gonna find doubles
if (!b1 && !b2) {
Double d1 = Double.parseDouble(s1);
Double d2 = Double.parseDouble(s2);
return d1.compareTo(d2);
}
// if both are text, then compare as strings
else if (b1 && b2) {
return s1.compareTo(s2);
}
// otherwise return one or the other, depending on which is text/number
else return b2 ? -1 : 1;
}
@Override
public int compare(List<String> o1, List<String> o2) {
for(int i=0;i<Math.min(o1.size(), o2.size()); i++) {
int comparedAtThisLevel=compare(o1.get(i),o2.get(i));
if (comparedAtThisLevel!=0)
return comparedAtThisLevel;
}
return Integer.compare(o1.size(),o2.size());
}
}
Это компаратор для списка строк (а не только для двух строк). Я использовал ваш метод для сравнения двух строк на одном уровне, но затем я перебираю список значений и сравниваю 1-е с 1-м, 2-м с 2-м, 3-м с 3-м и т. д. Если все значения совпадают (или один из списков заканчивается), мы сравните размеры и возьмите более длинный
Затем вы можете проверить это с помощью этого:
public static void main(String[] args) {
System.out.println(new Date()+": Let's start our StackOverflow helper project!");
List<List<String>> listOfLists=new ArrayList<>();
listOfLists.add(Arrays.asList("-22","123456","4234","5435345"));
listOfLists.add(Arrays.asList("-22","-3","-4"));
listOfLists.add(Arrays.asList("-22","11","Pillow"));
Collections.sort(listOfLists, new ComparatorClass());
}
Вы попали в яблочко и разрешили мою головную боль последних двух дней. Большое спасибо друг! <3
Возможный дубликат Сортировка ArrayList настраиваемых объектов по свойству