根据另一个列表的顺序排序列表

我需要排序一个Person对象List<Person>List<Person> ,其中每个Person对象具有像id (唯一), nameage等少数属性)。

排序顺序是基于另一个列表。 该列表包含一组Person id (已被排序的List<String> )。

使用Kotlin或Java以与id列表相同的顺序排列List<Person>的最好方法是什么?

例:

 List Person { (“ID1”,”PERSON1”,22,..), (“ID-2”,”PERSON2”,20,..) ), (“ID-3”,”PERSON3”,19,..),….. } 

有序Id列表:

 List of ID {(“ID2”), (“ID1”),(”ID3”)….} 

排序Person列表应该是:

 List PERSON { (“ID-2”,”PERSON 2”,20,..) ), (“ID1”,”PERSON 2”,22,..), (“ID-3”,”PERSON 2”,19,..),….. } 

如果Person列表包含id列表中没有提到的任何id ,那么这些值应该在排序列表的末尾。


编辑:这是我目前在Java中的方式。 我希望有一个比这更好的方法:

 public static List<Person> getSortList(List <Person> unsortedList, List<String> orderList){ if(unsortedList!=null && !unsortedList.isEmpty() && orderList!=null && !orderList.isEmpty()){ List sortedList = new ArrayList<OpenHABWidget>(); for(String id : orderList){ Person found= getPersonIfFound(unsortedList, id); // search for the item on the list by ID if(found!=null)sortedList.add(found); // if found add to sorted list unsortedList.remove(found); // remove added item } sortedList.addAll(unsortedList); // append the reaming items on the unsorted list to new sorted list return sortedList; } else{ return unsortedList; } } public static Person getPersonIfFound(List <Person> list, String key){ for(Person person : list){ if(person.getId().equals(key)){ return person; } } return null; } 

我会做类似的(伪代码,因为我不知道你的代码是什么样子)

 listOfPersons = [{2,Bob},{3,Claire},{1,Alice}] orderList = [1,3,2] sortedList = [] for(id in orderList) person = listOfPersons.lookup(id) sortedList.add(person) 

如果你有一个map(id-> person)而不是listOfPersons,查找会更容易。

一个有效的解决方案是首先创建从ids (您想要的ID顺序)中的ID到该列表中的索引的映射:

 val orderById = ids.withIndex().associate { it.value to it.index } 

然后在这个映射中按照他们的id顺序排列你的people列表:

 val sortedPeople = people.sortedBy { orderById[it.id] } 

注意:如果一个人的ID不在ids ,他们将被放在列表中。 要放置最后一个,可以使用nullsLast比较器:

 val sortedPeople = people.sortedWith(compareBy(nullsLast<String>) { orderById[it.id] }) 

尝试下面的代码。

  Map<String, Person> personMap=new HashMap<>(); // create a map with key as ID and value as Person object List<String> orderList=new ArrayList<>(); // create a list or array with ID order List<Person> outputList=new ArrayList<>(); //list to hold sorted values //logic // to sort Person based on ID list order for (String order : orderList) { if(personMap.containsKey(order)){ outputList.add(personMap.get(order)); personMap.remove(order); } } // logic to add the Person object whose id is not present in ID order list for (Entry<String, Person> entry : personMap.entrySet()) { int lastIndex=outputList.size(); outputList.add(lastIndex, entry.getValue()); lastIndex++; } 

现在, outputList将具有您所期望的值…

下面的代码将Person列表转换为Map ,其中键将是ID,值将是Person对象本身。 此Map将有助于快速查找。 然后迭代ID的列表,从Map获取值并添加到另一个List

 fun main(args: Array<String>) { // List of ID val listId = listOf(2, 1, 3) val list = listOf(Person(id = 1, name = "A"), Person(id = 2, name = "B"), Person(id = 3, name = "C")) val map: Map<Int, Person> = list.associateBy ({it.id}, {it}) val sortedList = mutableListOf<Person>() listId.forEach({ sortedList.add(map[it]!!) }) sortedList.forEach({ println(it) }) } data class Person(val id: Int, val name: String) 

产量

 Person(id=2, name=B) Person(id=1, name=A) Person(id=3, name=C)