Сравнение объектов в List

У меня есть List объектов:

   {
      "rn": "14",
      "time": "2020-06-16 16:47:55",
      "id": 42332392988,
      "termname": "S1160AFB",
      "type": "100",
      "trancode": "110",
      "pan": "4790729949581839",
      "amount": "360.96",
      "approvalcode": "44444"
    },
    {
      "rn": "15",
      "time": "2020-06-16 16:48:55",
      "id": 42330308379,
      "termname": "S1160AFB",
      "type": "100",
      "trancode": "110",
      "pan": "4149510064617121",
      "amount": "360.96",
      "approvalcode": "55555"
    },
    {
      "rn": "13",
      "time": "2020-06-16 16:49:11",
      "id": 42332530886,
      "termname": "S1160AFB",
      "type": "420",
      "trancode": "110",
      "pan": "4790729949581839",
      "amount": "360.96",
      "approvalcode": "44444"
    }

Задача:

  1. Найти объекты у которых одинаковый approvalcode. (Он уникальный и может повторяться только 2 раза)
  2. Если объекта два и у второго у которого дата позже чем у первого в поле type значение 420. То удалить эти оба объекта из list.

Мое решение:

  1. Сортирую list по полю approvalcode и дате.
     List<Transaction> filteredTrans = transResponse.getTransaction().stream().sorted(Comparator.comparing(Transaction::approvalcode).thenComparing(Transaction::getTime))
     .collect(Collectors.toList());
  1. Сравниваю по два объекты и удаляю если они выполняют необходимое мне условие.
int j = 1;
for (int i=0; i<filteredTrans.size()-1; i++) {
if (filteredTrans.get(i).getApprovalcode().equals(filteredTrans.get(j).getApprovalcode()) && filteredTrans.get(j).getType().equals("420")) {
        filteredTrans.remove(i);
        filteredTrans.remove(j);
        j++;
    }

Но вторая часть выглядит как по мне ужасно. Посоветуйте, пожалуйста, адекватное решение.


Ответы (1 шт):

Автор решения: IR42
List<Transaction> filteredTrans = transResponse.getTransaction().stream()
        .collect(Collectors.groupingBy(Transaction::getApprovalcode))
        .values()
        .stream()
        .filter(l -> {
            if (l.size() == 1) return true;
            Transaction maxTimeTr = l.stream().max(Comparator.comparing(Transaction::getTime)).orElseThrow();
            return !maxTimeTr.getType().equals("420");
        })
        .flatMap(Collection::stream)
        .collect(Collectors.toList());
→ Ссылка