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