按数组中的值排序对象列表;

时间:2016-01-27 12:49:15

标签: java arrays list sorting

我有一个List<Brand> categories;,包含1000多个项目。

对于我有id列表中的每个项目,为了得到它我使用categories.getId();

我有一个数组int[] sortedIdArr = {4,53,102,403,110,5,6,8,12};

我想对categories列表进行排序,并按idsortedIdArr进行排序。 我该如何实现呢?

private void sortBrandsById(List<Brand> categories) {
    Collections.sort(categories, new Comparator<Brand>() {
        public int compare(Brand o1, Brand o2) {

        }
    });    
}

我可以使用Collections.sort吗?

4 个答案:

答案 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());
                }
            });    
        }

如果您能够将预定义的排序顺序放在不在数组中的列表中,则会更容易。