搜狐新闻直播间适配HarmonyOs实现点赞动画

01

背景介绍

随着新闻客户端鸿蒙单框架系统适配工作的推进,从原来的基础功能到现在已经适配全功能的85%以上。与此同时,我们也在持续深入挖掘鸿蒙系统的特性,以提升整体应用的质量与用户体验。在这一过程中,动画作为增强交互与视觉体验的重要手段,成为不可或缺的一环。本文将通过一个实际案例,详细介绍鸿蒙 ArkUI 动画的用法,如何利用ArkUI提供的API及其特性实现相对复杂的动画,并对比 Android 平台的实现方式。首先,我们来看一下新闻客户端在 Android 上直播间点赞动效的效果,见图1。图2为利用ArkUI动画API在HarmonyOS系统上实现的效果:

图1

图2

动画解析:当发生点击事件时,点赞按钮会有一个放大动画,随之点赞按钮底部会出现一个飘动的爱心,向上按照一定的曲线进行位移,同时在位移的过程中伴随有透明度,缩放的变化,同时点赞数加一,这一系列变化是一组动画;当长按事件触发时,以固定的频率连续触发这一组动画的播放。

02

ArkUI动画API简介

ArkUI提供了全面的动画实现方式,其中包括属性动画、转场动画、粒子动画、组件动画、帧动画等。目前在整个适配过程中,我们用的比较多的就是属性动画和转场动画,而属性动画也是最适合为组件定制动效的API。ArkUI提供了三种属性动画接口:animateTo、animation和keyframeAniamteTo。

animateTo是一个通用函数,通过对比闭包内状态变量和闭包前状态变量的差异通过改变状态变量实现动画效果,支持嵌套、能多次调用。animation是组件的一个属性,只能改变该属性之前设置的组件属性,keyframeAniamteTo是关键帧动画,通过设置关键帧实现动画效果。本次动画使用animateTo实现动画,该API介绍如下:

animateTo(value: AnimateParam, event: () => void): void

AnimateParam可以指定本次动画的时长、曲线效果(Curve)、重复次数、结束回调等参数,而event闭包则是本次动画需要改变哪些状态变量,更多参数可查阅鸿蒙的开发文档。

03

Android实现

先介绍下Android上实现的方法,向上飘动的爱心所做出的透明度、缩放动画相对容易实现,位移的曲线动画是这个动画比较难实现的点。如何让飘动的爱心每一次路径都不重复,并且能够实现一个平滑的曲线效果呢?这里就要用到强大的贝塞尔曲线了,通过输入不同的起点和终点以及控制点,就可以绘制不同效果的曲线,从而实现连续且弧度优美的路径曲线。当完成了路径的动画之后,加上透明度、缩放动画就能实现上述效果了。下面结合代码讲解实现的核心思路:

首先自定义组合View,按照效果图所示结构进行布局,布局底部放一个用于显示点赞图标的ImageView,在图标顶部放置一个TextView用于显示点赞数。然后监听图标的点击事件,当点击事件触发时,我们利用Android 系统中View的public void addView(View child, int index, LayoutParams params)方法添加一个用于做动画的ImageView,该ImageView就是接下来用于进行动画的核心对象。添加完执行动画的View就可以构造动画集合执行动画了。具体添加动画ImageView的方法如下:

