Обьединение двух ArrayList по условию
Есть два листа
List<Report> ReportTrue,
List<Report> ReportFalse,
В одном элементы такие: 01 True (может быть несколько, 01 - это как будто месяц, true это их булевое поле), в другом 01 False (тоже может быть несколько или один)
Не могу додумать как их объединить в другой лист, чтобы был такой порядок
01 True
01 True
01 False
02 True
02 False
и т.д
Сначала тру одного месяца потом фолс этого же месяца и т.д.
public List<Report> monthlyReportForUser(List<Report> ReportTrue, List<Report> ReportFalse) {
List<Report> ReportListForUser = new ArrayList<>();
int size = ReportTrue.size() + ReportFalse.size();
for (int i = 0; i < size; i++) {
if (ReportTrue.get(i).isExpense().ismouth() {
ReportListForUser.add(ReportTrue.get(i));
}
}
return monthlyReportListForUser;
}
Ответы (1 шт):
Списки можно объединить просто используя конструктор / метод List::addAll и компаратор для сортировки сначала по месяцу, затем по значению true/false (так как false < true, для задания обратного порядка нужно использовать Comparator.reverseOrder):
List<Report> total = new ArrayList<>(reportTrue);
total.addAll(reportFalse);
total.sort(Comparator.comparing(Report::getMonth)
.thenComparing(Report::isTrue, Comparator.reverseOrder()) // true before false
);
System.out.println(total);
или же используя Stream API Stream::concat + Stream::sorted и аналогичный компаратор:
List<Report> merged = Stream.concat(reportTrue.stream(), reportFalse.stream())
.sorted(Comparator.comparingInt(Report::getMonth)
.thenComparing(Report::isTrue, Comparator.reverseOrder()))
.collect(Collectors.toList());
System.out.println(merged);
Есть ещё вариант с "алгоритмическим" слиянием через циклы, при обязательном условии, что оба списка уже отсортированы.
Здесь поочередно инкрементируются индексы в обоих списках:
List<Report> looped = new ArrayList<>();
int t = 0;
int f = 0;
int n = listTrue.size() + listFalse.size();
int k = 0;
while (k < n) {
boolean trueFound = false;
while (t < listTrue.size() && (f == listFalse.size() || listTrue.get(t).getMonth() <= listFalse.get(f).getMonth())) {
looped.add(listTrue.get(t++));
k++;
trueFound = true;
}
if (trueFound) t--;
while (f < listFalse.size() && (t == listTrue.size() || listFalse.get(f).getMonth() <= listTrue.get(t).getMonth())) {
looped.add(listFalse.get(f++));
k++;
}
if (trueFound) t++;
}