mapreduce實現bean的序列化與反序列化

目錄

序列化(Serialization)

反序列化(Deserialization)

事例操作?

UserSale

??重寫序列化方法

重寫反序列化

?重寫toString方法

SaleMapper

SaleReducer

SaleDriver


序列化(Serialization)

????????序列化是將Java對象轉換成字節流的過程,使得對象可以被存儲到磁盤上或通過網絡進行傳輸。在Hadoop中,這個過程特別關鍵,因為數據經常需要在網絡間傳遞(例如,從Map任務到Reduce任務),或者存儲到HDFS上。Hadoop自定義了一套序列化機制——Writable接口,任何需要進行序列化的類都必須實現這個接口。實現Writable接口的類需要重寫兩個方法:write(DataOutput out)readFields(DataInput in)。前者負責將對象的狀態(即成員變量的值)寫入到DataOutput流中;后者則從DataInput流中讀取字節并恢復對象狀態。

反序列化(Deserialization)

????????反序列化則是序列化的逆過程,即將字節流轉換回Java對象。在Hadoop中,當數據從網絡接收或從HDFS讀取后,需要通過反序列化恢復成原始的Java對象,以便程序能夠進一步處理這些數據。利用前面提到的readFields(DataInput in)方法,Hadoop可以從輸入流中重建對象實例。

?Hadoop選擇了自定義Writable接口,主要出于以下考慮:

  1. 性能:Hadoop的Writable接口設計得更加輕量級和高效,特別適合大規模數據處理,減少序列化和反序列化過程中的開銷。
  2. 緊湊性:Writable接口能夠生成更緊湊的二進制格式,節省存儲空間和網絡帶寬。
  3. 可移植性:Hadoop集群可能包含不同版本的Java或運行在不同的操作系統上,自定義序列化機制保證了跨平臺的一致性。

事例操作?

使用自定義對象,實現對用戶購買商品總額的計算

入口文件示例

UserSale

實現Hadoop的Writable接口

public class UserSale implements Writable {
//銷售idprivate int saleId;//用戶名稱private String username;//用戶性別private String sex;//商品名稱private String goodsName;//商品單價private  int price;//購買數量private  int saleCount;//購買總價private  int totalPrice;

?記得得有空參構造

public UserSale() {}
??重寫序列化方法
 //重寫序列化方法@Overridepublic void write(DataOutput out) throws IOException {out.writeInt(saleId);out.writeUTF(username);out.writeUTF(sex);out.writeUTF(goodsName);out.writeInt(price);out.writeInt(saleCount);out.writeInt(totalPrice);}
重寫反序列化

順序和序列化的順序一樣

   @Overridepublic void readFields(DataInput in) throws IOException {this.saleId = in.readInt();this.username = in.readUTF();this.sex = in.readUTF();this.goodsName = in.readUTF();this.price = in.readInt();this.saleCount = in.readInt();this.totalPrice = in.readInt();}
?重寫toString方法
reduce階段的輸出的格式
//重寫toString方法//最終輸出到文件的value@Overridepublic String toString() {return " " + totalPrice;}

?get,set方法,以及定義totalPrice的構造方法

