根据其他列表的顺序对列表进行排序

时间:2017-07-27 11:18:12

标签: java list sorting kotlin

我需要对Person个对象(List<Person>列表进行排序,其中每个Person对象的属性很少,如id(唯一),nameage ......等等。

排序顺序基于另一个列表。该列表包含一组Person id&#39; s(已排序的A List<String>)。

使用Kotlin或Java以List<Person>列表的顺序排序id的最佳方法是什么。

示例:

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;
}

4 个答案:

答案 0 :(得分:4)

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

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

然后按照此映射中people的顺序对id列表进行排序:

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

注意:如果某人拥有ids中不存在的ID,则会将其放在列表中的第一位。要将它们放在最后,您可以使用nullsLast比较器:

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

答案 1 :(得分:2)

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

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

如果您有地图(id-&gt; person)而不是listOfPersons,查找会更容易。

答案 2 :(得分:0)

请尝试以下代码。

 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将拥有您期望的值......

答案 3 :(得分:0)

以下代码会将Person列表转换为Map,其中key将是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)