Карты сортировки Java по значениям некоторых ключей - PullRequest
0 голосов
/ 28 мая 2018

Как реализовать Comparator для сортировки списка карт по определенным значениям ключа?Моя цель - произвольно отсортировать два списка, чтобы я мог сравнить другие поля, которые не являются частью сортировки.

Например, учитывая, что у меня есть эти два списка карт, я хочу отсортировать по firstName иlastName.

+-----------+--------+-------+-------+
| List 1    | Map 1  | Map 2 | Map 3 |
+-----------+--------+-------+-------+
| firstName | John   | Eric  | John  |
| lastName  | Miller | Smith | Davis |
| age       | 17     | 19    | 35    |
+-----------+--------+-------+-------+

+-----------+--------+-------+-------+
|  List 2   | Map 1  | Map 2 | Map 3 |
+-----------+--------+-------+-------+
| firstName | Eric   | John  | John  |
| lastName  | Smith  | Davis | Miller|
| age       | 53     | 38    | 26    |
+-----------+--------+-------+-------+

И после того, как я отсортировал это, теперь я могу сравнить Карту 1 Списка 1 с Картой 2 Списка 2 и посмотреть, что отличается.

Итак, у меня есть класс, который реализует компаратор следующим образом:

// Note that the values may not implement Comparable
public class PersonComparator implements Comparator<Map<String, Object>> {
    private List<String> sortKeys = Arrays.asList("firstName", "lastName");

    @Override
    public int compare(Map<String, Object> map1, Map<String, Object> map2) {
        Map<String, Object> keyValue1 = new HashMap<>();
        sortKeys.forEach(key -> keyValue1.put(key, map1.get(key)));

        Map<String, Object> keyValue2 = new HashMap<>();
        sortKeys.forEach(key -> keyValue2.put(key, map2.get(key)));

        return keyValue2.hashCode() - keyValue1.hashCode();
    }
}

И вызов sort для каждого из списков приведет к следующему:

+-----------+--------+-------+-------+
| List 1    | Map 1  | Map 2 | Map 3 |
+-----------+--------+-------+-------+
| firstName | John   | Eric  | John  |
| lastName  | Miller | Smith | Davis |
| age       | 17     | 19    | 35    |
+-----------+--------+-------+-------+

+-----------+--------+-------+-------+
| List 2    | Map 1  | Map 2 | Map 3 |
+-----------+--------+-------+-------+
| firstName | John   | Eric  | John  |
| lastName  | Miller | Smith | Davis |
| age       | 26     | 53    | 38    |
+-----------+--------+-------+-------+

Но порядок списков никогда не меняется ... Что я делаю не так?

1 Ответ

0 голосов
/ 28 мая 2018

В конечном счете, ваша сортировка основана на хэш-кодах ключа - порядок, который не обязательно соответствует их значениям (т. Е. «Меньшая» строка может иметь больший хэш-код и наоборот).

Вместо этого вы должны сортировать в соответствии с самими значениями, даже если это означает явное приведение Object значений, которые у вас есть к сопоставимым значениям:

Comparator<Map<String, Object>> personComparator =
    Comparator.comparing(m -> (String) m.get("firstName"))
              .thenComparing(m -> (String) m.get("lastName"));
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...