基于大数据的音乐推荐系统的设计与实现

article/2025/11/1 11:48:41

基于大数据的音乐推荐系统是为了给听众推荐符合内心喜好的个性化系统。系统提供的功能有,音乐管理:管理员可以添加删除音乐,音乐查找:用户可以在系统中自行查找想要听的歌曲,音乐推荐:系统在收集了用户的行为数据之后为用户个性化推荐音乐,用户管理:管理员可以对用户进行删除,评论管理:管理员可以对评论进行删除,音乐下载:用户可以自行下载个人喜欢分歌曲。
本系统部署在开源大数据平台hadoop3.5之上,搭配的spark2.2也为开源免费。后端使用的关系型数据库为mysql。开发软件使用的是eclipse社区版、pycharm社区版和其他一些免费开源软件。前端采用spring和ssm,技术已经较为成熟。
目 录
摘 要 I
Abstract II
1 绪论 1
1.1 研究背景 1
1.2 研究现状 1
1.2.1 国内研究现状 1
1.2.2 国外研究现状 2
1.3 发展趋势 2
2 相关技术介绍 3
2.1 大数据环境 3
2.1.1 全球开源的Linux系统-Ubuntu 3
2.1.2 开源分大数据处理平台Hadoop 3
2.1.3 shell 3
2.1.4 kettle 4
2.1.5 Scala 4
2.2 数据获取与处理 4
2.2.1 Pymysql 4
2.2.2 Urllib.request 4
2.2.3 besutifulsoup4 4
2.3网页端 5
2.3.1 tomcat9 5
2.3.2 spring 5
3 数据采集 6
3.1 数据源确定 6
3.2 爬虫数据库设计 6
3.3 数据爬取 7
4 系统分析 15
4.1 业务分析 15
4.2 系统功能分析 16
4.3 系统可行性分析 16
4.3.1 技术可行性分析 16
4.3.2 经济可行性分析 17
4.3.3 操作性可行性分析 17
4.4 数据字典 17
4.4.1 数据项条目 17
4.4.2 数据流 19
4.4.3 数据处理条目 21
5 系统设计 23
5.1 系统总体模块结构设计 23
5.2 局部模块设计 24
5.2.1 登录注册模块 24
5.2.2 热门推荐模块 25
5.2.3 新歌上架模块 26
5.2.4 个性化推荐模块 26
5.2.5 用户中心模块 27
5.2.6 音乐管理模块 27
5.2.7 用户管理模块 28
5.2.8 评论管理模块 28
5.3 系统角色功能设计 29
5.4 推荐系统数据库设计 29
5.4.1 数据库概念结构设计 29
5.4.2 数据库物理结构设计 32
5.5 大数据平台搭建设计 35
5.5.1 hadoop的安装与配置 35
5.5.2 spark的安装 38
5.6 推荐算法设计 39
6 系统实现 46
6.1 用户界面 46
6.1.1 系统主页 46
6.1.2 用户登录 46
6.1.3 用户注册 47
6.1.4 用户登陆后界面 49
6.1.5 热门推荐界面 49
6.1.6 音乐播放详情界面 50
6.1.7 个性化音乐推荐详情界面 51
6.1.8 个人音乐记录页面 51
6.2 管理员界面 53
6.2.1 管理员登录 53
6.2.3 评论管理界面 54
6.2.4 用户管理界面 55
总结与展望 56
致 谢 57
参考文献 58
2.2 数据获取与处理
2.2.1 Pymysql
Mysql是如今最为普遍的数据库里,而python作为比较流行的语言之一,自然少不了与mysql做交互,其中pymysql就是使用最多的工具库了。Python导入pymysql之后,配置完数据库就可以直接操作数据库内各种表等。
2.2.2 Urllib.request
Urllib.request 模块定义了适用于在各种复杂情况下打开 URL(主要为 HTTP)的函数和类 — 例如基本认证、摘要认证、重定向、cookies 及其它。Requests 继承了urllib2的所有特性。Requests支持HTTP连接保持和连接池,支持使用cookie保持会话,支持文件上传,支持自动确定响应内容的编码,支持国际化的 URL 和 POST 数据自动编码。Requests的文档非常完备,中文文档也相当不错。Requests能完全满足当前网络的需求,支持Python 2.6—3.8,而且能在PyPy下完美运行。
2.2.3 besutifulsoup4
HTML 文档本身是结构化的文本,有一定的规则,通过它的结构可以简化信息提取。于是,就有了lxml、pyquery、BeautifulSoup等网页信息提取库。一般会用这些库来提取网页信息。其中,lxml 有很高的解析效率,支持 xPath 语法(一种可以在 HTML 中查找信息的规则语法);pyquery 得名于 jQuery(知名的前端 js 库),可以用类似 jQuery 的语法解析网页。
BeautifulSoup(下文简称 bs)翻译成中文就是“美丽的汤”,这个奇奇怪怪的名字取自于《爱丽丝梦游仙境》,bs 最大的特点就是简单易用,不需要像正则和 xPath 等工具必须牢记很多特定的语法。虽然效率更高更直接,但对大多数 python 使用者来说,好用会比高效更重要。
2.3网页端
2.3.1 tomcat9
Tomcat是Apache Software Foundation的Jakarta项目的核心组件,该项目是由Apache,Sun和一些公司和个人开发的轻量级Web应用程序服务器。是Servlet和JSP规范的开源实现。由于其技术非常先进,而且工作稳且性能高,它深受java爱好者的追捧,很多开源边界者都对他赞赏有加。目前呢已经成为最流行流行的Web应用程序服务器。
2.3.2 spring
Spring框架是Rod Johnson启动的开源J2EE应用程序框架,而Rod Johnson是用于bean生命周期管理的轻量级容器。 Spring解决了J2EE开发过程中开发人员遇到的较多常见问题,还提供了非常实用的功能,例如IOC,AOP,Web MVC等。 Spring甚至可以单独构建,也可以与Struts,Webwork和Tapstry等桌面应用程序结合以创建JEE,桌面和小型应用程序。
3 数据采集
3.1 数据源确定
确定了要做基于大数据的音乐推荐系统之后,首先要确定数据源。通过分析基于大数据的音乐推荐系统,即音乐推荐需要哪些数据,详细了解推荐机制,搞清楚这些数据需要被处理为什么格式。
首先定义爬取目标:
1.实现音乐的个性化推荐,帮助用户快速找到可能感兴趣的音乐。
2.实现音乐的热门推荐,帮助主流大众迅速找到流行的趋势。
3.实现音乐的新品推荐,帮助唱片公司带动市场,实现引流。
各大音乐网站多如牛毛,确定了数据爬取目标之后,接下来要确定去哪个平台去爬取泽泻数据。选择数据源要确定数据源数据是否可靠真实,要避免爬取音乐平台发布的虚伪的音乐数据,如不存在的歌唱家、专辑、音乐等。
于是,在比较多家音乐平台(QQ音乐、网易云音乐、酷狗音乐、酷音乐)后,综合分析后选择网易云音乐网页版作为爬虫目标。基于之前设定的爬取目标,选择爬取以下数据:
1.歌手信息:歌手id,歌手名字
2.歌手专辑信息:专辑id,专辑名称,专辑封面
3.音乐信息:音乐名

