扩展函数工具类篇(Kotlin)

news2024/11/30 0:28:29

引言:本文仅记录自己项目中使用到的扩展类、则需使用!(均为kt文件)

一、ActivityExpand

/**
 * 启动Activity
 */
fun AppCompatActivity.startPager(actClass: Class<*>) {
    startActivity(Intent(this, actClass))
}

/**
 * 启动Activity
 */
fun Context.startPager(actClass: Class<*>) {
    startActivity(Intent(this, actClass))
}

/**
 * 传递intent,启动Activity
 */
fun Context.startPager(intents: Intent, actClass: Class<*>) {
    intents.setClass(this, actClass)
    startActivity(intents)
}

/**
 * 待餐传递
 */
fun Activity.startPager(intents: Intent, actClass: Class<*>) {
    intents.setClass(this, actClass)
    startActivity(intents)
}

使用:

 


二、ContextExand(兼容6.0 及一下老设备写法)

fun Context.getColors(@ColorRes id: Int) = ContextCompat.getColor(this, id)

fun Context.getDrawables(@DrawableRes id: Int) = ContextCompat.getDrawable(this, id)

三、DecimalExpand

fun String.fenToYuanByString() = BigDecimal(this).fenToYuanByNumber()

fun Int.fenToYuanByString() = BigDecimal(this).fenToYuanByNumber()

fun String.fenToYuanByStringNoZero(): String {
    return try {
        val result = BigDecimal(this).fenToYuanByNumber().toString()
        result.subSequence(0, result.indexOf(".")).toString()
    } catch (e: Exception) {
        BigDecimal(this).fenToYuanByNumber().toString()
    }
}

fun Int.fenToYuanByStringNoZero(): String {
    return try {
        val result = BigDecimal(this).fenToYuanByNumber().toString()
        result.subSequence(0, result.indexOf(".")).toString()
    } catch (e: Exception) {
        BigDecimal(this).fenToYuanByNumber().toString()
    }
}


fun BigDecimal.fenToYuanByNumber(): BigDecimal =
    this.divide(BigDecimal(100), 2, RoundingMode.HALF_UP)

格式化money 保留2位数


四、FloatExpand(dp、sp像素转换)

fun Float.dp2Px() = ConvertUtils.dp2px(this).toFloat()

fun Float.px2Dp() = ConvertUtils.px2dp(this).toFloat()

fun Float.sp2Px() = ConvertUtils.sp2px(this).toFloat()

用到了第三方库(当然也可以不用、懒得折腾了):

implementation 'com.blankj:utilcodex:1.31.1'

使用: 

 

 


五、LongExpand

//格式化时间
fun Long.formatDate(format: String) = SimpleDateFormat(format, Locale.CHINA).format(Date(this))

/**
 * this ==单位秒
 * 返回对应的秒数 eg 1s 2s
 */
fun Long.formatSeconds(): String = when {
    this <= 0 -> {
        "00:00"
    }
    this < 60 -> {
        format(Locale.getDefault(), "00:%02d", this % 60)
    }
    this < 3600 -> {
        format(
            Locale.getDefault(),
            "%02d:%02d",
            this / 60,
            this % 60
        )
    }
    else -> {
        format(
            Locale.getDefault(),
            "%02d:%02d:%02d",
            this / 3600,
            this % 3600 / 60,
            this % 60
        )
    }
}


六、ObjectExpand(对象转json字符串)

fun Any.toJson(): String {
    return try {
        GsonUtils.toJson(this)
    } catch (e: Exception) {
        ""
    }
}

七、StringExpand

/**
 * 是否包含英文字母与数字
 */
fun String.isLetter(): Boolean {
    val regex = "^[a-z0-9A-Z].*"
    return this.matches(Regex(regex))
}

/**
 * 是否包含英文字符
 */
