【Kotlin精简】第2章 集合

news2024/7/6 18:14:11

1 简介

在 Kotlin 中集合主要分为可变集合只读集合,其中可变集合使用 “Mutable” 前缀 + 集合类名表示,比如 MutableListMutableSetMutableMap 等。而对于只读集合就是和 Java 中集合类名是一致。 Java 中的 List 非 Kotlin 中的 List , 因为 Kotlin 中的 List 是只读的而非可变,却有点类似于 Kotlin 中的 MutableList
在这里插入图片描述

  1. 只读集合:
    内部只具有访问元素的方法,不具有类似 add、remove、clear 之类修改集合的方法。比如 Collection 只读集合内部就没有 add、remove、clear 之类方法,只有 get 访问元素的方法.
  2. 可变集合
    在集合内部既具有访问元素的方法,也具有类似 add、remove、clear 之类修改集合的方法。比如 MutableCollection 可变集合内部就有 addremoveclear 之类方法。

集合是可变数量的一组条目。
List : 是有序集合,可以通过下标访问元素,元素可以重复。
Set : 是无序集合,有别于List集合的地方在于,1.没有下标,2.元素不允许重复。只能遍历获取参数,遍历参数的顺序与添加顺序相同。元素如果已经存在不进行添加。可以存储Null, 而且Null也是唯一的。
Map:是无序集合,通过键值对存储数据。每个键唯一。值可以重复。

集合主要就是ListSetMap,它们在Java中都有接口可以实现,
List --> ArrayList、LinkedList
Set --> HashSet
Map–> HashMap

1.1 List集合

	val list = ArrayList<String>()
	list.add("1")
	list.add("2")
	
	// 创建的是一个不可变的集合,该集合创建成功只能用于读取数据,不能增删改集合数据。
	val list1 = listOf("aa", "bb")
	// 创建的是一个可变的集合,可以进行增删改查操作。
	val list2 = mutableListOf("cc", "dd")
	
	// 遍历List集合需要使用for-in循环进行遍历
	for (content in list1){
		// 把遍历内容大写
		content.toUpperCase()
		print(content)	// 输出:aa bb
	}
	
	list2.add("ee")
	list2.addAll(list1)
	// 移除指定的元素对象。如果指定元素不存在,移除null。不会报错
	list2.remove("ee")
	// 移除参数集合中存在的所有元素。 
   	// 或者,你可以关键字作为参数来调用它;在这种情况下,函数移除关键字匹配true 的所有元素。
	list2.removeAll(list1)
	// retainAll() 与 removeAll() 相反,
   	// 它移除除参数集合中的元素之外的所有元素。
   	// 当与关键字一起使用时,它只留下与关键字匹配的元素。
	list2.retainAll(list)

1.2 Set集合

Set和List的用法其实一样,在初始化时会用到这几个方法:setof()mutableSetOf()

	// 不可变的集合
	val set1 = setOf("aa", "bb") 
	// 可变的集合
	val set2 = mutableSetOf("cc", "dd") 

	// 新增元素
   	set2.add("ee")
   	set2.addAll(set1)
   	
	// 移除指定的元素对象。如果指定元素不存在,移除null。不会报错
   	set2.remove("ee")
   	// 移除参数集合中存在的所有元素。 
   	// 或者,你可以关键字作为参数来调用它;在这种情况下,函数移除关键字匹配true 的所有元素。
   	set2.removeAll(set1)
   	// retainAll() 与 removeAll() 相反,
   	// 它移除除参数集合中的元素之外的所有元素。
   	// 当与关键字一起使用时,它只留下与关键字匹配的元素。
   	set2.retainAll(set1)

setof():创建的是一个不可变的集合,该集合创建成功只能用于读取数据,不能增删改集合数据。
mutableSetOf():创建的是一个可变的集合,可以进行增删改查操作。
在这里,Set集合List集合的区别需要注意的是,Set底层是使用Hash映射机制来存储数据的,因此集合中的元素无法保证有序。
----遍历和List一样,就不做解释了

