根据另一个列表的顺序排序列表
我需要排序一个Person
对象List<Person>
( List<Person>
,其中每个Person
对象具有像id
(唯一), name
, age
等少数属性)。
排序顺序是基于另一个列表。 该列表包含一组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)