fun String.isContainLetter(): Boolean {
    val regex = ".*[a-zA-Z]+.*"
    return Pattern.compile(regex, Pattern.CASE_INSENSITIVE or Pattern.DOTALL).matcher(this)
        .matches()
}

/**
 * 全部为英文字母?
 */
fun String.isAllLetter(): Boolean {
    val regex = "[a-zA-Z]+"
    return this.matches(Regex(regex))
}

/**
 * 判断是否包含.0 .00的数据类型
 * 整数
 */
fun String.convertInteger(): String {
    val subs = splitToMutableList(".")
    return if (subs.last() == "0") {
        removeSuffix(".0")
    } else if (subs.last() == "00") {
        removeSuffix(".00")
    } else {
        this
    }
}

/**
 * 隐藏中间的手机号 188****7502
 */
fun String.hideMiddlePhone(): String {
    val msg = replaceRange(3..6, "")
    return StringBuilder(msg).apply {
        for (index in 0..length) {
            if (index == 3) {
                insert(index, "****")
            }
        }
    }.toString()
}

/**
 * 隐藏身份证、
 */
fun String.hideIcCard(): String {
    val last = this.length - 4
    val msg = replaceRange(4..last, "")
    return StringBuilder(msg).apply {
        for (index in 0..length) {
            if (index == 4) {
                insert(index, "******")
            }
        }
    }.toString()
}



//截取 根据表达式
fun String.splitToMutableList(regex: String) = split(regex).toMutableList()

/**
 * 转为实体类对象
 */
fun <T> String.toJsonObject(type: Class<T>): T? {
    return try {
        GsonUtils.fromJson(this, type)
    } catch (e: Exception) {
        null
    }
}

/**
 * 转为list实体类对象
 */
fun <T> String.toJsonListObject(type: Class<T>): List<T>? {
    return try {
        GsonUtils.fromJson<List<T>?>(this, GsonUtils.getListType(type))
    } catch (e: Exception) {
        null
    }
}

八、RecycleViewExpand

/**
 * 是否滚动到底部
 */
fun RecyclerView.isSlideToBottom(): Boolean {
    return this.computeVerticalScrollExtent() + this.computeVerticalScrollOffset() >= this.computeVerticalScrollRange()
}

fun RecyclerView.isSlideToTop(): Boolean {
    return if (layoutManager is LinearLayoutManager) {
        val firstItemPosition =
            (layoutManager as LinearLayoutManager).findFirstCompletelyVisibleItemPosition()
        firstItemPosition == 0
    } else false
}

九、ViewExpand(包含了EditText、ScrollView、ImageView等)

fun View.showAnim(duration: Long, listener: AnimatorListenerAdapter?) {
    ObjectAnimator.ofFloat(this, "alpha", 0f, 1f).run {
        this.duration = duration
        addListener(listener)
        start()
    }
}

/**
 * 隐藏动画
 */
fun View.hideAnim(duration: Long, listener: AnimatorListenerAdapter?): Animator {
    return ObjectAnimator.ofFloat(this, "alpha", 1f, 0f).apply {
        this.duration = duration
        if (listener != null) {
            addListener(listener)
        }
        start()
    }
}

fun View.hideAnimate(duration: Long = 500, alpha: Float = 0f, listener: AnimatorListenerAdapter) {
    this.animate().alpha(alpha).setDuration(duration).setListener(listener).start()
}

/**
 * 扩大点击作用域
 * @param expandTouch 扩大的点击区域
 */
fun View.setTouchDelegate(expandTouch: Int) {
    try {
        val parentView = this.parent as View
        parentView.post {
            val rect = Rect()
            this.getHitRect(rect)
            rect.top -= expandTouch
            rect.bottom += expandTouch
            rect.left -= expandTouch
            rect.right += expandTouch
            parentView.touchDelegate = TouchDelegate(rect, this)
        }
    } catch (e: Exception) {
    }
}


/**
 * 点击放大  
 *   implementation 'com.github.SherlockGougou:BigImageViewPager:androidx-6.2.0'
 */