1.3 Map集合

Map集合这里重点介绍,Map和前两者不同,Map是一种键值对形式的数据结构,因此在用法上和List、Set存在很大不同。
一般初始化Map时都需要创建一个HashMap

val map = HashMap<String, String>()
map.put("aa", "1")
map.put("bb", "2")

// 因为在Kotlin中,并不建议使用put()、get()方法对Map进行添加和读取数据,
// 而是使用这种类似下标的方式添加数据:
val map1 = HashMap<String, Int>()
map1["aa"] = 1
map1["bb"] = 2

// 当读取数据时
val text = map1["aa"]

// 移除对应的值,参数为key
map1.remove("aa")

然而,上面这种添加数据方式依然很繁琐,和List、Set一样,Map也有自己的方法mapof()、mutableMapOf()

// 不可变
val map1 = mapOf("aa" to 1, "bb" to 2)  
// 可变
val map2 = mutableMapOf("aa" to 1, "bb" to 2)  

mapof():创建的是一个不可变的集合,该集合创建成功只能用于读取数据,不能增删改集合数据。
mutableMapOf():创建的是一个可变的集合,可以进行增删改查操作。
遍历Map集合,也是使用的for-in循环,唯一区别在于,for-in循环中,map键值对变量一起申明到了一对括号中

fun main(){
    val map1 = mapOf("aa" to 1, "bb" to 2) 
    for ((content1, content2) in map1){
        print(content1 + "--" + content2)
    }
}

1.4 集合迭代器 Iterator

提供一种遍历集合元素的方法,而不暴露集合内部的实现。

1.4.1 迭代器的方式

只要实现了Iterable接口的类型,都提供迭代器。
下面是使用迭代器的3种方式:

  1. 使用next()
val numbers = listOf("one", "two", "three", "four")
val numbersIterator = numbers.iterator()
while (numbersIterator.hasNext()) {
    println(numbersIterator.next())
}
  1. 使用for…in
val numbers = listOf("one", "two", "three", "four")
for (item in numbers) {
    println(item)
}
  1. 使用forEach()
val numbers = listOf("one", "two", "three", "four")
numbers.forEach {
    println(it)
}

1.4.2 List 的迭代器

List 的迭代器是ListIterator类型,可以反向迭代:

val numbers = listOf("one", "two", "three", "four")
val listIterator = numbers.listIterator()
while (listIterator.hasNext()) listIterator.next()
println("Iterating backwards:")
while (listIterator.hasPrevious()) {
    print("Index: ${listIterator.previousIndex()}")
    println(", value: ${listIterator.previous()}")
}

// Iterating backwards:
// Index: 3, value: four
// Index: 2, value: three
// Index: 1, value: two
// Index: 0, value: one

1.4.3 可变迭代器

可变集合(MutableList, MutableSet, MutableMap)的迭代器都是MutableIterator类型,可以在迭代的过程中调用remove()方法删除元素。

val numbers = mutableListOf("one", "two", "three", "four") 
val mutableIterator = numbers.iterator()

mutableIterator.next()
mutableIterator.remove()

println("After removal: $numbers")
// After removal: [two, three, four]

另外,MutableList的迭代器是MutableListIterator类型,可以在迭代过程中插入替换元素。

val numbers = mutableListOf("one", "four", "four") 
val mutableListIterator = numbers.listIterator()

mutableListIterator.next()
mutableListIterator.add("two")
mutableListIterator.next()
mutableListIterator.set("three")

println(numbers)
// [one, two, three, four]

1.5 集合Range

使用rangeTo()可以创建范围,rangeTo()对应的操作符:…。

// 遍历范围
for (i in 1..4) print(i)

// 反序遍历:
for (i in 4 downTo 1) print(i)

// 反序遍历2:
for (i in (1..4).reversed()) print(i)