private fun addHeartImage() {mVibrator.vibrate(10)val moveImage = ImageView(context)if (mFlyDrawable == null) {moveImage.setImageResource(R.drawable.ico_live_new_heart)} else {moveImage.setImageDrawable(mFlyDrawable)//服务器下发}addView(moveImage, 0, LayoutParams(mLikedImg.width, mLikedImg.height).apply {addRule(CENTER_HORIZONTAL, TRUE)addRule(ALIGN_PARENT_BOTTOM, TRUE)bottomMargin = DensityUtils.dip2px(context, 24f)})val animatorSet = AnimatorSet()val moveAnimator = getBezierAnimator(moveImage)val scaleXAnimator = getScaleAnimator(moveImage, "scaleX")val scaleYAnimator = getScaleAnimator(moveImage, "scaleY")animatorSet.playTogether(moveAnimator, scaleXAnimator, scaleYAnimator)animatorSet.duration = mAnimationDurationanimatorSet.start()
}

第二步是完善第一步中的getBezierAnimator()方法,该方法会返回一个ValueAnimator对象,这个动画对象实现的就是开头介绍的贝塞尔曲线。利用Android动画框架的属性动画、以及自定义估值器,可以实现Android动画系统规定以外的类型插值。这里自定义一个估值器,因为路径动画是通过控制ImageView的x和y属性实现位移,因此估值器的泛型定义为PointF类型,三次贝塞尔曲线的公式如下:

根据上述公式,我们可以完成估值器的计算过程如下:

/*** 计算贝塞尔曲线路径,实现自然平滑的动画效果*/
class BezierEvaluator(privateval controlPoint1: PointF, privateval controlPoint2: PointF) : TypeEvaluator<PointF> {overridefun evaluate(fraction: Float, startValue: PointF, endValue: PointF): PointF {val pathPoint = PointF()// 贝塞尔三次方公式pathPoint.x =startValue.x * (1 - fraction) * (1 - fraction) * (1 - fraction) +3 * controlPoint1.x * fraction * (1 - fraction) * (1 - fraction) +3 * controlPoint2.x * fraction * fraction * (1 - fraction) +endValue.x * fraction * fraction * fractionpathPoint.y =startValue.y * (1 - fraction) * (1 - fraction) * (1 - fraction) +3 * controlPoint1.y * fraction * (1 - fraction) * (1 - fraction) +3 * controlPoint2.y * fraction * fraction * (1 - fraction) +endValue.y * fraction * fraction * fractionreturn pathPoint}
}

三次贝塞尔曲线一共有四个点,起始点、终点以及两个控制点,发生位移的ImageView在向上移动的过程中,起始点是固定的,终点是随机的,要实现下图摆动曲线的效果,两个控制点必须控制在图中黄色区域内,当控制点也随机产生之后,动画的曲线就不再重合,从而实现向上移动并随机摆动的效果。

根据上述思路以及三次贝塞尔曲线计算View的x、y属性的插值器,完善获取贝塞尔曲线位移效果的动画代码如下:

/*** 注:* DensityUtils.dip2px(context, 35f):点赞按钮图片的大小* DensityUtils.dip2px(context, 24f):点赞按钮距父控件底部的 Margin*/
privatefun getBezierAnimator(targetView: View): ValueAnimator {//计算随机控制点val pointF1 = PointF(Random.nextInt(width - DensityUtils.dip2px(context, 35f)).toFloat(),Random.nextInt(height / 2) + height / 2f - DensityUtils.dip2px(context, 35f + 24f).toFloat())val pointF2 = PointF(width / 2 + Random.nextInt(width).toFloat() / 2 - DensityUtils.dip2px(context, 35f),Random.nextInt(height / 2).toFloat())Log.d(TAG, "pointF1 = (${pointF1.x},${pointF1.y})")Log.d(TAG, "pointF2 = (${pointF2.x},${pointF2.y})")//计算起始点和终点val startPoint = PointF((width / 2 - DensityUtils.dip2px(context, 35f) / 2).toFloat(),height - DensityUtils.dip2px(context, 35f + 24f).toFloat())val endPoint = PointF(Random.nextInt(width - DensityUtils.dip2px(context, 35f)).toFloat(), 0f)Log.d(TAG, "startPoint = (${startPoint.x},${startPoint.y})")Log.d(TAG, "endPoint = (${endPoint.x},${endPoint.y})")val bezierEvaluator = BezierEvaluator(pointF1, pointF2)val valueAnimator = ObjectAnimator.ofObject(bezierEvaluator, startPoint, endPoint)valueAnimator.duration = mAnimationDurationvalueAnimator.interpolator = DecelerateInterpolator()valueAnimator.addListener(object : AnimatorListenerAdapter() {overridefun onAnimationStart(animation: Animator) {addLikedNum()}overridefun onAnimationEnd(animation: Animator) {removeView(targetView)}})valueAnimator.addUpdateListener { animator: ValueAnimator ->// 自定义估值器BezierEvaluator的贝塞尔公式算出的 pointval bezierPoint = animator.animatedValue as PointFtargetView.x = bezierPoint.xtargetView.y = bezierPoint.ytargetView.alpha = (1 - animator.animatedFraction + 0.1).toFloat()}return valueAnimator
}

04

HarmonyOS实现

HarmonyOS系统上,ArkUI动画框架提供的API与Android系统的动画框架差别比较大,在HarmonyOS系统中,动画的实现方式有属性动画、帧动画、粒子动画等,从Android上实现的经验来看使用属性动画实现该案例比较合适。ArkUI是声明式UI,并没有类似Android中可以在运行时直接添加组件的方法,所以需要找到代替方案替代Android上的addView() 和 removeView()方法。

在ArkUI中,控制渲染流程可以用到if/else、ForEach 以及LazyForEach,该动画需要考虑到用户连续点击,多个向上位移动画的组件同时渲染,因此if/else并不合适,ForEach需要搭配List容器组件使用,因此只剩下LazyForEach。Ark UI中,UI的变化是通过状态变量控制的,由此需要设计一个数组,初始化为空数组,当触发一次动画操作时,向数组中添加一个数据,此时系统会根据数组的数量自动渲染对应的组件,当组件准备完成时执行属性动画,控制动画的状态变量放在数组里的对象中,当动画执行结束时,从数组中移除该数据,相应的组件也随之移除。

首先还是构建组件的布局,按照效果图依然封装自定义组件,采用Image组件进行点赞按钮的渲染,同时使用Text组件进行点赞数的展示,通过DevcoStudio中的ArkUI Inspector可以得到布局效果如下图所示:

组件布局结构代码实现如下,同时利用LazyForEach的特性为后面动态添加组件做渲染流程控制,build函数内代码如下:

build() {Stack({ alignContent: Alignment.Bottom }) {LazyForEach(this.animaList, (item: AnimationState) => {//当animaList中添加数据时,可以在这里渲染对应的UI组件,即一个向上飘动的Image组件,//向上飘动的过程由动画实现}, (item: AnimationState) =>JSON.stringify(item))Column({ space: 2 }) {Text(this.liveRoomViewModel.liveData.likeCount.toString()).fontSize(9).fontColor($r('app.color.text5')).fontWeight(FontWeight.Bold).width('100%').textAlign(TextAlign.Center)Image($r('app.media.ico_live_new_heart')).width(35).height(35).borderRadius(35).scale({ x: this.likedButtonScale, y: this.likedButtonScale }).backgroundColor('#40ffffff').draggable(false).onClick(()=>{//当点击时间触发时,向this.animaList中添加一个数据,对应会渲染一个动画组件})}}.width(65).height(200)
}

上述代码中,Image组件上设置点击事件,当点击事件触发时,向数组中添加一条数据,而该数组所绑定的LazyForEach组件会执行对应的渲染逻辑,当一次点击发生时,需要对应渲染一个Image组件,同时进行对应的动画,动画结束时将该数据从数组中移除,执行完动画的组件随即从组件树中移除。多次点击产生的多个动画对象不能相互影响,因此将控制动画的状态变量保存在数组对应的对象中,因此设计如下类保存动画所需数据:

@ObservedV2
exportclass AnimationState {
@Trace P0: number[] = [0, 0]; // 起点(通常为 View 的初始位置)
// 控制点1
@Trace P1: number[] = [this.getRandomInt(0, 65), this.getRandomInt(0, -80)];
// 控制点2 
@Trace P2: number[] = [this.getRandomInt(0, 65), this.getRandomInt(-80, -165)]; 
@Trace P3: number[] = [this.getRandomInt(-15, 15), -140]; // 终点
@Trace progress: number = 0; // 动画进度 0~1
@Trace scale: number = 0.3; //缩放动画
@Trace alpha: number = 0.8; //透明度动画id: string = ''//数据时间戳用于唯一标识constructor(id: string) {this.id = id}getRandomInt(min: number, max: number): number {returnMath.floor(Math.random() * (max - min + 1)) + min;}
}

AnimationState 类中一些常数是组件的尺寸大小,通过计算起点、控制点、终点需要限制在一定的范围内,类似于Android中实现的那样。变量progress是动画的一个核心变化因子,类似于Android估值器实现类evaluate方法中的fraction变量,progress随着动画的时间变化由0到1变化,变化的效果由动画设置的曲线决定。scale、alpha分别控制动画的缩放、透明度变化。

如何启动动画呢?首先在Image组件的点击事件方法中向数组中添加一个对象,同时设置好动画参数的初始值,代码如下:

this.animaList.pushData(new AnimationState(Date.now().toString()))

当this.animaList数组中有数据添加时,LazyForEach即开始渲染对应的组件,因此在对应处渲染一个Image组件,设置好业务需要的图片,当组件准备完成即将送显时,利用ArkUI提供的动画API animateTo()方法开启动画,animateTo()方法可参考官方文档链接(https://developer.huawei.com/consumer/cn/doc/harmonyos-references/ts-explicit-animation),该方法主要设置动画的时长、曲线、重复方式以及哪些属性要做动画,比如在该方法的闭包中将progress的值赋值为1,时长设置为1000毫秒,那么progress的值会在设置的时间内根据曲线的效果进行不断的改变,时间结束时会变成赋值的1。具体代码如下,在闭包中同时开启了缩放动画和透明度动画,也就是progress的变化与缩放动画、透明度变化同时开始,具体代码如下:

LazyForEach(this.animaList, (item: AnimationState) => {Image(this.flyImageLoadFailed ? $r('app.media.ico_zan_v6') :this.liveRoomViewModel.liveInfoModel.likeAnimation || $r('app.media.ico_zan_v6')).width(35).height(35).opacity(item.alpha).onError(() => {this.flyImageLoadFailed = true}).scale({x: item.scale,y: item.scale}).translate({x: this.calculateCubicBezier(item.P0, item.P1, item.P2, item.P3, item.progress)[0],y: this.calculateCubicBezier(item.P0, item.P1, item.P2, item.P3, item.progress)[1]}).onAppear(() => {this.liveRoomViewModel.localCacheLikedNum ++animateTo({duration: 1000, // 动画时长curve: Curve.Ease, //动画以低速开始,然后加快,在结束前变慢iterations: 1, // 播放次数(-1 表示无限循环)playMode: PlayMode.Normal,onFinish: () => {this.animaList.deleteData(this.animaList.findIndex((findItem) => findItem.id === item.id))}}, () => {//缩放动画animateTo({duration: 500, // 动画时长curve: Curve.EaseIn, //动画以低速开始iterations: 1, // 播放次数(-1 表示无限循环)playMode: PlayMode.Normal,onFinish: () => {animateTo({duration: 500, // 动画时长curve: Curve.EaseOut, //动画以低速结束iterations: 1, // 播放次数(-1 表示无限循环)playMode: PlayMode.Normal,}, () => {item.scale = 0.3})}}, () => {item.scale = 1.2})//透明度动画animateTo({duration: 800, // 动画时长curve: Curve.EaseOut, //动画以低速结束iterations: 1, // 播放次数(-1 表示无限循环)playMode: PlayMode.Normal,delay: 200,}, () => {item.alpha = 0})vibrationV2(50,'alarm')item.progress = 1; // 驱动 progress 从 0 到 1})})
}, (item: AnimationState) =>JSON.stringify(item))

随着动画的开始,组件还需要进行位移,设置的progress会从0变到1,那么就可以利用progress通过贝塞尔曲线计算动画组件的路径,通过公式可以得到如下方法:

// 三次贝塞尔计算公式,用于计算路径
private calculateCubicBezier(P0: number[], P1: number[], P2: number[], P3: number[], t: number): number[] {const x = (1 - t)**3 * P0[0] +3 * t * (1 - t)**2 * P1[0] +3 * t**2 * (1 - t) * P2[0] +t**3 * P3[0];const y = (1 - t)**3 * P0[1] +3 * t * (1 - t)**2 * P1[1] +3 * t**2 * (1 - t) * P2[1] +t**3 * P3[1];return [x, y];
}

该方法返回一个数组,同时该方法计算过程利用到数组中对象的状态变量,因此给组件设置translate时,利用该方法计算对应的x、y值,UI会随着progress的变化从而引起位置变化,从而达到触发位移动画的目的。同时在animateTo()方法的onFinish回调中移除这条数据,动画结束时组件自动从组件树移除,实现效果如本篇开头ArkUI实现效果所示,满足动效设计要求。

05

总结

本文主要介绍实现复杂动画的思路以及同样的动画HarmonyOS系统与Android系统的区别,其中一些业务代码未给出,这里只给出核心代码。ArkUI的动画框架对比Android系统的动画框架区别还是很大的,ArkUI是声明式UI,动画也是由状态变量驱动的,并且ArkUI引擎对动画渲染做了很多技术革新,掌握了ArkUI动画也能在开发中利用动画做出更好的过度效果,使应用更加流畅,自然。

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

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

相关文章

83、设置有人DTU设备USR-M100采集传感器数据,然后上传阿里云服务

基本思想:设置M100 采集传感器数据 一、首先将DTU设备USR-M100连接路由器上,然后使用python代码搜索同一局域网设备, import platform import sys import os import time import threadinglive_ip = 0def get_os():os = platform.system()if os == "Windows":re…

P1019 [NOIP 2000 提高组] 单词接龙

题目描述单词接龙是一个与我们经常玩的成语接龙相类似的游戏&#xff0c;现在我们已知一组单词&#xff0c;且给定一个开头的字母&#xff0c;要求出以这个字母开头的最长的“龙”&#xff08;每个单词都最多在“龙”中出现两次&#xff09;&#xff0c;在两个单词相连时&#…

详解力扣高频SQL50题之1633. 各赛事的用户注册率【简单】

传送门&#xff1a;1633. 各赛事的用户注册率 题目 用户表&#xff1a; Users -------------------- | Column Name | Type | -------------------- | user_id | int | | user_name | varchar | -------------------- user_id 是该表的主键(具有唯一值的列)。 该表中的每行包…

FROM stakater/java8-alpine 构建cocker镜像

在 Dockerfile 中&#xff0c;FROM stakater/java8-alpine 是第一条也是最核心的指令&#xff0c;它定义了构建新镜像所基于的「基础镜像」。以下是逐层解析&#xff1a;&#x1f50d; 关键字拆解 1. FROM —— 起点指令 ✅ 作用&#xff1a;声明当前镜像的起点&#xff08;父镜…

Word2Vec模型训练全流程解析:从数据预处理到实体识别应用

请添加图片描述 训练Word2Vec模型 概述 问题 我们如何训练Word2Vec模型&#xff1f;在特定数据集上训练Word2Vec模型何时是有利的&#xff1f; 目标 理解在自有数据上训练Word2Vec模型而非使用预训练模型的优势 Colab环境配置 运行以下代码以启用辅助函数并重新读取数据…

在Ubuntu上使用QEMU学习RISC-V程序(2)gdb调试

文章目录一、准备工作二、基本调试流程1. 设置断点2. 执行程序3. 查看源代码/汇编三、查看寄存器1. 查看通用寄存器2. 查看特殊寄存器四、查看内存1. 内存查看命令2. 内存修改命令五、调试实战示例六、高级调试技巧1. 条件断点2. 自动显示3. 内存断点&#xff08;观察点&#x…

不止于“亮”:一盏智慧路灯的技术进化史——塔能科技用“落地性”定义行业标准

在凌晨3点的园区道路之上&#xff0c;路灯会随着车辆的靠近而自动亮起&#xff0c;待车辆逐渐远去之后&#xff0c;又会缓缓地调暗下来&#xff1b;当电缆意外被触碰的时候&#xff0c;系统能够在短短3秒之内自动发出报警信息&#xff0c;并且推送出维修工单&#xff1b;而当一…

Redis的String数据类型底层实现

redis就是用c语言写&#xff0c;但redis的string并没有直接用c语言的string&#xff0c;而是自己搞了一个 SDS 结构体来表示字符串。SDS 的全称是 Simple Dynamic String&#xff0c;中文叫做“简单动态字符串”。想知道为什么这么做&#xff0c;我们先看看c语言的string是什么…

【音视频学习】四、深入解析视频技术中的YUV数据存储方式:从原理到实践

文章目录 引言 1. YUV 基础:为什么它比 RGB 更适合视频? 1.1 YUV 与 RGB 的核心区别 1.2 YUV色度下采样简介 2. YUV 的三大存储方式 方式一:平面格式(Planar) 方式二:半平面格式(Semi-Planar ) 方式三:打包格式(Packed YUV) 三种存储方式对比: 3. 如何选择合适的 Y…

前端项目组成

一、前端项目常见模块及功能&#xff08;以 Vue/React 通用结构为例&#xff09; 前端项目的模块本质是「按功能拆分的代码文件/文件夹」&#xff0c;就像盖房子的「砖、梁、窗」各司其职&#xff1a;模块类型功能说明&#xff08;大白话&#xff09;举个例子pages&#xff08;…

聚观早报 | 猿编程推动中美青少年AI实践;华为Pura 80数字版售价公布;iPhone 17 Air电池曝光

聚观早报每日整理最值得关注的行业重点事件&#xff0c;帮助大家及时了解最新行业动态&#xff0c;每日读报&#xff0c;就读聚观365资讯简报。整理丨肖羽7月24日消息猿编程推动中美青少年AI实践华为Pura 80数字版售价公布iPhone 17 Air电池曝光亚马逊收购AI初创公司Bee蜂巢半固…

unittest 案例执行顺序详解

unittest 案例执行顺序详解在 unittest 框架中&#xff0c;测试用例的执行顺序有默认规则&#xff0c;也可通过自定义方式调整。以下是具体说明&#xff1a;一、默认执行顺序规则unittest 对测试用例的执行顺序遵循 “按测试方法名的 ASCII 码排序” 原则&#xff0c;具体逻辑如…

【web大前端】001_前端开发入门:创建你的第一个网页

前端开发入门&#xff1a;创建你的第一个网页 在当今数字化时代&#xff0c;网页已经成为人们获取信息和交流的重要平台。对于想要学习编程的人来说&#xff0c;前端开发往往是一个不错的起点。本文将带你通过简单的两步&#xff0c;创建属于你的第一个网页程序。 点击这里去…

HTTP性能优化终极指南:从协议原理到企业级实践

前言&#xff1a;为什么性能优化是Web开发的生命线&#xff1f;根据Google研究数据&#xff0c;当页面加载时间从1秒增加到3秒时&#xff0c;跳出率提升32%&#xff1b;当达到5秒时&#xff0c;转化率下降90%。本文将通过七层优化体系&#xff0c;带您掌握HTTP性能优化的核心技…

Python 数据分析(二):Matplotlib 绘图

目录 1. 简介2. 绘图 2.1 折线图 2.1.1 单线2.1.2 多线2.1.3 子图 2.2 散点图2.3 直方图2.4 条形图 2.4.1 纵置2.4.2 横置2.4.3 多条 2.5 饼图 1. 简介 Matplotlib 是 Python 提供的一个绘图库&#xff0c;通过该库我们可以很容易的绘制出折线图、直方图、散点图、饼图等丰…

Scrapy分布式爬虫数据统计全栈方案:构建企业级监控分析系统

引言&#xff1a;数据统计在分布式爬虫中的战略价值在分布式爬虫系统中&#xff0c;​​数据统计与分析​​是系统优化的核心驱动力。根据2023年爬虫工程调查报告&#xff1a;实施专业统计方案的爬虫系统性能提升​​40%以上​​数据驱动的优化策略可减少​​70%​​的资源浪费…

计划任务(at和cron命令介绍及操作)

简介计划任务主要做一些周期性的任务&#xff0c;目前最主要的是定期备份数据分类at&#xff1a;一次性调度执行cron&#xff1a;循环调度执行at简介at 是一个用于安排一次性任务的命令行工具&#xff0c;适合在指定时间点执行单次任务语法at 时间 选项若要提交&#xff0c;通过…

[2025CVPR:图象合成、生成方向]WF-VAE:通过小波驱动的能量流增强视频 VAE 的潜在视频扩散模型

论文概述​ 这篇论文提出了一种名为WF-VAE(Wavelet Flow VAE)​的新型视频变分自编码器(Video VAE),旨在解决潜在视频扩散模型(LVDM)中的关键瓶颈问题,包括高计算成本和潜在空间不连续性。WF-VAE利用小波变换(Wavelet Transform)来分解视频信号,并通过能量流路径优…

Map接口-实现类HashMap

目录 一、什么是Map&#xff1f; 二、实现类HashMap 1.关键特点 无序、key唯一、value允许重复、key和value允许为null。 2.数据结构 2.1 JDK 1.7 2.2 JDK 1.8 2.3 关键参数 2.4 关键计算 3.扩容方式 3.1 初始化 3.2 扩容 4.常见方法 4.1 根据key存入value 4.2 …

深入解析Hadoop如何实现数据可靠性:三副本策略、校验和验证与Pipeline复制

Hadoop数据可靠性的重要性在大数据时代&#xff0c;数据可靠性已成为企业数字化转型的生命线。根据IDC预测&#xff0c;到2025年全球数据总量将增长至175ZB&#xff0c;其中企业数据占比超过60%。面对如此庞大的数据规模&#xff0c;任何数据丢失或损坏都可能造成数百万美元的经…