fun ImageView.clickBigger(uri: String, showDownBt: Boolean = true) {
    setOnClickListener {
        ImagePreview.getInstance().setContext(this.context).setImage(uri)// 图片
            .setShowCloseButton(true)// 是否显示关闭按钮
            .setShowDownButton(showDownBt)// 是否显示下载按钮
            .setFolderName(
                this.context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString()
            )// 设置下载到的文件夹名(保存到根目录)
            .start()
    }
}

/**
 * 点击放大
 */
fun ImageView.clickBigger(
    listUri: List<String>, defaultIndex: Int = 0, showDownBt: Boolean = true
) {
    setOnClickListener {
        ImagePreview.getInstance().setContext(this.context).setImageList(listUri)// 图片
            .setIndex(defaultIndex).setShowCloseButton(true)// 是否显示关闭按钮
            .setShowDownButton(showDownBt)// 是否显示下载按钮
            .setFolderName(
                this.context.getExternalFilesDir(Environment.DIRECTORY_DOWNLOADS).toString()
            )// 设置下载到的文件夹名(保存到根目录)
            .start()
    }
}

/**
 * 清除点击放大逻辑
 */
fun ImageView.clearClickBigger() {
    setOnClickListener(null)
}


fun View.show() {
    visibility = View.VISIBLE
}

fun View.hide() {
    visibility = View.INVISIBLE
}

fun View.goneHide() {
    visibility = View.GONE
}

/**
 * 禁止输入空格 禁止后xml中的限制将失效。
 * @param limitLength 限制文本输入长度
 */
fun EditText.noSpace(limitLength: Int = 1000) {
    filters = arrayOf(object : InputFilter {
        override fun filter(
            source: CharSequence?, p1: Int, p2: Int, p3: Spanned?, p4: Int, p5: Int
        ): CharSequence? {
            return when {
                source.isNullOrBlank() -> ""
                source.contains("\\n") -> {
                    source.toString().replace("\\n", "")
                }
                source.contains("\\b") -> {
                    source.toString().replace("\\b", "")
                }
                else -> null
            }
        }
    }, InputFilter.LengthFilter(limitLength))
}

//禁止\n \b 符号
fun EditText.noSymbol(limitLength: Int = 1000) {
    filters = arrayOf(object : InputFilter {
        override fun filter(
            source: CharSequence?, p1: Int, p2: Int, p3: Spanned?, p4: Int, p5: Int
        ): CharSequence? {
            return when {
                source?.contains("\\n") == true -> {
                    source.toString().replace("\\n", "")
                }
                source?.contains("\\b") == true -> {
                    source.toString().replace("\\b", "")
                }
                else -> null
            }
        }
    }, InputFilter.LengthFilter(limitLength))
}

//只输入中文
fun EditText.onlyCN(limitLength: Int = -1) {
    if (limitLength != -1) {
        filters = arrayOf(object : InputFilter {
            override fun filter(
                source: CharSequence?, start: Int, end: Int, p3: Spanned?, p4: Int, p5: Int
            ): CharSequence? {
                try {
                    for (index in start..end) {
                        return if (!isChinese(source?.get(index))) "" else source
                    }
                } catch (e: Exception) {
                }
                return null
            }
        }, InputFilter.LengthFilter(10))
    } else {
        filters = arrayOf(object : InputFilter {
            override fun filter(
                source: CharSequence?, start: Int, end: Int, p3: Spanned?, p4: Int, p5: Int
            ): CharSequence? {
                try {
                    for (index in start..end) {
                        return if (!isChinese(source?.get(index))) "" else source
                    }
                } catch (e: Exception) {
                }
                return null
            }
        })
    }
}

/**
 * 判定输入汉字
 *
 * @param c
 * @return
 */
