我有一個ID屬性的對象集合(無序)和ID(有序)列表。 該id列表沒有排序。我想創建我的集合中的對象列表,根據ID列表進行排序。根據ID的相關列表重新排序集合
我沒有在Guava或Apache Commons中看到這種方法 - 但這正是我正在尋找的。具有良好實現的庫函數。
我有一個ID屬性的對象集合(無序)和ID(有序)列表。 該id列表沒有排序。我想創建我的集合中的對象列表,根據ID列表進行排序。根據ID的相關列表重新排序集合
我沒有在Guava或Apache Commons中看到這種方法 - 但這正是我正在尋找的。具有良好實現的庫函數。
這聽起來像你的id列表有它自己的順序;你不僅僅在使用自然順序,對吧?
這裏的番石榴解決方案:
Ordering.explicit(idList)
// constructs a "fluent Comparator" that compares elements in the
// explicitly specified order
.onResultOf(new Function<MyObject, Id>() {
public Id apply(MyObject o) { return o.getId(); }
}) // make this a Comparator<MyObject> that compares on IDs
.sortedCopy(myObjects); // get the sorted copy of the collection
就是這樣。沒有什麼。 (披露:我貢獻番石榴。)
或者,如果你知道ID都是唯一的,它可能只是說
Map<Id, MyObject> objectsById =
Maps.uniqueIndex(myObjects, GET_ID_FUNCTION); // defined elsewhere
List<MyObject> sortedObjects = Lists.newArrayList();
for (Id id : sortedIds)
sortedObjects.add(objectsById.get(id));
聽起來就像你有一個你想要的訂單,可能或不可能是數字上升/下降?
我會建議在下面製作自己的謂詞。 org.apache.commons.collections.CollectionUtils.find(java.util.Collection collection,
Predicatepredicate);
和循環在你的具體順序尋找在無序列表中的每個實際的對象。 N^2的解決方案
和創造性地運用java.util.collections.sort(List list, Comparator c)
,一個org.apache.find()和java.util.collections.swap(List list, int i, int j)
你可能會從N^2
遠閱讀ID的列表中,複製收集到一個新的以ID列表順序列出。
創建一個實現Comparable的類。在該課程中,根據您的ID排序列表進行排序。然後根據Comparable類定義一個TreeSet。下面顯示了一個非常簡單的例子。
例如,它會自動排序,根據您的MySort類
private Set<MyObject> mySet = new TreeSet<MyObject>;
mySet.add(new MyObject(12));
mySet.add(new MyObject(17));
當你做一個mySet.add():
public class MyObject implements Comparable<MyObject> {
private Integer id;
// a map of IDs to how they are ordered.
private static Map<Integer, Integer> idOrder = null;
public MyObject(Integer id) {
setId(id);
if (idOrder == null) {
idOrder = new HashMap<Integer, Integer>();
idOrder.put(17, 1);
idOrder.put(27, 2);
idOrder.put(12, 3);
idOrder.put(14, 4);
}
}
public int getId() {
return (this.id);
}
public void setId(int id) {
this.id = id;
}
public int compareTo(MyObject anotherThing) {
return (idOrder.get(this.getId()).compareTo(idOrder.get(anotherThing.getId())));
}
}
然後,定義和填充你的設置,像這樣。如果遍歷生成的TreeSet,則「17」條目將出現在「12」條目之前。
您可以:
隨着第一個解決方案,你必須修改你的對象,第二個你必須創建另一個類,但是你可以不修改你的對象。 <T>
是你的對象類。
如果你的無序輸入不超過集合更具體和你的ID列表中以任意順序(不是數字減少或類似的東西),你最簡單,最高效的方法可能就是這樣。成本是線性的,O(m + n),其中m是最初排序列表中的id數,n是要排序的值數。
Map<IDType, ValueType> keyed = new HashMap<IDType, ValueType>();
for (ValueType value : unsortedCollection) {
keyed.put(value.getId(), value);
}
List<ValueType> sorted = new ArrayList<ValueType>();
for (IDType id : sortedIds) {
ValueType value = keyed.get(id);
if (value != null) {
sorted.add(value);
}
}
這是我的第一個想法,如果我沒有找到清潔劑已經寫在圖書館。它可能是這個或者@Louis建議的。 – Eyal
聽起來像番石榴解決方案也會這樣做。除非性能很重要,否則我會選擇你認爲最可讀的任何東西。 –
這很有趣,也是我所期待的。 – Eyal
或者,如果您想對輸入列表進行就地排序,只需使用'Collections.sort(list,Ordering.explicit(idList).onResultOf(..))',因爲'Ordering'也是一個'Comparator' 。 –