简体   繁体   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"}]

so the logic should be like first object must be {"z","pnp"} as current("z") there is no object where next is ("z"), so it should be first object after sorting.所以逻辑应该像 first object must be {"z","pnp"} as current("z") 没有 object where next is ("z"), 所以排序后它应该是 first object。 Then last object after sorting should be {"123","d"}, since there next("d"), there doestn exist any object whose current("d"), so its last object. The remaining objects are sorted in the middle based on their next and current properties.那么排序后的最后一个object应该是{“123”,“d”},因为有next(“d”),不存在任何object的current(“d”),所以它的最后一个object。剩余的对象排序在中间基于他们的下一个和当前属性。

How can i acheive this?我怎样才能做到这一点?

Rather than using a comparator to sort them, this solution considers this as an ordering problem and re-orders the list into a new list in O(n) time.该解决方案不是使用比较器对它们进行排序,而是将其视为排序问题,并在O(n)时间内将列表重新排序为新列表。

First, it builds a Map<String, DocumentObject> from the input list.首先,它根据输入列表构建一个Map<String, DocumentObject> Next, it gets all the keys of the map as a Set (all current values in the list of DocumentObject s) and then removes all the next elements from the set.接下来,它获取 map 的所有键作为一个集合( DocumentObject列表中的所有current值),然后从集合中删除所有next元素。 This leaves only one element in the set which will be the root or first element (since it didn't have any DocumentObject instance with its value as the next ).这只在集合中留下一个元素,它将成为根元素或第一个元素(因为它没有任何 DocumentObject 实例,其值为next )。 Thinking in graph terminology, this element is the only element whose in-degree is 0.用图的术语来思考,这个元素是唯一入度为 0 的元素。

Finally, starting from the root element, we build the ordered list (using the auxiliary map) by traversing the elements as per the next value of the current (previous) element.最后,从根元素开始,我们通过根据当前(上一个)元素的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