fun isChinese(c: Char?): Boolean {
    if (c == null) {
        return false
    }
    val ub = Character.UnicodeBlock.of(c)
    return ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS || ub === Character.UnicodeBlock.CJK_COMPATIBILITY_IDEOGRAPHS || ub === Character.UnicodeBlock.CJK_UNIFIED_IDEOGRAPHS_EXTENSION_A || ub === Character.UnicodeBlock.GENERAL_PUNCTUATION || ub === Character.UnicodeBlock.CJK_SYMBOLS_AND_PUNCTUATION || ub === Character.UnicodeBlock.HALFWIDTH_AND_FULLWIDTH_FORMS
}

/**
 * 设置Hint字体大小
 */
fun EditText.setHintTextSize(hint: String, sizeSp: Int) {
    val sp = SpannableString(hint).apply {
        setSpan(
            AbsoluteSizeSpan(sizeSp, true), 0, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        )
    }
    setHint(sp)
}

fun EditText.setHintTextSize(sizeSp: Int) {
    val sp = SpannableString(hint).apply {
        setSpan(
            AbsoluteSizeSpan(sizeSp, true), 0, length, Spanned.SPAN_EXCLUSIVE_EXCLUSIVE
        )
    }
    hint = sp
}

/**
 * 设置过滤器、一般用于提现等金额操作、
 * 保留两位小数
 */
fun EditText.formatMoney() {
    filters = arrayOf(AmountInputFilter())
}

/**
 * 限制输入小数位数
 */
fun EditText.limitInputNUm(numLimitLength:Int) {
    filters = arrayOf(AmountInputFilter(numLimitLength))
}

fun EditText.clearFilter() {
    filters = arrayOf()
}

class AmountInputFilter : InputFilter {

    constructor()

    constructor(numLimitLength: Int) {
        this.numLimitLength = numLimitLength
    }

    /**
     * 最大数字,我们取int型最大值
     */
    val MAX_VALUE = Int.MAX_VALUE

    /**
     * 小数点后的数字的位数
     */
    var numLimitLength = 2

    var p: Pattern? = null

    init {
        //除数字以外的
        p = Pattern.compile("[0-9]*")
    }

    override fun filter(
        source: CharSequence,
        start: Int,
        end: Int,
        dest: Spanned,
        dstart: Int,
        dend: Int
    ): CharSequence {
        val oldtext = dest.toString()
        //第一个输入.或者0,返回
        if (dest.toString() == "" && source.isNotEmpty() && (source[0].toString() == "." || source[0].toString() == "0")) return ""
        // 验证删除等按键 排除首字符.
        if (TextUtils.isEmpty(source)
            || (TextUtils.isEmpty(oldtext)
                    && source[0].toString() == ".")
        ) {
            return ""
        }
        // 验证非数字或者小数点的情况
        val m = p!!.matcher(source)
        if (oldtext.contains(".")) {
            // 已经存在小数点的情况下,只能输入数字
            if (!m.matches()) {
                return ""
            }
        } else {
            // 未输入小数点的情况下,可以输入小数点和数字
            if (!m.matches() && source != ".") {
                return ""
            }
        }
        // 验证输入金额的大小
        if (source.toString() != "") {
            val dold = (oldtext + source.toString()).toDouble()
            if (dold > MAX_VALUE) {
                return dest.subSequence(dstart, dend)
            } else if (dold == MAX_VALUE.toDouble()) {
                if (source.toString() == ".") {
                    return dest.subSequence(dstart, dend)
                }
            }
        }
        // 验证小数位精度是否正确
        if (oldtext.contains(".")) {
            val index = oldtext.indexOf(".")
            val len = dend - index
            // 小数位只能2位
            if (len > numLimitLength) {
                return dest.subSequence(dstart, dend)
            }
        }
        return dest.subSequence(dstart, dend).toString() + source.toString()
    }
}