    public void setTotalPrice(int totalPrice) {this.totalPrice = totalPrice;}public void setTotalPrice(){this.totalPrice = this.price*this.saleCount;}

SaleMapper

package com.igeekhome.mapreduce.sale;import com.igeekhome.mapreduce.model.UserSale;
import org.apache.hadoop.io.LongWritable;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Mapper;import java.io.IOException;public class SaleMapper extends Mapper<LongWritable, Text, Text, UserSale>{//創建輸出key對象private Text keyOut = new Text();//創建輸出valueUserSale valueOut = new UserSale();@Overrideprotected void map(LongWritable key, Text value, Mapper<LongWritable, Text, Text, UserSale>.Context context) throws IOException, InterruptedException {//獲取一行數據String line = value.toString();//根據分隔符拆解數據String[] saleDetails = line.split(",");//封裝對象valueOut.setSaleId(Integer.parseInt(saleDetails[0]));valueOut.setUsername(saleDetails[1]);valueOut.setSex(saleDetails[2]);valueOut.setGoodsName(saleDetails[3]);valueOut.setPrice(Integer.parseInt(saleDetails[4]));valueOut.setSaleCount(Integer.parseInt(saleDetails[5]));//賦值keyOut.set(valueOut.getUsername());//計算總價valueOut.setTotalPrice();System.out.println(keyOut+"+"+valueOut);//map階段的輸出context.write(keyOut,valueOut);}
}

?其中

Mapper<LongWritable, Text, Text, UserSale>

分別表示

LongWritable:map階段輸入的key類型,一行文本的偏移量

Text:map階段輸入的value類型,表示一行文本中的內容

Text: map階段輸出的key類型 ,表示一個單詞

UserSale?:map階段輸出的value類型,這里是UserSale對象

SaleReducer

新建reduce階段輸出的alue

reduce()方法的調用次數 是由kv鍵值對中有多少不同的key決定的

比如此時小明的兩條數據進入Reducer,for循環執行的是這兩條數據里的總價相加

package com.igeekhome.mapreduce.sale;import com.igeekhome.mapreduce.model.UserSale;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Reducer;import java.io.IOException;public class SaleReducer extends Reducer<Text, UserSale,Text, UserSale> {//新建reduce階段輸出的alue//reduce()方法的調用次數 是由kv鍵值對中有多少不同的key決定的private UserSale valueOut = new UserSale();@Overrideprotected void reduce(Text key, Iterable<UserSale> values, Reducer<Text, UserSale, Text, UserSale>.Context context) throws IOException, InterruptedException {//定義一個用戶的訂單int sumTotalPrice = 0;for (UserSale userSale : values) {//獲取一個訂單中的總價int totalPrice = userSale.getTotalPrice();valueOut.setSex(userSale.getSex());//進行累加sumTotalPrice +=totalPrice;}//設置在結果文件終端輸出valueOut.setTotalPrice(sumTotalPrice);System.out.println("reduce" +valueOut);//reduce階段的輸出context.write(key,valueOut);}
}

Reducer<Text, UserSale,Text, UserSale>

Text:reduce階段的輸入key類型, 即map階段輸出key類型,表示用戶名

UserSale:reduce階段的輸入value類型,即map階段輸出value類型,表示用戶對象

Text:reduce階段的輸出key類型,表示用戶名

UserSale:reduce階段的輸出value類型,表示用戶對象,實際上輸出的是totalPrice(因為toString方法的重寫)

SaleDriver

package com.igeekhome.mapreduce.sale;import com.igeekhome.mapreduce.model.UserSale;
import org.apache.hadoop.conf.Configuration;
import org.apache.hadoop.fs.Path;
import org.apache.hadoop.io.Text;
import org.apache.hadoop.mapreduce.Job;
import org.apache.hadoop.mapreduce.lib.input.FileInputFormat;
import org.apache.hadoop.mapreduce.lib.output.FileOutputFormat;import java.io.IOException;public class SaleDriver {public static void main(String[] args) throws IOException, InterruptedException, ClassNotFoundException {//1.獲取配置對象和job對象Configuration conf = new Configuration();Job job = Job.getInstance(conf);//2.設置Driver類對象job.setJarByClass(SaleDriver.class);//3.設置mapper和reducer類對象job.setMapperClass(SaleMapper.class);job.setReducerClass(SaleReducer.class);//4.設置map階段輸出的kv對象job.setMapOutputKeyClass(Text.class);job.setMapOutputValueClass(UserSale.class);//5.設置最終輸出的kv類對象job.setOutputKeyClass(Text.class);job.setOutputValueClass(UserSale.class);//6.設置讀取文件的路徑 和 輸出文件的路徑FileInputFormat.setInputPaths(job,new Path("D:\\code\\sale_details (1).txt"));FileOutputFormat.setOutputPath(job,new Path("D:\\code\\output"));//7.提交jobboolean result = job.waitForCompletion(true);System.out.println(result?"計算成功":"計算失敗");}}

之后的分區操作mapreduce分區icon-default.png?t=N7T8https://blog.csdn.net/m0_74934794/article/details/139991018?csdn_share_tail=%7B%22type%22%3A%22blog%22%2C%22rType%22%3A%22article%22%2C%22rId%22%3A%22139991018%22%2C%22source%22%3A%22m0_74934794%22%7D

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/39657.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/39657.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/39657.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

【后端面試題】【中間件】【NoSQL】MongoDB的配置服務器、復制機制、寫入語義和面試準備

MongoDB的配置服務器 引入了分片機制之后&#xff0c;MongoDB啟用了配置服務器(config server) 來存儲元數據&#xff0c;這些元數據包括分片信息、權限控制信息&#xff0c;用來控制分布式鎖。其中分片信息還會被負責執行查詢mongos使用。 MongoDB的配置服務器有一個很大的優…

WPF----自定義滾動條ScrollViewer

滾動條是項目當中經常用到的一個控件&#xff0c;大部分對外項目都有外觀的需求&#xff0c;因此需要自定義&#xff0c;文中主要是針對一段動態的狀態數據進行展示&#xff0c;并保證數據始終在最新一條&#xff0c;就是需要滾動條滾動到底部。 1&#xff0c;xaml中引入 <…

zxing-cpp+OpenCV根據字符串生成條形碼

編譯構建 需要使用到 CMake、Git、GCC 或 MSVC。 github 鏈接&#xff1a;https://github.com/zxing-cpp/zxing-cpp 編譯之前請確保&#xff1a; 確保安裝了 CMake 版本 3.15 或更高版本。 確保安裝了與 C17 兼容的編譯器(最低VS 2019 16.8 / gcc 7 / clang 5)。 編譯構建…

Python面試寶典第4題:環形鏈表

題目 給你一個鏈表的頭節點 head &#xff0c;判斷鏈表中是否有環。如果存在環 &#xff0c;則返回 true 。 否則&#xff0c;返回 false 。 如果鏈表中有某個節點&#xff0c;可以通過連續跟蹤 next 指針再次到達&#xff0c;則鏈表中存在環。 為了表示給定鏈表中的環&#xf…

重寫父類方法、創建單例對象 題目

題目 JAVA27 重寫父類方法分析&#xff1a;代碼&#xff1a; JAVA28 創建單例對象分析&#xff1a;代碼&#xff1a; JAVA27 重寫父類方法 描述 父類Base中定義了若干get方法&#xff0c;以及一個sum方法&#xff0c;sum方法是對一組數字的求和。請在子類 Sub 中重寫 getX() 方…

AI智能體|AI打工我躺平!使用扣子Coze智能體自動生成和發布文章到微信公眾號(一)

大家好&#xff0c;我是無界生長&#xff0c;國內最大AI付費社群“AI破局俱樂部”初創合伙人。這是我的第 44 篇原創文章——《AI智能體&#xff5c;AI打工我躺平&#xff01;使用扣子Coze智能體自動生成和發布文章到微信公眾號&#xff08;一&#xff09;》 AI智能體&#xf…

《涅朵奇卡:一個女人的一生》讀后感

這周的計劃是看完海明威的《喪鐘為誰而鳴》&#xff0c;但是因為下班晚&#xff0c;而且書的體量大&#xff0c;所以只看了一半。本來以為這周的閱讀計劃完不成了&#xff0c;不料昨天加完班后拿起新到的《涅朵奇卡&#xff1a;一個女人的一生》&#xff0c;不自覺就陷進去了&a…

端口聚合基礎知識

一、什么是端口聚合 端口聚合是將多個物理端口捆綁在一起&#xff0c;形成一個邏輯鏈路&#xff0c;以實現帶寬增加、提高冗余和負載均衡的技術。端口聚合&#xff0c;也稱為以太通道&#xff08;Ethernet Channel&#xff09;&#xff0c;主要用于交換機之間的連接。在具有多…

開發數字藥店APP實戰:互聯網醫院系統源碼詳解

本篇文章&#xff0c;筆者將深入探討如何開發一個功能完善的數字藥店APP&#xff0c;并詳細解析互聯網醫院系統的源碼實現。 一、數字藥店APP的需求分析 應具備以下基本功能&#xff1a; 用戶注冊與登錄 藥品搜索與瀏覽 在線下單與支付 訂單管理 健康咨詢與遠程醫療 個人…

partition()方法——分割字符串為元組

自學python如何成為大佬(目錄):https://blog.csdn.net/weixin_67859959/article/details/139049996?spm1001.2014.3001.5501 語法參考 partition()方法根據指定的分隔符將字符串進行分割。如果字符串中包含指定的分隔符&#xff0c;則返回一個3元的元組&#xff0c;第一個為…

Perl 語言開發(四):條件語句

目錄 1. 概述 2. if 語句 3. else 語句 4. elsif 語句 5. unless 語句 6. 嵌套條件語句 7. 三元運算符 8. 智能匹配運算符 9. given-when 語句 10. 條件修飾符 11. 高級條件語句應用 11.1 數據驗證 11.2 配置文件解析 11.3 異常處理 12. 條件語句的最佳實踐 12…

Spring Boot+Mybatis Plus 使用Redis實現二級緩存具體步驟以及代碼

下面是使用Spring BootMybatis Plus和Redis實現二級緩存的具體步驟和代碼示例&#xff1a; 1. 首先&#xff0c;確保你已經添加了Spring Boot、Mybatis Plus和Redis的依賴。 2. 在Spring Boot的配置文件中添加Redis的配置&#xff0c;如下所示&#xff1a; yaml spring: r…

wordpress:更新網站域名后后頁面無法訪問,頁面媒體文件異常(已解決)

WordPress 在數據庫中存儲了許多配置信息,包括網站的域名。如果更新了域名,但數據庫中的舊域名沒有更新,WordPress 將無法正確生成頁面鏈接或重定向訪問請求。 一、更新域名 在wp-config.php 文件中,添加或更新你的新域名! define(WP_HOME, http://172.18.214.195:32520…

Linux_fileio學習

參考韋東山老師教程&#xff1a;https://www.bilibili.com/video/BV1kk4y117Tu?p12 目錄 1. 文件IO函數分類2. 函數原型2.1 系統調用接口2.2 標準IO接口 3. fileio內部機制3.1 系統調用接口內部流程3.1 dup函數使用3.2 dup2函數使用 4. open file4.1 open實例4.2 open函數分析…

Cocos如何跟Android通信?

點擊上方億元程序員+關注和★星標 引言 Cocos如何跟Android通信 大家好,相信小伙伴們通過閱讀筆者前幾期的文章**《Cocos打安卓包打不出來?看看這個》,對Cocos**如何打安卓包有了一定的了解。 但是,除了把安卓包打出來,另外還有一個重要的就是要能夠調用安卓提供的Java方…

華為HCIP Datacom H12-821 卷21

1.單選題 以下關于PIM-SM中SPT切換的描述,錯誤的是哪一項? A、若所有組播流量都經過RP路由器,則RP路由器可能成為數據轉發的瓶頸 B、SPT路徑最短,轉發性能更優 C、SPT 切換完成后,組播流量依然經過 ReT 樹 D、RPT 樹可能不是組播流量轉發的最優路徑 正確答案: C 解析…

【AI原理解析】—K近鄰(KNN)原理

目錄 一、算法概述 二、算法原理 1. 數據集準備 2. 輸入新數據 3. 距離計算 4. 選擇K個最近鄰 5. 預測 三、關鍵要素 1. K值的選擇 2. 距離度量方法 3. 數據預處理 四、算法優缺點 優點 缺點 五、總結 KNN&#xff08;K-Nearest Neighbors&#xff0c;K最近鄰&a…

[教程]Gitee保姆級圖文使用教程

我們在日常的工作過程中經常會遇到&#xff0c;家里和公司資料文件同步的問題&#xff0c;以及項目開發過程中的協作問題。Git就完美的解決了這些問題&#xff0c;但是由于 Git國外服務器的原因平時網絡太慢了&#xff0c;不過還好有國內的托管平臺Gitee&#xff08;碼云&#…

「C++系列」C++ 變量類型

文章目錄 一、C 變量類型1. 基本數據類型2. 復合數據類型3. 類型修飾符 二、C 變量定義案例 1: 基本類型變量的定義和初始化案例 2: 數組的定義和使用案例 3: 結構體&#xff08;Struct&#xff09;的定義和使用案例 4: 指針的定義和使用案例 5: 類的定義和使用&#xff08;面向…

五、removeClosedPointCloud

五、removeClosedPointCloud 主要功能: removeClosedPointCloud 函數用于過濾掉點云中距離傳感器(例如激光雷達)太近的點。這些點可能會引入噪聲或不利于后續的點云處理和分析。函數通過比較每個點與傳感器之間的距離,移除那些距離小于設定閾值 minimumRange 的點。 計算…