Как отсортировать список массивов по двум полям - PullRequest
0 голосов
/ 04 февраля 2019

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

Реальное состояние:

0         1         2
-------  -------  -------
78       100        0
78       100        1
0        100        0
104      100        1

Ожидается:

0         1         2
-------  -------  -------
0        100       0
78       100       1
78       100       0
101      100       1

Я хочу отсортировать поле по значению 1-го элемента массива.Если значения 1 и 2 равны, я хочу отсортировать по 3-му элементу, где сначала должно быть 1, а затем 0 (будет только 1 и 0 значение)

List<Double[]> splitList = new ArrayList<>();
Double[] tmp1 = { 78d, 100d, 0d };
Double[] tmp2 = { 78d, 100d, 1d };
Double[] tmp3 = { 0d, 100d, 0d };
Double[] tmp4 = { 104d, 100d, 1d };
splitList.add(tmp1);
splitList.add(tmp2);
splitList.add(tmp3);
splitList.add(tmp4);
splitList.sort(Comparator.comparingDouble(a -> a[0]));

Этот сортирует меня по первомуэлемент.Я нашел решение для сортировки по двум элементам https://stackoverflow.com/a/26865122/9774735, поэтому я попробовал его:

splitList.sort(Comparator.comparingDouble(a -> a[0]).thenComparingDouble(b -> b[2]));

, и он выдал ошибку:

Multiple markers at this line
    - The type of the expression must be an array type but it resolved 
     to Object
    - The type of the expression must be an array type but it resolved 

Как я могу сравнить СписокМассив

Ответы [ 3 ]

0 голосов
/ 04 февраля 2019

Похоже, что у java-компилятора есть проблемы с выводом универсального типа, у вас есть несколько вариантов для решения этой проблемы:

  1. Использование подсказок типов с шаблоном Class.<GenericType>.method(Arguments):

    splitList.sort(Comparator.<Double[]>comparingDouble(a -> a[0]).thenComparingDouble(b -> b[2]));
    
  2. Объявите тип лямбда-параметра (кажется, достаточно указать его первым):

    splitList.sort(Comparator.comparingDouble((Double[] a) -> a[0]).thenComparingDouble(b -> b[2]));
    

После прочтения ваших комментариев вы хотитечтобы отменить последнее сравнение, которое можно сделать так:

Comparator.<Double[]>comparingDouble(a -> a[0])
   .thenComparing(Comparator.<Double[]>comparingDouble(b -> b[2]).reversed())

Что довольно грязно, лучше использовать что-то вроде этого:

splitList.sort((a, b) -> {
    int c = Double.compare(a[0], b[0]);
    return c == 0 ? Double.compare(b[2], a[2]) : c;
});
0 голосов
/ 04 февраля 2019

Если вы используете Java 8 или следующую версию, вы можете использовать это:

splitList.stream()
            .sorted(Comparator.comparing((Double[] array) -> array[0])
                    .thenComparing(Comparator.comparing((Double[] array2) -> array2[2]).reversed()));

для печати в консоли:

splitList.stream()
            .sorted(Comparator.comparing((Double[] array) -> array[0])
                    .thenComparing(Comparator.comparing((Double[] array2) -> array2[2]).reversed()))
            .forEach(array -> System.out.println(Arrays.toString(array)));

или вы можете собрать в списке, а затем распечататьсписок тоже:

List<Double[]> list = splitList.stream()
            .sorted(Comparator.comparing((Double[] array) -> array[0])
                    .thenComparing(Comparator.comparing((Double[] array2) -> array2[2]).reversed()))
            .collect(Collectors.toList());

for (Double[] array: list) {
    System.out.println(Arrays.toString(array));
}

Удачи!

0 голосов
/ 04 февраля 2019

Попробуйте это:

    splitList.sort((a,b) -> {
        int r = a[0].compareTo(b[0]);
        if (r == 0) {
            r = a[2].compareTo(b[2]);
        }
        return r;
    });
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...