/**
 * 全局置灰
 * 一般我们都知道图像是由一个一个像素点组成的,而像素点是通过RGBA(红绿蓝,透明度)来控制的,这个是数字方向的。
 * 但是在我们早期的彩色电视机中,我们经常会调整彩电的色调,饱和度和亮度,其中色调就是物体的颜色,饱和度就是颜色的纯度,从0到100%来描述,亮度就是颜色的相对明暗程度。
 * 既然饱和度为0就可以变成灰色,那么我们通过设置ColorMatrix然后给到Paint画笔。
 */
fun setWindowsViewGray(view: View) {
    try {
        val paint = Paint()
        val cm = ColorMatrix()
        cm.setSaturation(0f)
        paint.colorFilter = ColorMatrixColorFilter(cm)
        view.setLayerType(View.LAYER_TYPE_HARDWARE, paint)
    } catch (e: Exception) {
        e.printStackTrace()
    } catch (e: Error) {
        e.printStackTrace()
    }
}

/**
 * 恢复原色
 */
fun setWindowsViewPrimaryColor(view: View) {
    try {
        val paint = Paint()
        val cm = ColorMatrix()
        cm.setSaturation(1f)
        paint.colorFilter = ColorMatrixColorFilter(cm)
        view.setLayerType(View.LAYER_TYPE_HARDWARE, paint)
    } catch (e: Exception) {
        e.printStackTrace()
    } catch (e: Error) {
        e.printStackTrace()
    }
}

/**
 * 是否到底部
 */
fun ScrollView.isBottom() = (this.getChildAt(0).height - this.height == this.scrollY)

/**
 * 是否到底部 带有误差
 */
fun ScrollView.isBottom(deviationPx: Int) =
    ((this.getChildAt(0).height - this.height) - deviationPx <= this.scrollY)

/**
 * 滚动到顶部
 */
fun ScrollView.scrollTop() = this.fullScroll(ScrollView.FOCUS_UP)

/**
 * 滚动到底部
 */
fun ScrollView.scrollBottom() = this.fullScroll(ScrollView.FOCUS_DOWN)

十、ImageView 使用Coil的扩展

依赖:

//coil 图片加载框架Kotlin 推荐
implementation("io.coil-kt:coil:1.1.1")
implementation("io.coil-kt:coil-gif:0.9.5")
//加载一个圆角为10dp的图片
/**
* corner.dp2Px() 也可以自行进行dp转换
* placeholder errorPic 、自行替换、展位图 及加载错误图
*/
fun ImageRequest.Builder.coilSet(
    corner: Float = 10f,
    @DrawableRes placeholder: Int = R.drawable.ic_qg_placeholder,
    @DrawableRes errorPic: Int = R.drawable.ic_qg_placeholder,
    scale: Scale = Scale.FILL
) {
    placeholder(placeholder)
    error(errorPic)
    transformations(RoundedCornersTransformation(corner.dp2Px()))
    scale(scale)
}

//corner.dp2Px()参考FloatExpand扩展函数

 使用:

  val test_uri1 =
        "https://img2020.cnblogs.com/blog/1289812/202005/1289812-20200509091913298-1286944090.png"

    fun test1() {

        val imageView = ImageView(this)

        //加载一个圆角为10dp的图片
        imageView.load(test_uri1) {
            coilSet()
        }

    }

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

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

相关文章

微软推出适用于 Linux 的 Windows 子系统

导读微软宣布正式推出适用于 Linux 的 Windows 子系统 (WSL)&#xff0c;现在可以在 Microsoft Store 中以完整形式购买。据微软称&#xff0c;WSL 以前以预览形式提供&#xff0c;允许开发人员使用他们最喜欢的笔记本电脑进行编程&#xff0c;以运行 GNU/Linux 环境&#xff0…

拓扑排序(Topological Sorting)

题目描述 题目链接&#xff1a;剑指 Offer II 113. 课程顺序 - 力扣&#xff08;Leetcode&#xff09; 现在总共有 numCourses 门课需要选&#xff0c;记为 0 到 numCourses-1。 给定一个数组 prerequisites &#xff0c;它的每一个元素 prerequisites[i] 表示两门课程之间的…

