Java - сортировка списка объектов по значению объекта

проблема, с которой я столкнулся, не является чем-то особенным, однако, будучи относительно новичком в программировании, я оказываюсь в ситуации, когда мне нужна помощь более продвинутых программистов. Проблема, с которой я столкнулся, заключается в сортировке списка объектов различного размера в зависимости от их определенного элемента. У меня есть набор данных на картинке ниже.

Java - сортировка списка объектов по значению объекта

Как видите, данные состоят из 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), который затем будет отсортирован. Окончательный результат должен выглядеть как на картинке ниже.

Java - сортировка списка объектов по значению объекта

Я провел обширный поиск по 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] довольно хромает. Любая помощь, советы, примеры того, как склеить все вместе и произвести необходимый результат, приветствуются, заранее спасибо.

Возможный дубликат Сортировка ArrayList настраиваемых объектов по свойству

daniu 18.04.2018 11:15

В чем именно является ваша проблема?

HBo 18.04.2018 11:20

В предложенной теме daniu, вероятно, есть конструкторы, связанные с геттерами, я не знаю, нужно ли мне делать что-то подобное или мой случай может быть решен каким-либо другим способом @Hbo. Потому что, если бы мне пришлось устанавливать конструкторы для каждой строки с разными элементами, это бы меня запутало.

Karolis Gadeikis 18.04.2018 11:33
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
0
3
1 227
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Это отчасти зависит от выбранной вами структуры данных. Например, использование массивов может быть немного сложнее реализовать с использованием шаблона 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

Karolis Gadeikis 18.04.2018 11:54

Другие вопросы по теме