[英]Sort List of Objects by values from array;
我有一個List<Brand> categories;
有1000多個項目。
對於我有id
的列表中的每個項目,為了得到它我使用categories.getId();
我有一個數組int[] sortedIdArr = {4,53,102,403,110,5,6,8,12};
我想對我的categories
列表進行排序, sortedIdArr
id
在sortedIdArr
中進行sortedIdArr
。 我該如何實現呢?
private void sortBrandsById(List<Brand> categories) {
Collections.sort(categories, new Comparator<Brand>() {
public int compare(Brand o1, Brand o2) {
}
});
}
我可以使用Collections.sort
嗎?
通常,您將使用Collections.sort
或Java 8中的等效慣用語(如果適用),或者使用排序的Collection
(如TreeSet
。
但是,在這種情況下,您希望遵循由sortedIdArr
數組指定的預定義順序。
實現這一目標的一種方法是使用鏈接集合(例如LinkedHashSet
)。
然后迭代您的sortedIdArr
數組,並在List<Brand>
搜索具有給定ID的對象。
如果找到,則將具有給定ID的Brand
對象添加到LinkedHashSet
,這將保留插入順序。
請注意,如果找不到ID,則您的Set
將不會與陣列完全“匹配”。
自封閉示例,使用Java 8
package test;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Optional;
import java.util.Set;
public class Main {
// simplified Brand pojo
static class Brand {
int id;
public Brand(int id) {
this.id = id;
}
public int getId() {
return id;
}
// for output clarity
@Override
public String toString() {
return String.format("Brand: %d", id);
}
}
public static void main(String[] args) throws Exception {
// simplified ID list
int[] sortedIdArr = {4,53,102};
// "randomly" ordered Brand list
final List<Brand> categories = new ArrayList<Brand>() {
{
add(new Brand(1));
add(new Brand(102));
add(new Brand(53));
add(new Brand(4));
add(new Brand(0));
}
};
// destination: linked set
Set<Brand> linked = new LinkedHashSet<Brand>();
// streaming the ID array in order
Arrays.stream(sortedIdArr)
.forEach((i) -> {
// retrieving a Brand with same ID as the current
// from the "randomly" ordered list
Optional<Brand> toAdd = categories.stream()
.filter((b) -> b.getId() == i)
.findFirst();
// making sure there's one
if (toAdd.isPresent()) {
// adding to linked set
linked.add(toAdd.get());
}
}
);
System.out.println(linked);
}
}
產量
[Brand: 4, Brand: 53, Brand: 102]
舊Java版本的命令式成語
for (int i: sortedIdArr) {
for (Brand b: categories) {
// assuming no nulls
if (b.getId() == i) {
linked.add(b);
break;
}
}
}
是的你可以使用Collections.sort()
要使用id
對您的Brand
進行排序:
public int compare(Brand o1, Brand o2) {
return o1.getId().compareTo(o2.getId());
}
要使用id sortedIdArr
數組對您的Brand
進行排序:
實現Comparator
類:
class C implements Comparator<A> {
int[] idOrder;
public C(int[] idOrder) {
super();
this.idOrder = idOrder;
}
@Override
public int compare(A o1, A o2) {
Integer indexofO1 = Arrays.binarySearch(idOrder, o1.getId());
Integer indexofO2 = Arrays.binarySearch(idOrder, o2.getId());
return indexofO1.compareTo(indexofO2);
}
}
這里的關鍵思想是反轉過程並使用id的索引而不是id本身進行比較!
要使用它:
Collections.sort(list, new C (idOrder));
測試示例:
int[] idOrder = new int [] {3,1,2};
List<A> list = new ArrayList<>();
list.add(new A(1));
list.add(new A(2));
list.add(new A(3));
System.out.println(list);
//Output : [A [id=1], A [id=2], A [id=3]]
Collections.sort(list, new C(idOrder));
System.out.println(list);
//Output : [A [id=3], A [id=1], A [id=2]]
您可以使用Collections.sort(...)
執行此操作,但強烈建議您不要在列表中使用此項目數的情況下使用Comparator
方法。
您可以在List<Brand> categories
上創建一個循環,並將它們添加到名為tempMap的HashMap<Integer,Brand>
。 然后使用它按sortedIdArr
數組的順序查找它們。 像這樣更改排序方法:
private void sortBrandsById(List<Brand> categories, int [] sortedIdArr) {
HashMap<Integer,Brand> tempMap = new HashMap<Integer, Brand>(categories.size());
for (int i = 0; i < categories.size(); i++) {
tempMap.put(categories.get(i).getId(), categories.get(i));
}
categories = new ArrayList<Brand>(sortedIdArr.length);
for (int i = 0; i < sortedIdArr.length; i++) {
categories.add(tempMap.get(sortedIdArr[i]));
}
}
這種排序方式來自訂單O(n)
用於創建tempMap
+ O(n)
以重新創建category
列表。 雖然, O(1)
不能保證HashMap的get / put操作,但java的體面哈希實現非常好且可靠。 因此總復雜度不能比O(n)
大得多。 至少它比O(n^2)
好得多。 時間復雜度非常重要,我認為你不能找到比O(n)
復雜度更接近的方法。
希望這會有所幫助。
您可以使用以下代碼(您需要Apache commons lang jar - 否則您必須遍歷數組才能找到索引)。
private static void sortBrandsById(List<Brand> categories,int[] array) {
Collections.sort(categories, new Comparator<Brand>() {
public int compare(Brand o1, Brand o2) {
return ArrayUtils.indexOf(array,o1.getId())-ArrayUtils.indexOf(array,o2.getId());
}
});
}
如果您能夠將預定義的排序順序放在不在數組中的列表中,則會更容易。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.