// 定义步长:
for (i in 1..8 step 2) print(i)

// 不包含末尾元素:
for (i in 1 until 10) print(i)

1.6 集合序列 Sequence

序列和迭代器的差别
Iterable遍历执行多步操作时,会先对所有元素执行一个步骤,将结果保存到中间集合中,然后再对中间集合中所有元素执行下一个步骤,以此类推。相当于,所有元素被并行处理。

Sequence遍历执行多步操作时,会对一个元素执行所有步骤,然后再对下一个元素执行所有步骤,以此类推。相当于,所有元素被串行处理。

// 1.通过元素创建
val s1 = sequenceOf(1, 2, 3)

// 2.通过Iterable创建
val list = listOf(1,2,3)
val s2 = list.asSequence()

// 3.通过generateSequence()函数创建

// 4.通过sequence()创建


// 例子:假设有很多单词,我们要过滤长度超过3个字母的单词,然后打印前4个这种单词的长度。
// Iterable的方式
val words = "The quick brown fox jumps over the lazy dog".split(" ")
val lengthsList = words.filter { println("filter: $it"); it.length > 3 }
    .map { println("length: ${it.length}"); it.length }
    .take(4)
println("Lengths of first 4 words longer than 3 chars:")
println(lengthsList)

// Sequence的方式
val words = "The quick brown fox jumps over the lazy dog".split(" ")
// 将 List 转换为序列
val wordsSequence = words.asSequence()
val lengthsSequence = wordsSequence.filter { println("filter: $it"); it.length > 3 }
    .map { println("length: ${it.length}"); it.length }
    .take(4)
println("Lengths of first 4 words longer than 3 chars")
// 终止操作: 以 List 形式获取结果
println(lengthsSequence.toList())
  1. filter()map()take()这些操作,在调用toList()后才开始执行。与上面Iterable相比,是”lazy“的。
  2. 当结果元素数量到达4个时,会停止处理,因为take(4)指定了最大元素数量。与上面Iterable相比,节省了操作步骤。
  3. Sequence处理执行了 18 步,而使用Iterable时则需要 23 步。

1.7 常用的集合函数式API

1.7.1 map()函数

它用于将每个元素都映射成一个另外的值,映射规则在Lambda表达式中指定,最终生成一个新的集合,

val list1 = listOf("aa", "bb") 
var newList = list1.map{ it.toUpperCase()}
for (content in list1){
    content.toUpperCase() //转换成大写模式
}

1.7.2 filter()函数

用于过滤集合中的数据,可以单独使用,也可以和map()一起使用

val list1 = listOf("aa", "bbbb", "cc") 
var list2 = list1.filter { it.length <= 2 }
                         .map { it.toUpperCase() }

1.7.3 any()函数

判断集合中是否至少存在一个元素满足指定条件

val list1 = listOf("aa", "bbbb", "cc") 
var anyResult = list1.any { it.length <= 2 }

1.7.4 all()函数

判断集合中是否所有元素都满足指定条件

val list1 = listOf("aa", "bbbb", "cc") 
var allResult = list1.all { it.length <= 2 }

1.7.5 maxBy()函数

定义一个集合,然后找出里面长度最长的元素,maxBy的工作原理是根据传入的条件来进行遍历,从而找打最大值

val list1 = listOf("aa", "bbbb", "cc") 
var maxLength = list1.maxBy { it.length }
print(maxLength)

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1069654.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

深度学习——权重衰减(weight_decay)

深度学习——权重衰减&#xff08;weight_decay) 文章目录 前言一、权重衰减1.1. 范数与权重衰减1.2. 高维线性回归1.3. 从零开始实现1.3.1.初始化模型参数1.3.2. 定义L₂范数惩罚1.3.3. 定义训练代码实现1.3.4. 不管正则化直接训练1.3.5. 使用权重衰减 1.4. 简洁实现 总结 前言…

寒露到了,冬天还会远吗?

