我有一个List<Brand> categories;
,包含1000多个项目。
对于我有id
列表中的每个项目,为了得到它我使用categories.getId();
我有一个数组int[] sortedIdArr = {4,53,102,403,110,5,6,8,12};
我想对categories
列表进行排序,并按id
按sortedIdArr
进行排序。
我该如何实现呢?
private void sortBrandsById(List<Brand> categories) {
Collections.sort(categories, new Comparator<Brand>() {
public int compare(Brand o1, Brand o2) {
}
});
}
我可以使用Collections.sort
吗?
答案 0 :(得分:2)
通常,您可以使用Collections.sort
或Java 8中的等效惯用语(如果适用),或使用排序Collection
(例如TreeSet
。
然而在这种情况下,您希望遵循由sortedIdArr
数组指定的预定义顺序。
实现这一目标的一种方法是使用链接集合(例如LinkedHashSet
)。
然后迭代sortedIdArr
数组,并在List<Brand>
中搜索具有给定ID的对象。
如果找到,则将具有给定ID的Brand
对象添加到LinkedHashSet
,这将保留插入顺序。
请注意,如果找不到ID,您的Set
将不会完全匹配&#34;数组。
自封闭示例,使用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;
}
}
}
答案 1 :(得分:1)
是您可以使用Collections.sort()
使用Brand
id
进行排序
public int compare(Brand o1, Brand o2) {
return o1.getId().compareTo(o2.getId());
}
使用ID为Brand
的数组对sortedIdArr
进行排序:
实施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]]
答案 2 :(得分:1)
您可以使用Collections.sort(...)
执行此操作但我强烈建议您不要在此情况下使用Comparator
方法使用此列表中的项目数。
您可以在List<Brand> categories
上设置循环,并将其添加到HashMap<Integer,Brand>
名为tempMap的地方。然后使用它按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)
复杂度更接近的方法更好的方法。
希望这会有所帮助。
答案 3 :(得分:0)
您可以使用以下代码(您需要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());
}
});
}
如果您能够将预定义的排序顺序放在不在数组中的列表中,则会更容易。