前端给后端发送数据,后端接收

在具体的前后端分离项目中&#xff0c;我们经常会遇到点击表格中的某一行的按钮&#xff0c;获取这一行的某一项值的需求&#xff0c;前端点击拿到这个值&#xff0c;再传给后端使用 例如&#xff1a;在此例中点击同步的按钮&#xff0c;需要获取到表格中的ip地址的内容&#…

GD32F303固件库开发(17)----内部Flash读写

概述 本例程主要讲解如何对芯片自带Flash进行读写&#xff0c;用芯片内部Flash可以对一些需要断电保存的数据进行保存&#xff0c;无需加外部得存储芯片&#xff0c;本例程采用的是GD32F303ZET6主控&#xff0c;512K大小的Flash。 最近在弄ST和GD的课程&#xff0c;需要GD样片…

web前端期末大作业:基于HTML+CSS+JS外卖服务平台10页 带购物车 (web课程设计与实现)

&#x1f389;精彩专栏推荐 &#x1f4ad;文末获取联系 ✍️ 作者简介: 一个热爱把逻辑思维转变为代码的技术博主 &#x1f482; 作者主页: 【主页——&#x1f680;获取更多优质源码】 &#x1f393; web前端期末大作业&#xff1a; 【&#x1f4da;毕设项目精品实战案例 (10…

Yolo v5源码解析笔记

一、Yolo v5文件目录树结构 二、train.py文件介绍 从main()方法&#xff0c;首先读取参数&#xff1b;其次建立YOLONet&#xff1b;然后读取训练数据&#xff1b;最后进行训练。 2.1 读取参数 部分截图 2.2 建立YOLONet YOLONet的建立是通过 yolo文件夹中的yolo_net.py文件…

游戏开发58课 性能优化

6. 卡顿优化 相信很多研发者或玩家&#xff0c;都遇到这种情况&#xff1a;游戏大部时间运行都很流畅&#xff0c;但在战斗的某些时刻或者打开某些界面会卡一下&#xff0c;甚至卡很久。这个现象就是卡顿。引发卡顿的原因有很多&#xff0c;但主要有&#xff1a; 突发大量IO。…

银河麒麟桌面V10SP1版本系统休眠唤醒鼠标键盘失效解决方法

使用银河麒麟桌面系统有时会出现系统休眠后再唤醒&#xff0c;鼠标键盘失效的问题&#xff0c;可尝试以下方法解决。 1.检查是否安装 laptop-mode-tools 工具 执行命令: dpkg -l | grep laptop-mode-tools如果执行命令无结果输出&#xff0c;表示未安装(如果已安装&#xff0…

【从零开始学习深度学习】21. 卷积神经网络(CNN)之二维卷积层原理介绍、如何用卷积层检测物体边缘

目录1. 二维互相关运算2. 自定义二维卷积层3. 卷积层的应用----图像中物体边缘检测4. 通过数据学习核数组5. 互相关运算和卷积运算6. 特征图和感受野总结卷积神经网络&#xff08;convolutional neural network&#xff09;是含有卷积层&#xff08;convolutional layer&#x…

欧克科技在深交所上市:客户集中度较高,胡坚晟为控股股东

12月12日&#xff0c;欧克科技股份有限公司&#xff08;下称“欧克科技”&#xff0c;SZ:001223&#xff09;在深圳证券交易所主板上市。本次上市&#xff0c;欧克科技的发行价格为65.58元/股&#xff0c;发行数量为1668万股&#xff0c;募资总额约为10.94亿元&#xff0c;募资…

印制电路板(PCB)设计原则和抗干扰措施

印制电路板(PCB)是电子产品中电路元件和器件的支撑件&#xff0e;它提供电路元件和器件之间的电气连接。随着电于技术的飞速发展&#xff0c;PCB的密度越来越高。PCB 设计的好坏对抗干扰能力影响很大&#xff0c;因此&#xff0c;在进行PCB 设计时&#xff0e;必须遵守PCB设计的…

