[8]集合Set及优化类DataUtil,ArrayUtil

前言

上节我们讲了集合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.封装类SetUtilActivity中的使用
    4.封装类SetUtil及其他相关类源码

一.Set家族及各种 set 的特性

KotlinSet集合有以下常用类:

  • 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

MutableSetKotlin中 一个特有集合,与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

其中还涉及到两个类DataUtilArrayUtil。下面给出以上几个类的代码。
DataUtil源码:

还有 46% 的精彩内容
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。
支付 ¥7.80 继续阅读

推荐阅读更多精彩内容