前言
上节我们讲了集合List
相关知识,大家感兴趣的可参看以下文章
[1]Kotlin中的算数运算
[2]二元运算符 ?:
[3]Any的使用 - 简书
[4]数组Array
[5]Predicate的使用
[6]字符串String
[7]集合List
今天我们来了解下集合Set
,今天涉及到的知识点有:
1.Set
家族及各种set
的特性
- 1.1 Set
- 1.2 MutableSet
- 1.3 HashSet
- 1.4 LinkedHashSet
- 1.5 SortedSet
- 1.6 TreeSet
2.Set
的初始化
3.封装类SetUtil
在Activity
中的使用
4.封装类SetUtil
及其他相关类源码
一.Set家族及各种 set 的特性
在Kotlin
中Set
集合有以下常用类:
- Set
- MutableSet
- HashSet
- LinkedHashSet
- SortedSet
- TreeSet
其中Kotlin
中常用的为不可变集合Set(只读集合)
与可变集合MutableSet(可读写集合)
,而其他集合,如HashSet
,LinkedHashSet
,SortedSet
,TreeSet
等仍沿用Java
特性。下面对各种Set
一 一讲解。
1.1 Set
Set
集合大致继承关系如下:
set-> Collection-> Iterable
其在Kotlin
中为不可变集合
,即该集合被初始化以后,其只可读取,不可做添加,删除,修改的操作。
Set
系列的集合,其内部元素拥有不可重复的特性,且存储的元素无序。尽管如此,我们仍然可以通过元素值来获取该元素在Set
中的下标,如:
//根据元素获取该元素在set中的下标
var set: Set<String> = setOf("a", "b", "c")
var indexSet: Int = set.indexOf("b")
LogUtil.i("获取${set}中 b 元素的下标为 indexSet=${indexSet}")
执行结果如下:
获取[a, b, c]中 b 元素的下标为 indexSet=1
由于Set
中存储元素无序,所以我们很少会去获取Set
中存储元素的下标。
1.2 MutableSet
MutableSet
为Kotlin
中 一个特有集合,与Kotlin
中不可变集合Set
相对应的,MutableSet
是一个可变集合
,我们可以对MutableSet
进行增删改查。
MutableSet
集合大致继承关系如下:
MutableSet->set-> Collection-> Iterable
1.3 HashSet
HashSet
大致继承关系如下:
HashSet->AbstractSet->set-> Collection-> Iterable
HashSet
特性如下:
-
特性
:哈希存储,线程不安全,查找,添加,删除效率高,无序 -
使用场景
:数据去重,快速查找,缓存机制
1.4 LinkedHashSet
LinkedHashSet
大致继承关系如下:
LinkedHashSet->HashSet->AbstractSet->set-> Collection-> Iterable
LinkedHashSet
特性如下:
-
特性
:LinkedHashSet
作为HashSet
的子类,查找,添加,删除效率比HashSet
低,有序 -
使用场景
:日志记录(需要按时间顺序查看日志的),队列管理,缓存管理(需要按顺序查找管理缓存数据的)
1.5 SortedSet
SortedSet
大致继承关系如下:
SortedSet->set-> Collection-> Iterable
SortedSet
很少被用到,用得比较多的是其子类TreeSet
,那么接下来让我们看看TreeSet
吧。
1.6 TreeSet
TreeSet
大致继承关系如下:
TreeSet->NavigableSet->SortedSet->set-> Collection-> Iterable
TreeSet
特性如下:
-
特性
:SortedSet
的子类,效率比LinkedHashSet
低 -
使用场景
:适用于去重且排序的场景,可自然排序或重写Comparator
定制排序
二. Set 的初始化
我们可以像下面这样初始化各个Set
:
//创建一个只读set
var set1 = setOf<Int>() //创建空只读set
var set2 = setOf("a") //创建一个只含一个元素的只读set
var set3 = setOf("b", "c", "f") //创建一个含多个元素的只读set
LogUtil.i("创建一个含多个元素的只读set: ${set3}")
//创建可变set(可增删)
var mutableSet1 = mutableSetOf<Int>() //创建空可变set
var mutableSet2 = mutableSetOf("a") //创建一个只含一个元素的可变set
LogUtil.i("创建一个只含一个元素的可变set: ${mutableSet2}")
var mutableSet3 = mutableSetOf("b", "c", "f") //创建一个含多个元素的可变set
//HashSet初始化
var hashSet1 = hashSetOf<Int>()
var hashSet2 = hashSetOf("a","b")
//LinkedHashSet初始化
var linkedHashSet1 = linkedSetOf<Int>()
var linkedHashSet2 = linkedSetOf("a","b")
//SortedSet初始化
var sortedSet1 = sortedSetOf<Int>()
var sortedSet2 = sortedSetOf("a","b")
//TreeSet初始化
var treeSet1 = TreeSet<Int>()
三.封装类 SetUtil 在 Activity 中的使用
Set
的相关操作,我封装到了一个工具类SetUtil
中,下面给出该类在TestActivity
中的使用:
package com.example.kdemo.ui.test
import android.os.Build
import android.os.Bundle
import android.view.View
import androidx.annotation.RequiresApi
import androidx.appcompat.app.AppCompatActivity
import com.example.kdemo.R
import com.example.kdemo.databinding.ActivityTestBinding
import com.example.kdemo.util.data.collection.SetUtil
import com.example.kdemo.util.data.normal.ArrayUtil
import com.example.kdemo.util.log.LogUtil
import com.example.kdemo.util.toast.ToastUtil
import java.util.SortedSet
import java.util.TreeSet
import java.util.function.Predicate
class TestActivity : AppCompatActivity(), View.OnClickListener {
private lateinit var mBinding: ActivityTestBinding
override fun onCreate(savedInstanceState: Bundle?) {
super.onCreate(savedInstanceState)
mBinding = ActivityTestBinding.inflate(layoutInflater)
setContentView(mBinding.root)
initData()
setListener()
}
private fun initData() {}
private fun setListener() {
mBinding.mBtnTest.setOnClickListener(this)
}
@RequiresApi(Build.VERSION_CODES.Q)
override fun onClick(view: View) {
when (view.id) {
R.id.mBtnTest -> {
test()
}
else -> {
}
}
}
private fun test() {
ToastUtil.showShortToast(this, "begin test")
//创建一个只读set
var set1 = setOf<Int>() //创建空只读set
var set2 = setOf("a") //创建一个只含一个元素的只读set
var set3 = setOf("b", "c", "f") //创建一个含多个元素的只读set
LogUtil.i("创建一个含多个元素的只读set: ${set3}")
//创建可变set(可增删)
var mutableSet1 = mutableSetOf<Int>() //创建空可变set
var mutableSet2 = mutableSetOf("a") //创建一个只含一个元素的可变set
LogUtil.i("创建一个只含一个元素的可变set: ${mutableSet2}")
var mutableSet3 = mutableSetOf("b", "c", "f") //创建一个含多个元素的可变set
//HashSet初始化
var hashSet1 = hashSetOf<Int>()
var hashSet2 = hashSetOf("a","b")
//LinkedHashSet初始化
var linkedHashSet1 = linkedSetOf<Int>()
var linkedHashSet2 = linkedSetOf("a","b")
//SortedSet初始化
var sortedSet1 = sortedSetOf<Int>()
var sortedSet2 = sortedSetOf("a","b")
//TreeSet初始化
var treeSet1 = TreeSet<Int>()
// //set-> Collection-> Iterable
//
// MutableSet->set-> Collection-> Iterable
// var s5: MutableSet
//
// //HashSet->AbstractSet->set-> Collection-> Iterable
// var s1: HashSet //哈希存储,线程不安全,查找,添加,删除效率高,无序
// //使用场景:数据去重,快速查找,缓存机制
//
// //LinkedHashSet->HashSet->AbstractSet->set-> Collection-> Iterable
// var s2: LinkedHashSet //HashSet得子类,查找,添加,删除效率比hashSet低,有序
// //使用场景:日志记录(需要按时间顺序查看日志的)
// // 队列管理
// // 缓存管理(需要按顺序查找管理缓存数据的)
//
// var s3: SortedSet //TreeSet的父类
//
// //TreeSet->NavigableSet->SortedSet->set-> Collection-> Iterable
// var s4: TreeSet //SortedSet的子类,效率比LinkedHashSet低
// //适用于去重且排序的场景,可自然排序或重写Comparator定制排序
//
//添加单个元素
var mutableSet10 = mutableSetOf<String>()
LogUtil.i("mutableSet10 添加元素前 ${mutableSet10}")
var pair10 = SetUtil.add(mutableSet10, "a")
LogUtil.i("mutableSet10 添加一个元素: flag= ${pair10.first}, mutableSet10=${pair10.second}")
//添加一个集合(可用于List去重)
var mutableSet11 = mutableSetOf<String>()
LogUtil.i("mutableSet11 添加元素前 ${mutableSet11}")
var mutableList11 = mutableListOf("g", "h", "g", "o")
var pair11 = SetUtil.addAll(mutableSet11, mutableList11)
LogUtil.i("mutableList11去重: flag= ${pair11.first} mutableSet11=${pair11.second}")
//移除元素
var mutableSet12 = mutableSetOf("a", "b", "c")
LogUtil.i("mutableSet12 移除元素前 ${mutableSet12}")
var pair12 = SetUtil.remove(mutableSet12, "b")
LogUtil.i("mutableSet12移除元素b: flag= ${pair12.first} mutableSet12=${pair12.second}")
//移除集合
var mutableSet13 = mutableSetOf("a", "b", "c")
LogUtil.i("mutableSet13 移除集合前 ${mutableSet13}")
var mutableList13 = mutableListOf("a", "b")
var pair13 = SetUtil.removeAll(mutableSet13, mutableList13)
LogUtil.i("mutableSet13移除集合${mutableList13}: flag=${pair13.first} mutableSet13=${pair13.second}")
//====retainAll的理解====
//集合元素一样
LogUtil.i("集合元素一样:")
var mutableSet14 = mutableSetOf("a", "b", "c")
var mutableList14 = mutableListOf("a", "b", "c")
LogUtil.i("retainAll前: mutableSet14=${mutableSet14} mutableList14=${mutableList14}")
var flag14 = mutableSet14.retainAll(mutableList14)
LogUtil.i("retainAll后: mutableSet14=${mutableSet14} flag14=${flag14}")
//集合mutableSet与mutableList有交集
LogUtil.i("集合mutableSet与mutableList有交集:")
var mutableSet15 = mutableSetOf("a", "b", "c")
var mutableList15 = mutableListOf("b", "c", "d")
LogUtil.i("retainAll前: mutableSet15=${mutableSet15} mutableList15=${mutableList15}")
var flag15 = mutableSet15.retainAll(mutableList15)
LogUtil.i("retainAll后: mutableSet15=${mutableSet15} flag15=${flag15}")
//集合mutableSet与mutableList无交集
LogUtil.i("集合mutableSet与mutableList无交集:")
var mutableSet16 = mutableSetOf("a", "b")
var mutableList16 = mutableListOf("c", "d")
LogUtil.i("retainAll前: mutableSet16=${mutableSet16} mutableList16=${mutableList16}")
var flag16 = mutableSet16.retainAll(mutableList16)
LogUtil.i("retainAll后: mutableSet16=${mutableSet16} flag16=${flag16}")
//====取交集====
//取交集集合元素一样
LogUtil.i("取交集集合元素一样:")
var mutableSet17 = mutableSetOf("e", "f", "g")
var mutableList17 = mutableListOf("e", "f", "g")
var pair17 = SetUtil.intersect(mutableSet17, mutableList17)
LogUtil.i("${mutableSet17}与集合${mutableList17}取交集: flag=${pair17.first} 交集=${pair17.second}")
//集合mutableSet与mutableList有交集
LogUtil.i("集合mutableSet与mutableList有交集:")
var mutableSet18 = mutableSetOf("e", "f", "g")
var mutableList18 = mutableListOf("f", "g", "h")
var pair18 = SetUtil.intersect(mutableSet18, mutableList18)
LogUtil.i("${mutableSet18}与集合${mutableList18}取交集: flag=${pair18.first} 交集=${pair18.second}")
//集合mutableSet与mutableList无交集
LogUtil.i("集合mutableSet与mutableList无交集:")
var mutableSet19 = mutableSetOf("e", "f")
var mutableList19 = mutableListOf("g", "h")
var pair19 = SetUtil.intersect(mutableSet19, mutableList19)
LogUtil.i("${mutableSet19}与集合${mutableList19}取交集: flag=${pair19.first} 交集=${pair19.second}")
//清空集合
var mutableSet20 = mutableSetOf("e", "f")
LogUtil.i("mutableSet20 清空集合前: ${mutableSet20}")
SetUtil.clear(mutableSet20)
LogUtil.i("mutableSet20 清空集合后: ${mutableSet20}")
//根据条件移除元素
var mutableSet21 = mutableSetOf(1, 2, 3, 4, 5)
LogUtil.i("mutableSet21 移除元素前: ${mutableSet21}")
//移除大于3的元素
var predicate21 = Predicate<Int> { it > 3 }
SetUtil.removeIf(mutableSet21, predicate21)
LogUtil.i("mutableSet21 移除大于3的元素后: ${mutableSet21}")
//set可以根据元素获取下标
var index = mutableSet21.indexOf(3)
LogUtil.i("mutableSet21 index= ${index}")
//set添加元素
var mutableSet22 = mutableSetOf("a", "b")
LogUtil.i("mutableSet22 plus元素前: ${mutableSet22}")
mutableSet22 = SetUtil.plus(mutableSet22, "c").toMutableSet()
LogUtil.i("mutableSet22 plus元素后: ${mutableSet22}")
//plusElement方式添加元素
var mutableSet23 = mutableSetOf("a", "d")
LogUtil.i("mutableSet23 plusElement元素前: ${mutableSet23}")
mutableSet23 = SetUtil.plusElement(mutableSet23, "e").toMutableSet()
LogUtil.i("mutableSet23 plusElement元素后: ${mutableSet23}")
//set与数组合并
var mutableSet24 = mutableSetOf("a", "b")
var array24 = arrayOf("k", "g")
LogUtil.i("mutableSet24 与数组${ArrayUtil.getData(array24)}合并前: mutableSet24=${mutableSet24}")
mutableSet24 = SetUtil.plus(mutableSet24, array24).toMutableSet()
LogUtil.i("mutableSet24 与数组${ArrayUtil.getData(array24)}合并后: mutableSet24=${mutableSet24}")
//set与集合合并
var mutableSet25 = mutableSetOf("a", "b")
var mutableList25 = mutableListOf("g", "f")
LogUtil.i("mutableSet25 与集合${mutableList25}合并前: mutableSet25=${mutableSet25}")
mutableSet25 = SetUtil.plus(mutableSet25, mutableList25).toMutableSet()
LogUtil.i("mutableSet25 与集合${mutableList25}合并后: mutableSet25=${mutableSet25}")
//set与序列合并
var mutableSet26 = mutableSetOf("a", "k")
var sequence26: Sequence<String> = sequenceOf("b", "n")
LogUtil.i("mutableSet26 与序列${mutableSet26}合并前: mutableSet26=${mutableSet26}")
mutableSet26 = SetUtil.plus(mutableSet26, sequence26).toMutableSet()
LogUtil.i("mutableSet26 与序列${mutableSet26}合并后: mutableSet26=${mutableSet26}")
//set剔除第一个元素f
var mutableSet27 = mutableSetOf("e", "f", "g")
LogUtil.i("mutableSet27 剔除元素f前: mutableSet27=${mutableSet27}")
mutableSet27 = SetUtil.minus(mutableSet27, "f").toMutableSet()
LogUtil.i("mutableSet27 剔除元素f后: mutableSet27=${mutableSet27}")
//set剔除第一个元素e
var mutableSet28 = mutableSetOf("e", "k", "g")
LogUtil.i("mutableSet28 剔除元素e前: mutableSet28=${mutableSet28}")
mutableSet28 = SetUtil.minusElement(mutableSet28, "e").toMutableSet()
LogUtil.i("mutableSet28 剔除元素e后: mutableSet28=${mutableSet28}")
//将数组从set中移除
var mutableSet29 = mutableSetOf("e", "k", "g", "a", "c", "h")
var array29 = arrayOf("a", "g", "e")
LogUtil.i("mutableSet29 剔除数组${ArrayUtil.getData(array29)}前: mutableSet29=${mutableSet29}")
mutableSet29 = SetUtil.minus(mutableSet29, array29).toMutableSet()
LogUtil.i("mutableSet29 剔除数组${ArrayUtil.getData(array29)}后: mutableSet29=${mutableSet29}")
//将集合从set中移除
var mutableSet30 = mutableSetOf("e", "k", "g")
var mutableList30 = mutableListOf("k", "g")
LogUtil.i("mutableSet30 剔除集合${mutableList30}前: mutableSet30=${mutableSet30}")
mutableSet30 = SetUtil.minus(mutableSet30, mutableList30).toMutableSet()
LogUtil.i("mutableSet30 剔除集合${mutableList30}后: mutableSet30=${mutableSet30}")
//将序列从集合中移除
var mutableSet31 = mutableSetOf("e", "k", "g")
var sequence31: Sequence<String> = sequenceOf("e", "k")
LogUtil.i("mutableSet31 剔除序列${sequence31.toMutableList()}前: mutableSet31=${mutableSet31}")
mutableSet31 = SetUtil.minus(mutableSet31, sequence31).toMutableSet()
LogUtil.i("mutableSet31 剔除序列${sequence31.toMutableList()}后: mutableSet31=${mutableSet31}")
//根据元素获取该元素在set中的下标
var set: Set<String> = setOf("a", "b", "c")
var indexSet: Int = set.indexOf("b")
LogUtil.i("获取${set}中 b 元素的下标为 indexSet=${indexSet}")
}
}
运行效果如下:
21:30:14.978 I 创建一个含多个元素的只读set: [b, c, f]
21:30:14.978 I 创建一个只含一个元素的可变set: [a]
21:30:14.978 I mutableSet10 添加元素前 []
21:30:14.978 I mutableSet10 添加一个元素: flag= true, mutableSet10=[a]
21:30:14.978 I mutableSet11 添加元素前 []
21:30:14.978 I mutableList11去重: flag= true mutableSet11=[g, h, o]
21:30:14.978 I mutableSet12 移除元素前 [a, b, c]
21:30:14.978 I mutableSet12移除元素b: flag= true mutableSet12=[a, c]
21:30:14.978 I mutableSet13 移除集合前 [a, b, c]
21:30:14.979 I mutableSet13移除集合[a, b]: flag=true mutableSet13=[c]
21:30:14.979 I 集合元素一样:
21:30:14.979 I retainAll前: mutableSet14=[a, b, c] mutableList14=[a, b, c]
21:30:14.979 I retainAll后: mutableSet14=[a, b, c] flag14=false
21:30:14.979 I 集合mutableSet与mutableList有交集:
21:30:14.979 I retainAll前: mutableSet15=[a, b, c] mutableList15=[b, c, d]
21:30:14.979 I retainAll后: mutableSet15=[b, c] flag15=true
21:30:14.979 I 集合mutableSet与mutableList无交集:
21:30:14.979 I retainAll前: mutableSet16=[a, b] mutableList16=[c, d]
21:30:14.979 I retainAll后: mutableSet16=[] flag16=true
21:30:14.979 I 取交集集合元素一样:
21:30:14.980 I checkCollectionType: type=1
21:30:14.980 I [e, f, g]与集合[e, f, g]取交集: flag=true 交集=[e, f, g]
21:30:14.980 I 集合mutableSet与mutableList有交集:
21:30:14.981 I checkCollectionType: type=1
21:30:14.982 I [e, f, g]与集合[f, g, h]取交集: flag=true 交集=[f, g]
21:30:14.982 I 集合mutableSet与mutableList无交集:
21:30:14.983 I checkCollectionType: type=1
21:30:14.983 I [e, f]与集合[g, h]取交集: flag=false 交集=[]
21:30:14.983 I mutableSet20 清空集合前: [e, f]
21:30:14.984 I mutableSet20 清空集合后: []
21:30:14.986 I mutableSet21 移除元素前: [1, 2, 3, 4, 5]
21:30:14.986 I mutableSet21 移除大于3的元素后: [1, 2, 3]
21:30:14.986 I mutableSet21 index= 2
21:30:14.986 I mutableSet22 plus元素前: [a, b]
21:30:14.990 I mutableSet22 plus元素后: [a, b, c]
21:30:14.992 I mutableSet23 plusElement元素前: [a, d]
21:30:14.993 I mutableSet23 plusElement元素后: [a, d, e]
21:30:14.993 I mutableSet24 与数组{k,g}合并前: mutableSet24=[a, b]
21:30:14.994 I mutableSet24 与数组{k,g}合并后: mutableSet24=[a, b, k, g]
21:30:14.995 I mutableSet25 与集合[g, f]合并前: mutableSet25=[a, b]
21:30:14.995 I mutableSet25 与集合[g, f]合并后: mutableSet25=[a, b, g, f]
21:30:14.995 I mutableSet26 与序列[a, k]合并前: mutableSet26=[a, k]
21:30:14.996 I mutableSet26 与序列[a, k, b, n]合并后: mutableSet26=[a, k, b, n]
21:30:14.996 I mutableSet27 剔除元素f前: mutableSet27=[e, f, g]
21:30:14.996 I mutableSet27 剔除元素f后: mutableSet27=[e, g]
21:30:14.996 I mutableSet28 剔除元素e前: mutableSet28=[e, k, g]
21:30:14.997 I mutableSet28 剔除元素e后: mutableSet28=[k, g]
21:30:14.998 I mutableSet29 剔除数组{a,g,e}前: mutableSet29=[e, k, g, a, c, h]
21:30:15.000 I mutableSet29 剔除数组{a,g,e}后: mutableSet29=[k, c, h]
21:30:15.002 I mutableSet30 剔除集合[k, g]前: mutableSet30=[e, k, g]
21:30:15.003 I mutableSet30 剔除集合[k, g]后: mutableSet30=[e]
21:30:15.003 I mutableSet31 剔除序列[e, k]前: mutableSet31=[e, k, g]
21:30:15.003 I mutableSet31 剔除序列[e, k]后: mutableSet31=[g]
21:30:15.003 I 获取[a, b, c]中 b 元素的下标为 indexSet=1
四. 封装类 SetUtil 及其他相关类源码
工具类SetUtil
的继承关系如下:
SetUtil->MutableCollectionOperator->CollectionOperator
其中还涉及到两个类DataUtil
和ArrayUtil
。下面给出以上几个类的代码。
DataUtil
源码: