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