寒露惊秋晚&#xff0c;朝看菊渐黄。 日复一日间&#xff0c;光影如梭&#xff0c;我们便很快将告别了秋高气爽&#xff0c;白日将变得幽晦&#xff0c; 天寒夜长&#xff0c;风气萧索&#xff0c;雾结烟愁。 还没好好体会秋高气爽,寒露就到了。 今天晚上9点多&#xff0c;我们…

成都直播产业未来发展新方向一览,又一大型直播基地入驻成都!

成都直播产业正迎来一股蓬勃发展的新浪潮&#xff0c;展现出无限的潜力和前景。最新消息显示&#xff0c;又一座大型直播基地——成都天府蜂巢直播产业基地即将入驻成都&#xff0c;为这座城市的直播产业注入了新的动力和活力。 天府蜂巢 行业模范 成都天府蜂巢直播产业基地采…

LLMs 入门实战系列

link 【LLMs 入门实战系列】 【LLMs 入门实战系列】交流群 (注&#xff1a;人满 可 添加 小编wx&#xff1a;yzyykm666 加群&#xff01;) 【LLMs 入门实战系列】 第一层 LLMs to Natural Language Processing (NLP) 第一重 ChatGLM-6B 系列 ChatGLM-6BChatGLM2-6B 第十一重 L…

WebSocket ----苍穹外卖day8

介绍 实现步骤 各个模块详解 OnOpen OnOpen:标记一个方法作为处理WebSocket连接打开的方法 当一个客户端与服务器建立 WebSocket 连接时&#xff0c;服务器会接收到一个连接请求。一旦服务器接受了这个连接请求&#xff0c;一个 WebSocket 连接就会被建立。这时&#xff0c;被…

Eclipse iceoryx™ - 真正的零拷贝进程间通信

1 序言 通过一个快速的背景教程&#xff0c;介绍项目范围和安装所需的所有内容以及第一个运行示例。 首先&#xff1a;什么是冰羚&#xff1f; iceoryx是一个用于各种操作系统的进程间通信&#xff08;IPC&#xff09;中间件&#xff08;目前我们支持Linux、macOS、QNX、FreeBS…

一文搞懂频率响应中的相位响应与信号在时域变化的关系

我们知道一个信号通过一个系统后&#xff0c;输出信号的频谱输入信号的频谱*传递函数的频谱 那么衡量输出信号与输入信号的关系通常是考虑他们的幅度和相位。即&#xff1a;传递函数的相位相应和幅度响应。幅度响应好理解&#xff0c;即输出信号相比于输入信号幅值放大多少倍。…

时空智友企业流程化管控系统 sessionid泄露漏洞 复现

文章目录 时空智友企业流程化管控系统 sessionid泄露漏洞 复现0x01 前言0x02 漏洞描述0x03 影响平台0x04 漏洞环境0x05 漏洞复现1.访问漏洞环境2.构造POC3.复现 时空智友企业流程化管控系统 sessionid泄露漏洞 复现 0x01 前言 免责声明&#xff1a;请勿利用文章内的相关技术从…

Django开发之初识篇

Django初识篇 前言一、Django 框架介绍二、Django 项目初始化方式一&#xff1a;Windows通过CMD创建并初始化项目方式二&#xff1a;Pycharm 总结 前言 通过Django初识篇、基本篇、进阶篇来学习Django&#xff0c;并能快速开发一个中型的Web网站。 一、Django 框架介绍 Djan…

【IEEE会议征稿】第三届IEEE电气工程与控制科学国际学术会议(IC2ECS 2023)

第三届IEEE电气工程与控制科学国际学术会议&#xff08;IC2ECS 2023&#xff09; 2023 3rd International Conference on Electrical Engineering and Control Science 第三届电气工程与控制科学国际学术会议 (IC2ECS 2023) 定于2023年12月1日在中国杭州召开。会议主要围绕“…

【RHAL】板子烧widevine key

前言&#xff1a;国庆回来工作后很懵逼…又遇见了新问题&#xff0c;因为旧板子烧坏了&#xff0c;新板子系统没带widevine key&#xff0c;我用旧板子命令烧pass&#xff0c;新板子apk烧就fail。 又接触到了新的领域&#xff0c;新名词。不错的&#xff0c;甲方乙方一起带我学…

Flink---13、容错机制(检查点(保存、恢复、算法、配置)、状态一致性、端到端精确一次)

星光下的赶路人star的个人主页 大鹏一日同风起&#xff0c;扶摇直上九万里 文章目录 1、容错机制1.1 检查点&#xff08;CheckPoint&#xff09;1.1.1 检查点的保存1.1.2 从检查点恢复状态1.1.3 检查点算法1.1.3.1 检查点分界线&#xff08;barrier&#xff09;1.1.3.2 分布式快…

elasticsearch基本语法

这里写自定义目录标题 elasticsearch简介基本语法索引创建索引修改索引删除索引 查询简单查询精确查询条件查询范围查询&#xff1a;聚合查询&#xff1a;排序和分页&#xff1a; 参考文献&#xff1a; elasticsearch简介 Elasticsearch 是一个开源的分布式搜索和分析引擎&…

地震勘探——相关概念(一)

地震波的基本介绍 波前&#xff1a;波在同一时刻所到达的点所构成的面&#xff0c;这个面上构成的相位是相同的。波前的形状取决于传播介质的物理性质。我们可以用地震波动方程模拟波前变化&#xff08;波场快照&#xff09;。 射线&#xff08;Ray&#xff09;&#xff1a;是…

java API 包装类Integer,int和String互相转换

integer类 package daysreplace;import com.sun.jdi.IntegerValue;import java.util.Arrays;public class Test {public static void main(String[] args) { //Integer a new Integer(29);//过时Integer b new Integer("30");//过时System.out.println(a);System.o…

matplotlib制图初级篇

做任何的报表分析&#xff0c;最后是达到可视化的目的。 全部都是一堆数字&#xff0c;那肯定不是一个合格的数据报表制作分析人员&#xff1a; 需求&#xff1a;根据excel表&#xff0c;生成折线图、柱状图和饼状图 1、pandas读取数据 说明&#xff1a;本机的运行环境为mac…

碰撞检测 Neon优化

1、碰撞检测 碰撞检测的原理,两个圆心距离d <= r1 + r2即发生碰撞, 对于下图这种,d的计算方法即为余弦定理 2、Neon优化 这段代码过于简单直接使用neon intrinsic编写 #include <arm_neon.h> #include <stdio.h>struct circle {

雷电模拟器在打开“指针位置“后,无效,没有指针xy轴坐标显示?(解决方法)

解决方法&#xff1a;雷电模拟器我甘霖娘***(不是 1. 打开"指针位置" 2. 右击雷电模拟器图标 - 打开文件所在位置 - 找到vms文件目录并进入 3. 新建名为debug的txt文件 4. 重启雷电模拟器 5. 已解决

Day08-面向对象

1. 类和对象 1.1 类和对象的理解 客观存在的事物皆为对象 &#xff0c;所以我们也常常说万物皆对象。 类 类的理解 类是对现实生活中一类具有共同属性和行为的事物的抽象 类是对象的数据类型&#xff0c;类是具有相同属性和行为的一组对象的集合 简单理解&#xff1a;类就是…

集睿致远CS5518国产MIPI转LVDS 点屏方案芯片可pin to pin替代国腾GM8775C

CS5518是一款MIPI DSI输入与1或2Port LVDS输出转换芯片。Pin to Pin替换GM8775C&#xff01;MIPI DSI最多支持4Lane&#xff0c;1Lane最大运行速率为1Gbps。LVDS支持18或24位像素&#xff0c;25MHz至154MHz&#xff0c;支持VESA或JEIDA格式。单路1.8V供电方式&#xff0c;可选配…