繁体   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