[英]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.