代码先锋网 代码片段及技术文章聚合

Kotlin中的Map排序

示例代码如下:

fun main() {
    val map = sortedMapOf(1 to 2, 3 to 1, 2 to 3)
    println(map) // 输出:{1=2, 2=3, 3=1}
    println(map.javaClass.simpleName) // 输出:TreeMap
}

从上面例子可以看到,有序Map的实现类是TreeMap,它默认是对key进行升序排序。TreeMap的构造方法中可以接收一个比较器,是用于比较key的,所以如果我们希望降序,则可以通过传入比较器实现,代码如下:

fun main() {
    val comparator = kotlin.Comparator { key1: Int, key2: Int -> key2.compareTo(key1) }
    val map = TreeMap<Int, Int>(comparator)
    map[1] = 2
    map[3] = 1
    map[2] = 3
    println(map) // 输出:{3=1, 2=3, 1=2}
}

OK,上面代码实现了对key的降序排序。但是有时候,我们的排序需要value的参与,比如有如下数据结构:

/** 员工类 */
data class Employee(val name: String, val isOnline: Boolean)

如上是一个员工类,有姓名属性和在线状态属性,比如一个聊天软件,登录时是在线状态,离线时就是离线状态。

我们可以用一个List来表示 一个部门的所有员工,可以用一个Map<String, List>来表示一个公司多个部门的所有员工,代码示例如下:

fun main() {
    val 研发部人员列表 = listOf(Employee("01研发部张某某", false), Employee("01研发部王某某", false))
    val 销售部人员列表 = listOf(Employee("02销售部陈某某", true), Employee("02销售部李某某", false))
    val 售后部人员列表 = listOf(Employee("03售后部周某某", false), Employee("03售后部赵某某", true))

    val company = TreeMap<String, List<Employee>>()
    company["01研发部"] = 研发部人员列表
    company["02销售部"] = 销售部人员列表
    company["03售后部"] = 售后部人员列表

    company.forEach { key, value -> println(key) }
}

打印结果如下:

01研发部
02销售部
03售后部

这里打印的是部门的名称,可以看到默认是按部门名称进行升序排序的,此时我想按在线状态来排序部门,有在线状态员工的部门排在前面,如上3个部门中,研发部没有在线的人员,所以研发部应该是排在最后的,此时用key来做排序条件已经不能满足我们的需求了,Comparator对象只能对key进行排序,那如何实现使用value进行排序呢?答:自定义TreeMap的排序方法即可,但是查阅源码发现,compare方法是final类型的,不能覆盖,哎,看来TreeMap实现不了,因为它只能对key进行排序,除非我们把value的值也绑定到key中,但是这样的话,我们还不如直接使用List来实现,增加一个部门类,实现如下:

/** 员工类 */
data class Employee(val name: String, val isOnline: Boolean)

/** 部门类 */
data class Department(val name: String, val employeeList: List<Employee>)

这里的Department类就相当于TreeMap类,name属性对应TreeMap的key,employeeList属性对应TreeMap的value,然后我们把多个Department保存到List中,这样就可以对List进行排序了,排序的时候就可以使用到员工列表对象了,实现代码如下:

fun main() {
    val 研发部人员列表 = mutableListOf(Employee("01研发部张某某", false), Employee("01研发部王某某", false))
    val 销售部人员列表 = mutableListOf(Employee("02销售部陈某某", true), Employee("02销售部李某某", false))
    val 售后部人员列表 = mutableListOf(Employee("03售后部周某某", false), Employee("03售后部赵某某", true))

    val 研发部 = Department("01研发部", 研发部人员列表)
    val 销售部 = Department("02销售部", 销售部人员列表)
    val 售后部 = Department("03售后部", 售后部人员列表)

    val company = mutableListOf(研发部, 销售部, 售后部)

    // 对每一个部门的人员列表进行排序,在线的排前面,离线的排后面
    company.forEach { department ->
        department.employeeList.sortByDescending { it.isOnline }
    }

    // 对部门进行排序,有在线状态的部门排前面
    company.sortByDescending { department ->
        department.employeeList[0].isOnline
    }

    company.forEach { println(it) }
}

输出结果如下:

Department(name=02销售部, employeeList=[Employee(name=02销售部陈某某, isOnline=true), Employee(name=02销售部李某某, isOnline=false)])
Department(name=03售后部, employeeList=[Employee(name=03售后部赵某某, isOnline=true), Employee(name=03售后部周某某, isOnline=false)])
Department(name=01研发部, employeeList=[Employee(name=01研发部张某某, isOnline=false), Employee(name=01研发部王某某, isOnline=false)])