歌曲推荐算法

package top.wangruns.trackstacking.algorithm;import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.Consumer;public class CollaborativeFiltering {/*** 基于最近邻用户产生协同过滤的推荐结果* @param userIdList* 用户Id列表* @param userKNNMatrix* 用户KNN矩阵* @param user2songRatingMatrix* 用户歌曲“评分”矩阵* @param songIdList* 歌曲Id列表* @param n* 推荐的前n首歌曲* @return* 用户歌曲推荐结果矩阵.userId,[recSongId1,recSongId2...recSongIdn]*/public static Map<Integer, Integer[]> userKNNBasedCF(List<Integer> userIdList,final Map<Integer, Integer[]> userKNNMatrix, final Map<Integer, float[]> user2songRatingMatrix,final List<Integer> songIdList, final int n) {// TODO Auto-generated method stubfinal Map<Integer,Integer[]> user2songRecMatrix=new HashMap<Integer, Integer[]>();userIdList.forEach(new Consumer<Integer>() {public void accept(Integer curUserId) {// TODO Auto-generated method stubInteger[] knnIdArray=userKNNMatrix.get(curUserId);/*** 对于每一首当前用户没有听过的歌曲* 协同得分为:* 其k个最近邻用户对该歌曲的“评分”的聚合*/float[] curUserRatings=user2songRatingMatrix.get(curUserId);//为用户建立一个最小堆来存放最高的前n首歌曲MininumHeap mininumHeap=new MininumHeap(n);for(int i=0;i<curUserRatings.length;i++) {//对于没有听过的歌曲/*** 这里需要注意的是,浮点数不能用==来比较...之前竟然犯了这个低级的错误...* 故这里用 curUserRatings[i]<0.01f 来表示 curUserRatings[i]==0f*/if(curUserRatings[i]<0.01f) {for(int knnIndex=0;knnIndex<knnIdArray.length;knnIndex++) {int knnId=knnIdArray[knnIndex];float[] knnUserRatings=user2songRatingMatrix.get(knnId);curUserRatings[i]+=knnUserRatings[i];}//这里的聚合策略取均值curUserRatings[i]/=knnIdArray.length;int curSongId=songIdList.get(i);//放入堆中mininumHeap.addElement(new TreeNode(curSongId,curUserRatings[i]));}}/*** 对该用户没有听过的歌曲,协同得分完成,选取n个得分最高的项目作为推荐*/int trueNumber=n;//如果推荐的歌曲少于计划推荐的n首(处理歌曲很少的情况)if(mininumHeap.getCurHeapSize()<n) {trueNumber=mininumHeap.getCurHeapSize();}Integer[] curUserRecSongId=new Integer[trueNumber];for(int i=0;i<trueNumber;i++) {int recSongId=mininumHeap.getArray()[i].id;curUserRecSongId[i]=recSongId;}user2songRecMatrix.put(curUserId, curUserRecSongId);}});return user2songRecMatrix;}}

获取歌曲信息代码:

package top.wangruns.trackstacking.algorithm;import java.lang.reflect.Field;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.function.Consumer;import top.wangruns.trackstacking.model.Collection;
import top.wangruns.trackstacking.model.DownloadRecord;
import top.wangruns.trackstacking.model.PlayRecord;
import top.wangruns.trackstacking.model.User;public class DataTranslate {private final static float PLAY_SCORE=1f;private final static float DOWNLOAD_SCORE=2f;private final static float COLLECTION_SCORE=5f;private final static float MAX_SCORE=10f;private final static int SONG_ID_SET_KEY=0;/*** 构建用户频率矩阵来近似用户评分,对于某些系统而言,我们是不可能获取到用户对某些项目的评分的,但是我们可以利用用户的* 行为习惯来反映用户的“评分”,比如一个用户常常收听某一首歌,那么我们可以推断该用户喜欢该歌曲的可能性很大.* 总分10分,主动播放一次1分,下载2分,收藏5分,如果超过10分,按10分计算.* @param userIdList * 用户Id列表* @param songIdList * 歌曲Id列表* @param downloadList* 用户的下载记录列表* @param playList* 用户的播放记录列表* @param collectionList* 用户的收藏记录列表* @return* 用户Id-歌曲Id 频率矩阵*/public static Map<Integer, float[]> getFrequencyMatrix(List<Integer> userIdList, final List<Integer> songIdList,List<DownloadRecord> downloadList, List<PlayRecord> playList, List<Collection> collectionList) {// TODO Auto-generated method stubfinal Map<Integer,float[]> user2songRatingMatrix=new HashMap<Integer, float[]>();final int songLen=songIdList.size();//获取用户-歌曲 下载映射final Map<Integer,Map<Integer,Set<Integer>>> userId2songIdDownloadMap=getUserId2songIdRecordMap(downloadList,false);//获取用户-歌曲 收藏映射final Map<Integer, Map<Integer, Set<Integer>>> userId2songIdCollectionMap=getUserId2songIdRecordMap(collectionList,false);//获取用户-歌曲-次数 播放映射final Map<Integer, Map<Integer, Set<Integer>>> userId2songIdPlayMap=getUserId2songIdRecordMap(playList,true);userIdList.forEach(new Consumer<Integer>() {public void accept(Integer userId) {// TODO Auto-generated method stubfloat[] curUserRatingArray=new float[songLen];int songIndex=0;//处理每一首歌曲for(Integer songId:songIdList) {/*** 处理下载,这里不考虑下载次数*/if(userId2songIdDownloadMap.get(userId)!=null && userId2songIdDownloadMap.get(userId).get(SONG_ID_SET_KEY).contains(songId)) {//当前用户下载过的歌曲curUserRatingArray[songIndex]+=DOWNLOAD_SCORE;}/*** 处理收藏,这里没有次数*/if(userId2songIdCollectionMap.get(userId)!=null && userId2songIdCollectionMap.get(userId).get(SONG_ID_SET_KEY).contains(songId)) {//当前用户收藏的歌曲curUserRatingArray[songIndex]+=COLLECTION_SCORE;}/*** 处理播放,考虑播放次数*/if(userId2songIdPlayMap.get(userId)!=null && userId2songIdPlayMap.get(userId).get(SONG_ID_SET_KEY).contains(songId)) {//当前用户播放过的歌曲int count=userId2songIdPlayMap.get(userId).get(songId).iterator().next();curUserRatingArray[songIndex]+=PLAY_SCORE + count;}/*** 处理最大得分,超过最大得分,记为最大得分*/if(curUserRatingArray[songIndex]>MAX_SCORE) {curUserRatingArray[songIndex]=MAX_SCORE;}//处理下一首歌songIndex++;}//处理完一个用户user2songRatingMatrix.put(userId, curUserRatingArray);}});return user2songRatingMatrix;}/*** 获取用户Id - 歌曲Id 的映射Map* @param recordList* 包含userId,songId的记录列表* @param isCount* 是否需要计数。如果true,则Integer[1]存放计数。* @return* 两层Map* 第一层Map<Integer,Map> 每个userId拥有一个自己的Map:* userId,userSetMap* * 第二层Map<Integer,Set> 用户自己的Map里面存放两个东西:* (1)为每首歌曲计数songId,CountSet;* (2)存放出现过的歌曲songSetFlay,SongIdSet:*/private static <T> Map<Integer, Map<Integer, Set<Integer>>> getUserId2songIdRecordMap(final List<T> recordList,final boolean isCount) {// TODO Auto-generated method stubfinal Map<Integer, Map<Integer, Set<Integer>>> userId2songIdRecordMap=new HashMap<Integer, Map<Integer, Set<Integer>>>();recordList.forEach(new Consumer<T>() {public void accept(T t) {// TODO Auto-generated method stubtry {//利用反射获和泛型获取不同类型表的相同属性Field userIdField=t.getClass().getDeclaredField("userId");Field songIdField=t.getClass().getDeclaredField("songId");userIdField.setAccessible(true);songIdField.setAccessible(true);int userId=userIdField.getInt(t);int songId=songIdField.getInt(t);//不需要计数if(!isCount) {//map外层的userId已经存在if(userId2songIdRecordMap.containsKey(userId)) {//获取当前用户的记录集合MapMap<Integer,Set<Integer>> curRecordSetMap=userId2songIdRecordMap.get(userId);//将当前歌曲添加到当前用户的记录集合中curRecordSetMap.get(SONG_ID_SET_KEY).add(songId);}else {Map<Integer,Set<Integer>> curRecordSetMap=new HashMap<Integer, Set<Integer>>();//创建记录歌曲Id的集合Set<Integer> curSongIdSet=new HashSet<Integer>();curSongIdSet.add(songId);curRecordSetMap.put(SONG_ID_SET_KEY, curSongIdSet);userId2songIdRecordMap.put(userId, curRecordSetMap);}}else {//map外层的userId已经存在if(userId2songIdRecordMap.containsKey(userId)) {//获取当前用户的记录集合MapMap<Integer,Set<Integer>> curRecordSetMap=userId2songIdRecordMap.get(userId);//将当前歌曲添加到当前用户的记录集合中curRecordSetMap.get(SONG_ID_SET_KEY).add(songId);//计数count(songId,curRecordSetMap);}else {Map<Integer,Set<Integer>> curRecordSetMap=new HashMap<Integer, Set<Integer>>();//创建记录歌曲Id的集合Set<Integer> curSongIdSet=new HashSet<Integer>();curSongIdSet.add(songId);curRecordSetMap.put(SONG_ID_SET_KEY, curSongIdSet);userId2songIdRecordMap.put(userId, curRecordSetMap);//计数count(songId,curRecordSetMap);}}}catch (NoSuchFieldException e) {e.printStackTrace();} catch (IllegalArgumentException e) {e.printStackTrace();} catch (IllegalAccessException e) {e.printStackTrace();}}private void count(int songId, Map<Integer, Set<Integer>> curRecordSetMap) {// TODO Auto-generated method stub/*** 计数,如果Map<songId,count>已经存在,则直接计数+1*/if(curRecordSetMap.containsKey(songId)) {//获取当前用户歌曲的计数集合(只有一个元素)Set<Integer> curCountSet=curRecordSetMap.get(songId);int cnt=curCountSet.iterator().next()+1;curCountSet.clear();curCountSet.add(cnt);}else {Set<Integer> curCountSet=new HashSet<Integer>();curCountSet.add(1);curRecordSetMap.put(songId, curCountSet);}}});return userId2songIdRecordMap;}//	private static Map<Integer, Integer>getUserId2songIdDownloadMap(List<DownloadRecord> downloadList) {
//		// TODO Auto-generated method stub
//		final Map<Integer,Integer> userId2songIdDownloadMap=new HashMap<Integer, Integer>();
//		downloadList.forEach(new Consumer<DownloadRecord>() {
//
//			public void accept(DownloadRecord t) {
//				// TODO Auto-generated method stub
//				if(!userId2songIdDownloadMap.containsKey(t.getUserId())) {
//					userId2songIdDownloadMap.put(t.getUserId(), t.getSongId());
//				}
//			}
//			
//		});
//		return userId2songIdDownloadMap;
//	}}

在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述


http://chatgpt.dhexx.cn/article/MMNa3DLV.shtml

相关文章

context-aware recommendation

智能手机的普及让大家随时随地都可接入互联网&#xff0c;而这样的随时随地的应用场景&#xff0c;也让传统推荐技术需要充分考虑&#xff0c;利用这些信息提升推荐的准确性&#xff0c;同时从另外一方面考虑&#xff0c; 这种符合LBS的推荐&#xff0c; 因为有了这些信息后&am…

accept函数_使用函数式接口

像上几章提到的&#xff0c;函数式接口定义且只定义了一个抽象方法。函数式接口很有用&#xff0c;因为抽象方法的签名可以描述Lambda表达式的签名。函数式接口的抽象方法的签名成为函数描述符。所以为了应用不同的Lambda表达式&#xff0c;你需要一套能够描述常见函数描述符的…

accept函数(TCP)

accept函数&#xff08;TCP&#xff09; #include <sys/types.h> /* See NOTES */ #include <sys/socket.h> int accept(int sockfd, struct sockaddr *addr, socklen_t *addrlen);功能&#xff1a;阻塞等待客户端的连接请求 sockfd&#xff1a;文件描述符&#…

Context context = getApplicationContext()

使用getApplicationContext 取得的是当前app所使用的application&#xff0c;这在AndroidManifest中唯一指定。意味着&#xff0c;在当前app的任意位置使用这个函数得到的是同一个Context 1、Context概念 其实一直想写一篇关于Context的文章&#xff0c;但是又怕技术不如而误人…

AutoCompleteTextView

自动完成的提供建议的文本 使用方法 //arrays.xml <?xml version"1.0" encoding"utf-8"?> <resources><array name"city_name"><item>Chengdu</item><item>Beijing</item><item>Tianjin<…

http状态码、accept、Content-Type

一、http状态码 &#xff08;1&#xff09;http状态码 1XX&#xff1a;信息&#xff0c;服务器收到请求&#xff0c;需要请求者继续执行操作 2XX&#xff1a;成功&#xff0c;操作被成功接收并处理 3XX&#xff1a;重定向&#xff0c;需要进一步的操作以完成请求 4XX&#xf…

Gated-Attention Readers for Text Comprehension

Gated-Attention Readers for Text Comprehension 文本理解中的门控attention阅读器 code Abstract 本文研究的是完形填空问题式MRC&#xff0c;作者提出的门控注意力阅读器集中了多跳结构和一种新的注意力计算机制&#xff08;基于query嵌入和RNN文档阅读器中间状态之间的…

Html中Input的accept属性

Accept属性规定通过在文件上传提交的服务接受的文件类型 但是accept属性只能适用在Html input类型为文件类型&#xff0c;也就是说其他类型的input accept属性就不适用 我写的这个过滤文件属性是针对于后缀名为.xls的文件&#xff0c;所有的文件只要不是.xls后缀就不显示出来…

ApplicationContext

如果说BeanFactory是Spring的心脏&#xff0c;那么Application就是完整的身躯。ApplicationContext就是由BeanFactory派生出来的。 1、ApplicationContext ApplicationContext的主要实现类是ClassPathXmlApplicationContext和FileSystemXmlApplicationContext,前者默认从类路径…

ActionContext

1、ActionContext翻译成中文就是Action的上下文&#xff08;为什么说是上下文&#xff0c;是应为他的生命周期长&#xff0c;和我们的项目的生命周期是相同的&#xff0c;我们很多公共的东西都放在里面&#xff0c;方便存取 &#xff09;&#xff0c;ActionContext是struts2的上…

readonly option is set (add ! to override)错误的解决

在mac电脑或linux系统中经常操作修改某个文件后保存退出出现readonly option is set (add ! to override)。如图&#xff1a; 正常情况下按 A进入编辑模式修改文件后按ESC退出编辑模式&#xff0c;:wq命令保存退出&#xff0c;但经常会遇到以上显示&#xff0c;文件权限只读或者…

ByteBuffer的allocate和allocateDirect

在Java中当我们要对数据进行更底层的操作时&#xff0c;通常是操作数据的字节&#xff08;byte&#xff09;形式&#xff0c;这时常常会用到ByteBuffer这样一个类。ByteBuffer提供了两种静态实例方式&#xff1a; Java代码 public static ByteBuffer allocate(int capacity…

直接内存 直接内存的释放和回收

直接内存 特点 不属于Java虚拟机管理&#xff0c;属于系统内存&#xff1b;属于操作系统&#xff0c;常见于NIO操作时&#xff0c;比如ByteBuffer【】用于数据缓冲区分配回收成本较高&#xff0c;但读写性能高&#xff1b;不受JVM内存回收管理 文件读写过程 java不具备磁盘…

解决The‘Access-Control-Allow-Origin‘ header contains multiple values‘*, ....‘, but only one is allowed

报错内容&#xff1a; Access to XMLHttpRequest at ‘http://www.z…n.com/api/login’ from origin ‘http://z…n.com’ has been blocked by CORS policy: The ‘Access-Control-Allow-Origin’ header contains multiple values ‘*, http://z…n.com’, but only one is …

C++中std::allocator的使用

标准库中包含一个名为allocator的类&#xff0c;允许我们将分配和初始化分离。使用allocator通常会提供更好的性能和更灵活的内存管理能力。 new有一些灵活性上的局限&#xff0c;其中一方面表现在它将内存分配和对象构造组合在了一起。类似的&#xff0c;delete将对象析构和内…

alloc的流程

1⃣️ 2⃣️ 3⃣️ 现在我们看的objc源码都是2.0的版本&#xff0c;之前还有一个1.0的版本 4⃣️ 5⃣️核心方法 最主要的就是最下面三个方法 他的最重要作用就是开辟内存 cls->instanceSize 先计算出需要的内存空间大小这个大小只和对象的成员变量有关 在没有成员变量…

ByteBuffer.allocate()与allocateDirect()的区别

allocate()产生的是HeapByteBuffer的实例, 本质上是一个no direct buffer, allocateDirect()产生的是DirectByteBuffer的实例, 本质是一个direct buffer 主要区别 buffer的创建方式不同, no direct buffer还可以通过封装已存在的byte array来产生执行IO操作时不同, no direct …

ByteBuffer常用方法与分析

目录 目标 常用API 工具方法 演示案例 allocate(int capacity)和allocateDirect(int capacity) put()和get() flip()和hasRemaining() clear() compact() wrap() 总结 目标 掌握ByteBuffer常用方法&#xff0c;分析ByteBuffer对象在切换读写模式的情况下基本属性的变…

allocate与allocateDirect的性能测试

allocate与allocateDirect的性能测试 测试工具JMH测试代码JMH结果结论 测试工具JMH java基准测试框架 测试代码 直接分配系统内存(allocateDirect) -测试申请内存性能JVM堆分配内存(allocate)-测试申请内存性能直接内存-操作-连续二十次添加(allocateDirect)-测试内存操作性能…

ByteBuffer.allocate()与ByteBuffer.allocateDirect()方法的区别

在Java中当我们要对数据进行更底层的操作时&#xff0c;一般是操作数据的字节&#xff08;byte&#xff09;形式&#xff0c;这时经常会用到ByteBuffer这样一个类。ByteBuffer提供了两种静态实例方式&#xff1a; public static ByteBuffer allocate(int capacity) public s…