Разделить заказы пациента по условиям
Есть коллекция с заказами клиентов.
List<Order> orderList;
Order содержит следующие поля:
id_client - уникальный номер клиента
status - Статус заказа
cito - Срочность заказа
Как можно разделить заказы клиента по условию что если у одного клиента были заказы с одним статусом и cito в одну коллекцию, а другие в другую коллекцию?
Класс Order
public class Order {
private int client_id;
private int type;
private String city;
public Order() {
}
public int getClient_id() {
return client_id;
}
public void setClient_id(int client_id) {
this.client_id = client_id;
}
public int getType() {
return type;
}
public void setType(int type) {
this.type = type;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
Ответы (1 шт):
Для решения таких задач удобно использовать Stream API, в котором поток заказов Stream<Order> группируется по идентификатору клиента, а затем заказы дополнительно делятся по условию на две коллекции при помощи коллектора Collectors.partitioningBy, для которого нужно передать функцию-предикат.
Таким образом, получается мапа Map<Long, Map<Boolean, List<Order>>>.
Пример реализации (с использованием Lombok-аннотаций):
// пример класса Order
@Data
@AllArgsConstructor
class Order {
private long idClient;
private String status;
private String urgency;
}
public static Map<Long, Map<Boolean, List<Order>>> groupByClientAndCondition(List<Order> orders, Predicate<Order> condition) {
return orders.stream()
.collect(Collectors.groupingBy(
Order::getIdClient,
LinkedHashMap::new,
Collectors.partitioningBy(condition)
));
}
Тест:
List<Order> orders = Arrays.asList(
new Order(1001L, "ok", "none"),
new Order(1002L, "cito", "asap"),
new Order(1001L, "cito", "urgent!"),
new Order(1010L, "usual", null)
);
groupByClientAndCondition(orders, order -> "cito".equals(order.getStatus()))
.forEach((clientId, groups) -> System.out.printf("%d:%n\tcito: %s%n\tother: %s%n---%n", clientId, groups.get(true), groups.get(false)));
1001:
cito: [Order(idClient=1001, status=cito, urgency=urgent!)]
other: [Order(idClient=1001, status=ok, urgency=none)]
---
1002:
cito: [Order(idClient=1002, status=cito, urgency=asap)]
other: []
---
1010:
cito: []
other: [Order(idClient=1010, status=usual, urgency=null)]
---
При необходимости большей детализации список заказов можно группировать отдельно по каждому статусу и другим полям, используя Collectors.groupingBy вместо Collectors.partitioningBy, соответственно ключом во вложенной мапе будет тип поля статуса.