Как я могу создать эффективную логику для создания нескольких неупорядоченных событий в последовательные события порядка

У меня есть следующий файл JSON. Этот файл JSON содержит список заказов, выполненных за этот день. Существуют исходные заказы, а также заказы на обновление, которые ссылаются на предыдущий порядок, указанный в "previousOrderRef".

[
    {
        "orderNum":"1",
        "orderType":"Original",
        "orderContent":"Apple",
        "previousOrderRef":null
    },
    {
        "orderNum":"2",
        "orderType":"Original",
        "orderContent":"Pear",
        "previousOrderRef":null
    },
    {
        "orderNum":"3",
        "orderType":"Original",
        "orderContent":"Orange",
        "previousOrderRef":null
    },
    {
        "orderNum":"4",
        "orderType":"Original",
        "orderContent":"Apple",
        "previousOrderRef":null
    },
    {
        "orderNum":"5",
        "orderType":"Original",
        "orderContent":"Pear",
        "previousOrderRef":null
    }
    ,
    {
        "orderNum":"6",
        "orderType":"Updates",
        "orderContent":"Watermelon",
        "previousOrderRef":[2,4]
    },
    {
        "orderNum":"7",
        "orderType":"Updates",
        "orderContent":"Grapefruit",
        "previousOrderRef":[1,3]
    }
    ,
    {
        "orderNum":"8",
        "orderType":"Updates",
        "orderContent":"Grapes",
        "previousOrderRef":[5]
    }
    ,
    {
        "orderNum":"9",
        "orderType":"Updates",
        "orderContent":"Pear",
        "previousOrderRef":[7]
    },
    {
        "orderNum":"10",
        "orderType":"Updates",
        "orderContent":"Blood Orange",
        "previousOrderRef":[8]
    }
    ,
    {
        "orderNum":"11",
        "orderType":"Updates",
        "orderContent":"Blood Orange",
        "previousOrderRef":[9]
    }

]

Этот файл JSON будет сопоставлен со следующим POJO с помощью Jackson

public class MyOrder{
    private String orderNum;
    private String orderType;
    private String orderContent;
    private List<String> previousOrderRef;


    public String getOrderNum(){
        return orderNum;
    }

    public void setOrderNum(String orderNum){
        this.orderNum = orderNum;
    }

    public String getOrderType(){
        return orderType;
    }

    public void setOrderType(String orderType){
        this.orderType = orderType;
    }

    public String getOrderContent(){
        return orderContent;
    }

    public void setOrderContent(String orderContent){
        this.orderContent = orderContent;
    }

    public List<String> getPreviousOrderRef(){
        return previousOrderRef;
    }

    public void setPreviousOrderRef(List<String> previousOrderRef){
        this.previousOrderRef = previousOrderRef;
    }
}

В отдельном файле или выводе я хочу создать некоторый тип аудита заказа, в котором он показывает след в виде цепочки событий, показанной ниже.

orderNum:1 -> orderNum:7 -> orderNum:9 -> orderNum:11
orderNum:2 -> orderNum:6 
orderNum:3 -> orderNum:7 -> orderNum:9 -> orderNum:11
orderNum:4 -> orderNum:6
orderNum:5 -> orderNum:8 -> orderNum:10 

Какой способ создания цепочки такого типа был бы наиболее эффективным?

так что вы до сих пор пытались напечатать это?

SamHoque 26.10.2018 09:23
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
Как вычислять биты и понимать побитовые операторы в Java - объяснение с примерами
В компьютерном программировании биты играют важнейшую роль в представлении и манипулировании данными на двоичном уровне. Побитовые операции...
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Поднятие тревоги для долго выполняющихся методов в Spring Boot
Приходилось ли вам сталкиваться с требованиями, в которых вас могли попросить поднять тревогу или выдать ошибку, когда метод Java занимает больше...
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
2
1
34
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

Прежде всего, определите объект, который может содержать требуемую структуру.

class MyOrderMapped{

    private String orderNum;
    private String orderType;
    private String orderContent;
    private List<MyOrderMapped> nextOrderRefs;

    public MyOrderMapped(String orderNum, String orderType, String orderContent) {
        this.orderNum = orderNum;
        this.orderType = orderType;
        this.orderContent = orderContent;
        this.nextOrderRefs= new LinkedList<>();
    }

    // getters and setters

}

Затем создайте Map из orderNum в MyOrderMapped.

// orders is what you deserialize from JSON
List<MyOrder> orders = new LinkedList<>();
Map<String, MyOrderMapped> mappedById = orders
            .stream()
            .map(o -> new MyOrderMapped(o.getOrderNum(), 
                                        o.getOrderType(), 
                                        o.getOrderContent()))
            .collect(Collectors.toMap(MyOrderMapped::getOrderNum, Function.identity()));

Итерируйте свой первоначальный список и постройте дерево заказов.

orders.stream().forEach(order -> {
        MyOrderMapped current = mappedById.get(order.getOrderNum());
        order.getPreviousOrderRef().forEach(parentOrderNum -> {
            MyOrderMapped parent = mappedById.get(parentOrderNum);
            parent.getNextOrderRefs().add(current);
        });
    });

Наконец, вы можете получить корни порядка следующим образом.

Set<String> roots = orders
            .stream()
            .filter(value -> value.getPreviousOrderRef() == null || 
                             value.getPreviousOrderRef().isEmpty())
            .map(MyOrder::getOrderNum)
            .collect(Collectors.toSet());

List<MyOrderMapped> orderRoots = mappedById.values()
            .stream()
            .filter(current -> roots.contains(current.getOrderNum()))
            .collect(Collectors.toList());

Другие вопросы по теме