对于排序,还可以加入更多的逻辑,比如在线状态相同的员工,使用员工名称排序,在线状态相同的部门,使用部门名称排序,假设我们要实现状态相同时,使用名称的降序排序,实现代码如下:

company.forEach { department ->
    department.employeeList.sortWith(Comparator { employee1, employee2 ->
        if (employee1.isOnline != employee2.isOnline) {
            // 状态不相同,则按状态降序排序(即在线的排前面)
            employee2.isOnline.compareTo(employee1.isOnline)
        } else {
            // 状态相同,则按名称升序排序
            employee1.name.compareTo(employee2.name)
        }
    })
}

// 对部门进行排序,有在线状态的部门排前面
company.sortWith(kotlin.Comparator { department1, department2 ->
    if (department1.employeeList[0].isOnline != department2.employeeList[0].isOnline) {
        // 部门第一个员工的状态不相同,则按状态降序排序(即有在线员工的部门排前面)
        department2.employeeList[0].isOnline.compareTo(department1.employeeList[0].isOnline)
    } else {
        // 状态相同,则按部门名称升序排序
        department1.name.compareTo(department2.name)
    }
})

输出结果如下:

Department(name=02销售部, employeeList=[Employee(name=02销售部陈某某, isOnline=true), Employee(name=02销售部李某某, isOnline=false)])
Department(name=03售后部, employeeList=[Employee(name=03售后部赵某某, isOnline=true), Employee(name=03售后部周某某, isOnline=false)])
Department(name=01研发部, employeeList=[Employee(name=01研发部张某某, isOnline=false), Employee(name=01研发部王某某, isOnline=false)])

对于List的更多详细排序入门,可查看此文章:https://blog.csdn.net/android_cai_niao/article/details/108407853

版权声明:本文为android_cai_niao原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/android_cai_niao/article/details/108404797

智能推荐

Java中Map的排序

Map的种类 在Java中,Map的主要作用是存储键值对。由于是根据键得到值,所以不允许键重复。它主要有如下几个类别: HashMap: 最常用的Map,它根据键的HashCode值存储数据,根据键可以直接获取它的值,具有很快的访问速度,遍历时,取得数据的顺序是完全随机的。HashMap最多只允许一条记录的键为Null;允许多条记录的值为Null;HashMap不支持线程的同步,即任一时刻可以有多...

kotlin的Map集合

kotlin的Map集合 只读Map 可变的Map mutableMapOf kotlin的Map分为: 只读Map 意味着我们创建出来的map是不可变的,即我们只能使用无法改变我们map中的数据,我们只能获取集合中的数据而无法对集合中的数据进行新增和修改。 可变的Map mutableMapOf 可变集合意味着我们创建的集合是可以往集合里面添加数据、修改数据、删除数据、清空数据。 以下为执行的结...

kotlin 中的 "for" 循环和迭代map

文章目录 ● 场景 ● “for” 循环 ● 迭代map ● 总结 场景 kotlin 中的 “for” 循环和迭代 map 与我们熟知的 java 中的有什么区别呢,有哪些更好的表现形式呢? “for” 循环 ● kotlin “for”循环结构:for (i in a..b) ● a代表起始值,b代...

Kotlin 中list set map

给定一个字符串 ,转成想要的List 关键字:filterTo 和 -= List 元素怎么才算相等 MutableList 是可以进行写操作的 List ,关键词 shuffle() 大打乱次序 set Set的默认实现 - LinkedHashSet—— 保留元素插入的顺序 Map 的默认实现 – LinkedHashMap—— 迭代...

kotlin Map集合的遍历

1.Map : (1).获取键值对看k,v (2).创建...

猜你喜欢

java 对map中的 value 排序

此时是按照降序排序,如果想升序排序,则Comparator的 返回 改为obj1.getValue() - obj2.getValue();即可 总结:由于TreeMap主要是针对key进行默认排序的,但是有的时候我们需要对value进行排序,这时候主要采取的策略是 将map变为List,然后利用Collections.sort进行排序,同时重写Comparator方法,即可。...

Java 中 Map 的排序详解

Map 中有 HashMap、TreeMap、HashTable、LinkedHashMap,首先简单说一下他们之间的区别:   HashMap:最常用的Map,它根据键的HashCode 值存储数据,根据键可以直接获取它的值,具有很快的访问速度。HashMap最多只允许一条记录的键为Null(多条会覆盖);允许多条记录的值为 Null。非线程安全的。   TreeMap:能够...

按list中map的key排序

List<Map<String,Object>>按map的key排序   ...

根据Map中的value进行排序

根据Map中的value进行排序...