在Java中,如何最好地使用一个ArrayList的顺序来排序另一个ArrayList?

在Java中,如何最好地使用一个ArrayList的顺序来排序另一个ArrayList?,java,arraylist,Java,Arraylist,对于我目前正在开发的Java应用程序,我使用的是一个ID系统,每个ID都是一个唯一的字符串。我有两个数组列表,一个是一个ArrayList,它只按正确的顺序保存ID,另一个是一个对象数组列表,所有对象都有一个.ID字段。对对象数组列表进行排序的最佳方法是什么,以便它们的ID与字符串ID数组列表的顺序相同?只是一般的想法(无编译器) 公共类MyListComparator实现Comparator{ 私有数组列表ID; 公共MyListComparator(ArrayList ID) { this.

对于我目前正在开发的Java应用程序,我使用的是一个ID系统,每个ID都是一个唯一的字符串。我有两个数组列表,一个是一个
ArrayList
,它只按正确的顺序保存ID,另一个是一个对象数组列表,所有对象都有一个.ID字段。对对象数组列表进行排序的最佳方法是什么,以便它们的ID与字符串ID数组列表的顺序相同?

只是一般的想法(无编译器)

公共类MyListComparator实现Comparator{
私有数组列表ID;
公共MyListComparator(ArrayList ID)
{
this.ids=ids;
}
@凌驾
公共整数比较(MyObject o1,MyObject o2){
整数i1=ids.indexOf(o1.id);
整数i2=ids.indexOf(o2.id);
返回i1。比较(i2);
}
}
只是一般的想法(没有编译器)

公共类MyListComparator实现Comparator{
私有数组列表ID;
公共MyListComparator(ArrayList ID)
{
this.ids=ids;
}
@凌驾
公共整数比较(MyObject o1,MyObject o2){
整数i1=ids.indexOf(o1.id);
整数i2=ids.indexOf(o2.id);
返回i1。比较(i2);
}
}
分配第三个列表。O(n^2)解决方案是迭代具有有序ID的列表。在这个循环中,有另一个循环来查找ID==在第一个循环/列表中找到的当前ID的对象。提取此项目并将其添加到第三个列表:

for (ID in List<ID>)
    for (Item item in List<Item>){
        if (item.ID == ID){
            list3.add(item);
        }
    }
for(列表中的ID)
用于(列表中的项目){
如果(item.ID==ID){
清单3.添加(项目);
}
}
可怕的算法。我建议你设计你的数据结构。使用地图或比较器。

分配第三个列表。O(n^2)解决方案是迭代具有有序ID的列表。在这个循环中,有另一个循环来查找ID==在第一个循环/列表中找到的当前ID的对象。提取此项目并将其添加到第三个列表:

for (ID in List<ID>)
    for (Item item in List<Item>){
        if (item.ID == ID){
            list3.add(item);
        }
    }
for(列表中的ID)
用于(列表中的项目){
如果(item.ID==ID){
清单3.添加(项目);
}
}

可怕的算法。我建议你设计你的数据结构。使用映射或比较器。

我将使用ID作为键将所有对象放在HashMap中,然后运行第二个ID列表,并使用ID和map创建新的对象列表。应具有2n->n左右的复杂度,而不是资源友好型

编辑:明确我的意思

List<String> idList;
List<ObjectWithID> objectList;

Map<String, ObjectWithID> helperMap=new HashMap<>();

//first O(n)
for (ObjectWithID o:objectList) {
  helperMap.put(o.ID, o);
}

int i=0;
//second O(n)
for (String id:idList) {
  objectList.set(i,helperMap.get(id));
  i++;
}
列表空闲列表;
列表对象列表;
Map helperMap=newhashmap();
//第一个O(n)
对于(ID为o:objectList的对象){
助手映射put(o.ID,o);
}
int i=0;
//第二O(n)
for(字符串id:idList){
set(i,helperMap.get(id));
i++;
}

假设objectList和idList具有相同的大小和相同的ID/object.ids resp.

我将使用它们的ID作为键将所有对象放在HashMap中,然后运行第二个ID列表,并使用ID和map创建对象的新列表。应具有2n->n左右的复杂度,而不是资源友好型

编辑:明确我的意思

List<String> idList;
List<ObjectWithID> objectList;

Map<String, ObjectWithID> helperMap=new HashMap<>();

//first O(n)
for (ObjectWithID o:objectList) {
  helperMap.put(o.ID, o);
}

int i=0;
//second O(n)
for (String id:idList) {
  objectList.set(i,helperMap.get(id));
  i++;
}
列表空闲列表;
列表对象列表;
Map helperMap=newhashmap();
//第一个O(n)
对于(ID为o:objectList的对象){
助手映射put(o.ID,o);
}
int i=0;
//第二O(n)
for(字符串id:idList){
set(i,helperMap.get(id));
i++;
}

假设objectList和idList具有相同的大小和相同的ID/object.ids resp.

为什么不按ID分别对这两个列表进行排序呢

制作一个比较器对字符串列表进行排序,然后制作另一个比较器对对象上的
.ID
字段进行比较。对两个列表分别排序,只要两个列表都是1对1就可以了


不可否认,这是对你试图做什么做了大量的假设。如果这不能实现您想要的,您可能应该在问题中更具体地说明您想要实现的目标。

为什么不按ID分别对两个列表进行排序呢

制作一个比较器对字符串列表进行排序,然后制作另一个比较器对对象上的
.ID
字段进行比较。对两个列表分别排序,只要两个列表都是1对1就可以了

不可否认,这是对你试图做什么做了大量的假设。如果这不能实现您想要的目标,您可能应该在问题中更具体地说明您想要实现的目标。

免责声明:您没有提到为什么需要订购这些条目,但如果只是为了ID匹配目的,您可能应该重新设计应用程序,以便从一开始就按照HashMap或TreeMap的方式使用某些东西

这是一个可能的解决方案,准备的复杂性为
O(n)
实际排序的复杂性为
O(n*log(n))

class MyEntry {
   public String id;
}

ArrayList<String> idList = new ArrayList<String>();
ArrayList<MyEntry> entryList = new ArrayList<MyEntry>();

final HashMap<String, Integer> index = new HashMap<String, Integer>();

// Match each ID to its index
for (int i = 0; i < idList.size(); ++i) {
    index.put(idList.get(i), i);
}

Collections.sort(entryList, new Comparator<MyEntry>() {
    public int compare(MyEntry o1, MyEntry o2) {
        return index.get(o1.id) - index.get(o2.id);
    }
});
MyEntry类{
公共字符串id;
}
ArrayList idList=新的ArrayList();
ArrayList entryList=新的ArrayList();
最终HashMap索引=新HashMap();
//将每个ID与其索引匹配
对于(int i=0;i
免责声明二:我没有实际运行此代码,但它应该可以工作

编辑:

为了记录在案,我太过专注于寻找一种对原始条目列表进行排序的方法。 对于这个特定的用例,该方法更简单、更快

只有当未来的需求需要根据条目的ID快速恢复其索引时,我的方法才具有优势。

免责声明:您没有提到为什么需要订购这些条目,但如果只是为了ID匹配目的,您可能应该重新设计应用程序,以便从一开始就按照HashMap或TreeMap的方式使用某些东西

这里有一个可能的解决方案,使用
O(n)public class TwoLists {
    public static void main(String[] args) {
        ArrayList<String> idList = new ArrayList<String>();
        ArrayList<Person> personList = new ArrayList<Person>();

        idList.add("1");
        idList.add("2");
        idList.add("3");
        idList.add("4");

        TwoLists twoLists = new TwoLists();

        personList.add(twoLists.createPerson("4", "Name4"));
        personList.add(twoLists.createPerson("2", "Name2"));
        personList.add(twoLists.createPerson("3", "Name3"));
        personList.add(twoLists.createPerson("1", "Name1"));

        System.out.println("Before Sorting:");
        for(Person person: personList) {
            System.out.println(person.getId());
        }

        Collections.sort(personList, twoLists.new TwoListsComparator(idList));

        System.out.println("After Sorting:");
        for(Person person: personList) {
            System.out.println(person.getId());
        }
    }

    private class TwoListsComparator implements Comparator<Person> {
        ArrayList<String> idList;

        private TwoListsComparator(ArrayList<String> idList) {
            this.idList = idList;
        }

        public int compare(Person person1, Person person2) {
            int index1 = idList.indexOf(person1.getId());
            int index2 = idList.indexOf(person2.getId());

            return Integer.valueOf(index1).compareTo(index2);
        }
    }

    private Person createPerson(String id, String name) {
        Person p = new Person();
        p.setId(id);
        p.setName(name);

        return p;
    }
}