Nginx 防盗链

Nginx 防盗链 本篇主要介绍一下 nginx 中 防盗链的具体配置 , 以及http 的 referer 头 概述 防盗链其实就是 防止别的站点来引用你的 资源, 占用你的流量 在了解nginx 防盗链之前 我们先了解一下 什么是 HTTP 的头信息 Referer,当浏览器访问网站的时候,一般会带上Referer,告…

【TS】TypeScript声明文件(.d.ts)的使用

前言 当我们在TS文件中需要引入外部库时&#xff0c;编译时是无法判断传入参数的类型的&#xff0c;所以我们需要在引入前加入一个声明文件来帮助ts判断类型。 当然现在大部分库都自带有自己的声明文件&#xff0c;一般在types目录下。 使用场景 在ts文件中对引用的外部库做…

汇编逻辑运算指令

目录 逻辑运算指令 一&#xff1a;取反指令NOT 二&#xff1a;逻辑与运算AND&#xff08;重点&#xff09; 屏蔽某些位. 把小写字母转换成大写字母 判断一个数的状态 三&#xff1a;逻辑或运算指令OR 用于拼字 把大写字母转换为小写字母 四&#xff1a;逻辑异或指令XOR…

程序员也会八卦吗?

世俗的眼光&#xff0c;总是觉得女生喜欢吃八卦&#xff0c;经常聚在一起小圈子叽叽喳喳谈论朋友圈。 其实&#xff0c;从现实来看&#xff0c;办公室的男性同胞也不啻于女生的八卦程度。 在吃瓜这件问题上&#xff0c;程序员凭借自身的技术优势&#xff0c;往往奋战于最前线…

【网络编程】捕获网卡IP数据报

本文将通过winsock从应用层捕捉网络层的IP数据报。 唉&#xff0c;原来的时候一直希望能在应用层实现网络游戏加速&#xff0c;发现可以捕捉网卡IP数据报后觉得可能有希望写出来。后面想了想得出结论&#xff1a;可以捕获没卵用&#xff0c;因为没法拦截&#xff08;包已经发出…

RocketMQ的事务消息是如何实现的?

RocketMQ的事务消息实现方法如下&#xff1a; 1、首先生产者订单系统先发送⼀条half消息到Broker&#xff0c;half消息对消费者而⾔是不可⻅的 2、再创建订单&#xff0c;根据创建订单成功与否&#xff0c;向Broker发送commit或rollback 3、并且⽣产者订单系统还可以提供Broker…

Spark 3.0 - 11.ML 随机森林实现二分类实战

目录 一.引言 二.随机森林实战 1.数据预处理 2.随机森林 Pipeline 3.模型预测与验证 三.总结 一.引言 之前介绍了 决策树 &#xff0c;而随机森林则可以看作是多颗决策树的集合。在 Spark ML 中&#xff0c;随机森林中的每一颗树都被分配到不同的节点上进行并行计算&…

Crack:Aspose.3D for .NET 22.11.X

Aspose.3D for .NETAspose.3D for .NET 是一个功能丰富的游戏软件和计算机辅助设计 (CAD) API&#xff0c;无需任何 3D 建模和渲染软件依赖即可操作文档。API 支持 Discreet3DS、WavefrontOBJ、FBX&#xff08;ASCII、二进制&#xff09;、STL&#xff08;ASCII、二进制&#x…

[附源码]Nodejs计算机毕业设计基于web的家教管理系统Express(程序+LW)

该项目含有源码、文档、程序、数据库、配套开发软件、软件安装教程。欢迎交流 项目运行 环境配置&#xff1a; Node.js Vscode Mysql5.7 HBuilderXNavicat11VueExpress。 项目技术&#xff1a; Express框架 Node.js Vue 等等组成&#xff0c;B/S模式 Vscode管理前后端分…