簡體   English   中英

如何根據 Java 中的某些條件對自定義對象的無序列表進行排序

[英]How to sort a unordered list of custom objects based on some condition in Java

@Data    
public class DocumentObject {
        public String current;
        public String next;
    
    }
    
    public static void main(String[] args) {
            //Unordered list of objects
            List<DocumentObject> list = Arrays.asList(
                    new DocumentObject("pnp","xyz"),
                    new DocumentObject("z","pnp"),
                    new DocumentObject("123","d"),
                    new DocumentObject("xyz","123"));
            //Expecting ordered list to be returned based on some conditions
            System.out.println(sortingLogic(list));
                    
        }
    
        private static List<DocumentObject> sortingLogic(List<DocumentObject> list) {
            if (list.size() > 0) {
//THIS APPROACH NOT WORKING :(
                  Collections.sort(list, new Comparator<DocumentObject>() {
                      @Override
                      public int compare(DocumentObject o1, DocumentObject o2) {
                          int index1 = list.indexOf(o1.getCurrent());
                          int index2 = list.indexOf(o2.getNext());
    
                          return Integer.compare(index2 , index1);
                      }
                  });
            }
            return list;
        }

//My Expected output
[{"z","pnp"},
{"pnp","xyz"},
{"xyz","123"},
{"123","d"}]

所以邏輯應該像 first object must be {"z","pnp"} as current("z") 沒有 object where next is ("z"), 所以排序后它應該是 first object。 那么排序后的最后一個object應該是{“123”,“d”},因為有next(“d”),不存在任何object的current(“d”),所以它的最后一個object。剩余的對象排序在中間基於他們的下一個和當前屬性。

我怎樣才能做到這一點?

該解決方案不是使用比較器對它們進行排序,而是將其視為排序問題,並在O(n)時間內將列表重新排序為新列表。

首先,它根據輸入列表構建一個Map<String, DocumentObject> 接下來,它獲取 map 的所有鍵作為一個集合( DocumentObject列表中的所有current值),然后從集合中刪除所有next元素。 這只在集合中留下一個元素,它將成為根元素或第一個元素(因為它沒有任何 DocumentObject 實例,其值為next )。 用圖的術語來思考,這個元素是唯一入度為 0 的元素。

最后,從根元素開始,我們通過根據當前(上一個)元素的next值遍歷元素來構建有序列表(使用輔助映射)。

private static List<DocumentObject> sortingLogic(List<DocumentObject> list) {
    Map<String, DocumentObject> map = list.stream()
            .collect(Collectors.toMap(DocumentObject::getCurrent, Function.identity()));

    Set<String> allCurrent = new HashSet<>(map.keySet());
    map.values()
                .forEach(documentObject -> 
                        allCurrent.remove(documentObject.getNext()));

    // The only 'current' value which is not present as next in any of the other entries
    String root = allCurrent.iterator().next();
    List<DocumentObject> orderedDocumentObjects = new ArrayList<>();
    orderedDocumentObjects.add(map.get(root));
        
    for (int i = 1; i < list.size(); i++) {
        String next = orderedDocumentObjects.get(i - 1).getNext();
        orderedDocumentObjects.add(map.get(next));
    }
    return orderedDocumentObjects;
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM