零基础学习java------day27-28---------电影评分数据案例,. RPC案例
一. 电影评分数据案例
movie:电影id
rate:用户评分
timeStamp:评分时间
uid:用户id
简化数据:
需求:
(1)每个用户评分最高的3部电影
(2)每个用户评分的平均值
(3)最大方(评分平均值高)的N个用户
(4)最热门的N部电影(评论次数)
(5)评价最高的N部电影
代码(此处只写了1-3题,剩下的类似的写)
工具类
public class LoadDataUtils { /**
* 以用户id分组
*/
public static Map<String, List<Movie>> getUidMap(){
Map<String, List<Movie>> uidMap = new HashMap<>();
// 获取缓冲字符流
try (
BufferedReader br = new BufferedReader(new FileReader("E:/javafile/movie.txt"));
){
String line = null;
while((line = br.readLine()) != null) {
// 获取movie对象
Movie m = JSON.parseObject(line, Movie.class);
String uid = m.getUid();
List<Movie> list = uidMap.getOrDefault(uid, new ArrayList<Movie>());
list.add(m);
//将数据封装进uidMap
uidMap.put(uid,list);
}
} catch (Exception e) {
e.printStackTrace();
}
return uidMap;
}
/**
* 以movie分组
* @return
*/
public static Map<String, List<Movie>> getMovieMap(){
Map<String, List<Movie>> movieMap = new HashMap<>();
// 获取缓冲字符流
try (
BufferedReader br = new BufferedReader(new FileReader("E:/javafile/movie.txt"));
){
String line = null;
while((line = br.readLine()) != null) {
Movie m = JSON.parseObject(line, Movie.class);
String mid = m.getMovie();
List<Movie> list = movieMap.getOrDefault(mid, new ArrayList<Movie>());
list.add(m);
movieMap.put(mid,list);
}
} catch (Exception e) {
e.printStackTrace();
}
return movieMap;
}
}
实现类
public class MovieTest1 {
public static void main(String[] args) {
// movieTop3OfEveryone();
// avrgOfEveryone();
userRateTop3();
} // 每个用户评分最高的3部电影
public static void movieTop3OfEveryone() {
Map<String, List<Movie>> uidMap = LoadDataUtils.getUidMap();
System.out.println(uidMap);
Set<Entry<String, List<Movie>>> entrySet = uidMap.entrySet();
for (Entry<String, List<Movie>> entry : entrySet) {
List<Movie> list = entry.getValue();
if(list !=null && list.size() >= 3) {
Collections.sort(list, new Comparator<Movie>() {
@Override
public int compare(Movie o1, Movie o2) {
return (o1.getRate()>o2.getRate())?-1:1;
}
});
for (int i=0;i<3; i++) {
Movie m = list.get(i);
System.out.println(entry.getKey()+":"+m);
}
}
}
} // 每个用户评分的平均值
public static void avrgOfEveryone() {
Map<String, List<Movie>> uidMap = LoadDataUtils.getUidMap();
Set<Entry<String, List<Movie>>> entrySet = uidMap.entrySet();
for (Entry<String, List<Movie>> entry : entrySet) {
List<Movie> list = entry.getValue();
double total = 0;
for(Movie movie : list) {
total += movie.getRate();
}
double avrg = total/list.size();
System.out.println(entry.getKey()+"电影评分的平均分为:"+avrg);
}
} // 最大方(评分平均值高)的N个用户
public static void userRateTop3() {
Map<String, List<Movie>> uidMap = LoadDataUtils.getUidMap();
HashMap<String, Double> map = new HashMap<>();
Set<Entry<String, List<Movie>>> entrySet = uidMap.entrySet();
for (Entry<String, List<Movie>> entry : entrySet) {
List<Movie> list = entry.getValue();
double total = 0;
for(Movie movie : list) {
total += movie.getRate();
}
double avrg = total/list.size();
map.put(entry.getKey(), avrg);
}
Set<Entry<String, Double>> entrySet1 = map.entrySet();
ArrayList<Entry<String, Double>> list = new ArrayList<>(entrySet1);
Collections.sort(list, new Comparator<Entry<String, Double>>() {
@Override
public int compare(Entry<String, Double> o1, Entry<String, Double> o2) {
return o1.getValue()>o2.getValue()?-1:1;
}
});
for(int i = 0;i<3;i++) {
System.out.println(list.get(i));
}
}
}
二. RPC案例
RPC(Remote Procedure Call)-远程过程调用,它是一种通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。RPC协议假定某些传输协议的存在,如TCP或UDP,为通信程序之间携带信息数据。在OSI网络通信模型中,RPC跨越了传输层和应用层。RPC使得开发包括网络分布式多程序在内的应用程序更加容易。RPC采用客户机/服务器模式。请求程序就是一个客户机,而服务提供程序就是一个服务器。首先,,客户机调用进程发送一个有进程参数的调用信息到服务进程,然后等待应答信息。在服务器端,进程保持睡眠状态直到调用信息到达为止。当一个调用信息到达,服务器获得进程参数,计算结果,发送答复信息,然后等待下一个调用信息,最后,客户端调用进程接收答复信息,获得进程结果
案例:
客户端远程请求注册,登录服务端,服务端响应客户端登录和注册是否成功(获取信息分为从数据库中获取和从本地磁盘中获取)
大致思路图:
流程:客户端请求(即发送request请求对象)服务端(登录或者注册),请求中包含的信息为请求所要调用的方法,方法参数列表(形参),方法的全类名以及实参。客户端为了接受这个请求(request对象),其要在服务端创建一个一样的request去接收客户端请求中的参数(注意;全类名也要一样)。接着使用反射的方法调用该请求中的方法(此处不用new的形式来创建对象并调用方法,若业务区有多个方法,就需要new很多对象,消耗性能)。方法中包含了与数据库或是磁盘文件的交互,一般与数据库的交互是通过dao,所以业务区通过dao层与数据库或是磁盘文件交互。最终响应由dao层返回业务区,再返回给server端,最终客户端读取服务端的响应,即可拿到响应数据(登录或是注册是否成功)。
代码:
客户端:
项目构造:
MyClient代码:
public class MyServer {
@SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
System.out.println("开始服务");
ServerSocket serverSocket = new ServerSocket(7788);
while(true) {
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(inputStream);
System.out.println("开始读取数据");
// 获取调用方法必须的参数
Request request = (Request)ois.readObject();
System.out.println("数据读取完毕");
String className = request.getClassName();
String methodName = request.getMethodName();
Class<?>[] parameterTypes = request.getParameterTypes();
Object[] paraterValues = request.getParaterValues();
// 反射调用方法,并接收返回数据
Class<?> clazz = Class.forName(className);
Method method = clazz.getMethod(methodName, parameterTypes);
Response response = (Response)method.invoke(clazz.newInstance(), (User)paraterValues[0]);
System.out.println("接收数据完毕"); // 向客户端发送响应
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(response);
System.out.println(response);
oos.close();
ois.close();
socket.close();
}
}
}
POJO(简单java对象,一般是由私有属性以及相应的设置或者获取这些属性的方法构成)部分代码:
request
public class Request implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String className;
private String methodName;
private Class<?>[] parameterTypes;
private Object[] paraterValues;
public String getClassName() {
return className;
}
public void setClassName(String className) {
this.className = className;
}
public String getMethodName() {
return methodName;
}
public void setMethodName(String methodName) {
this.methodName = methodName;
}
public Class[] getParameterTypes() {
return parameterTypes;
}
public void setParameterTypes(Class[] parameterTypes) {
this.parameterTypes = parameterTypes;
}
public Object[] getParaterValues() {
return paraterValues;
}
public void setParaterValues(Object[] paraterValues) {
this.paraterValues = paraterValues;
}
@Override
public String toString() {
return "Request [className=" + className + ", methodName=" + methodName + ", parameterTypes="
+ Arrays.toString(parameterTypes) + ", paraterValues=" + Arrays.toString(paraterValues) + "]";
}
}
response:
public class Response implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
private String msg;
private String statusCode;
private User user;
public String getMsg() {
return msg;
}
public void setMsg(String msg) {
this.msg = msg;
}
public String getStatusCode() {
return statusCode;
}
public void setStatusCode(String statusCode) {
this.statusCode = statusCode;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
@Override
public String toString() {
return "Response [msg=" + msg + ", statusCode=" + statusCode + ", user=" + user + "]";
}
}
User:
public class User implements Serializable{
/**
*
*/
private static final long serialVersionUID = 1L;
String name;
int age;
String password; public User() { } public User(String name, int age, String password) {
super();
this.name = name;
this.age = age;
this.password = password;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
} @Override
public String toString() {
return "User [name=" + name + ", age=" + age + ", password=" + password + "]";
}
服务端(server):
Myserver
public class MyServer {
@SuppressWarnings("resource")
public static void main(String[] args) throws Exception {
System.out.println("开始服务");
ServerSocket serverSocket = new ServerSocket(7788);
while(true) {
Socket socket = serverSocket.accept();
InputStream inputStream = socket.getInputStream();
ObjectInputStream ois = new ObjectInputStream(inputStream);
System.out.println("开始读取数据");
// 获取调用方法必须的参数
Request request = (Request)ois.readObject();
System.out.println("数据读取完毕");
String className = request.getClassName();
String methodName = request.getMethodName();
Class<?>[] parameterTypes = request.getParameterTypes();
Object[] paraterValues = request.getParaterValues();
// 反射调用方法,并接收返回数据
Class<?> clazz = Class.forName(className);
Method method = clazz.getMethod(methodName, parameterTypes);
Response response = (Response)method.invoke(clazz.newInstance(), (User)paraterValues[0]);
System.out.println("接收数据完毕"); // 向客户端发送响应
ObjectOutputStream oos = new ObjectOutputStream(socket.getOutputStream());
oos.writeObject(response);
System.out.println(response);
oos.close();
ois.close();
socket.close();
}
}
}
业务区(service)
UserServer(接口)
public interface UserServer { /**
* 用于用户登录
* @param user
* @return
* @throws Exception
*/ public Response login(User user) throws Exception; /**
* 用于用户的注册
* @param user
* @return
* @throws Exception
*/
public Response register(User user) throws Exception;
}
UserServerImpl(实现注册和登录)
public class UserServerImpl implements UserServer{
// 使用静态代码块加载配置文件
static String className;
static UserDao userDao;
static {
try {
Properties p = new Properties();
p.load(UserServerImpl.class.getClassLoader().getResourceAsStream("class.properties"));
className = p.getProperty("className");
userDao = (UserDao)Class.forName(className).newInstance();
} catch (Exception e) {
e.printStackTrace();
}
}
// 为了提高代码的扩展性,使用配置文件并使用反射获取实例对象
// 实现登录
@Override
public Response login(User user) throws Exception {
System.out.println(user);
User user1 = userDao.getUserFromDbByNameAndPwd(user);
Response response = new Response();
System.out.println(user1);
// 登录失败
if(user1==null) {
response.setMsg("登录失败");
response.setStatusCode("500");
response.setUser(null);
}else {
response.setMsg("登录成功");
response.setStatusCode("200");
response.setUser(user1);
}
return response;
} // 实现注册
@Override
public Response register(User user) throws Exception {
Response response = new Response();
boolean b = userDao.insertMessageOfUser(user);
if(b){
response.setMsg("注册成功");
response.setStatusCode("200");
}else{
response.setMsg("注册失败");
response.setStatusCode("500");
}
return response;
} }
dao
UserDao(接口)
public interface UserDao { /**
* 根据用户名和密码从数据库中查询用户
* @param name
* @param password
* @return
*/
public User getUserFromDbByNameAndPwd(User user) throws Exception; /**
* 往数据库插入数据
* @param user
* @return
*/
public boolean insertMessageOfUser(User user) throws Exception;
}
UserDaoImpl1(与磁盘文件交互)
/**
* 操作文件
* @author ASUS
*
*/
public class UserDaoImpl1 implements UserDao{
@Override
public User getUserFromDbByNameAndPwd(User u) throws Exception {
Map<String, User> map = TestMyUtil.getUserFromFile();
User user = null;
if(map != null) {
user = map.get(u.getName());
if(user !=null) {
String pwd = user.getPassword();
if(u.getPassword().equals(pwd)) {
return user;
}
}
}
return user;
} @SuppressWarnings("unchecked")
@Override
public boolean insertMessageOfUser(User user) throws Exception {
Map<String, User> map =null ;
File f = new File(Const.PATH);
boolean result = false;
if(!f.exists()) { //文件不存在,直接存map
map = new HashMap<>();
map.put(user.getName(), user);
FileUtil.addObjectToFile(map, Const.PATH);
result = true; // 文件已经存在,则先取出文件中的map对象,再存入相应的数据
}else {
// 取出map
map = (Map<String, User>) FileUtil.getObjectFromFile(Const.PATH);
boolean b = map.containsKey(user.getName());
if(!b) {
// 将数据存入已存在的map中,并将之写入文件
map.put(user.getName(), user);
FileUtil.addObjectToFile(map, Const.PATH);
result = true;
}
}
return result;
}
}
UserDaoImpl2
/**
* 操作数据库
* @author ASUS
*
*/
public class UserDaoImpl2 implements UserDao{
static ComboPooledDataSource dataSource;
static QueryRunner runner;
static {
// 获取连接池对象,其中包含连接数据库所需要的参数
dataSource = new ComboPooledDataSource();
// 连接数据库
runner = new QueryRunner(dataSource);
}
// 查询数据
@Override
public User getUserFromDbByNameAndPwd(User u) throws Exception { String sql = "select * from user where name=?and password=?";
User user = runner.query(sql, new BeanHandler<>(User.class),u.getName(),u.getPassword());
return user;
} // 插入数据
@Override
public boolean insertMessageOfUser(User u) throws Exception {
String sql = "insert into user values(?,?,?)";
int i = runner.update(sql,u.getName(),u.getAge(),u.getPassword());
if(i>0) {
return true;
}
return false;
} }
工具类(utils)
Const(保证操作的路径一致)
/**
* 指定路径
* @author ASUS
*
*/
public class Const {
public static final String PATH = "E:/javafile/object.txt"; }
FileUtil
/**
* 1 读取指定文件 获取对象
* 2 向指定文件中存储对象
* @author ASUS
*
*/
public class FileUtil { /**
* 读取指定文件 获取对象
* @param path
* @return
* @throws Exception
*/
public static Object getObjectFromFile(String path) throws Exception {
File f = new File(path);
Object obj = null ;
if(f.exists()){
ObjectInputStream ois = new ObjectInputStream(new FileInputStream(f));
obj = ois.readObject();
ois.close();
}
return obj;
} /**
* 向指定文件中存储对象
* @param obj
* @param path
* @throws Exception
*/
public static void addObjectToFile(Object obj , String path) throws Exception{
File f = new File(path);
ObjectOutputStream oos = new ObjectOutputStream(new FileOutputStream(f));
oos.writeObject(obj);
oos.close();
}
}
零基础学习java------day27-28---------电影评分数据案例,. RPC案例的更多相关文章
- 音乐出身的妹纸,零基础学习JAVA靠谱么
问:表示音乐出身的妹纸一枚 某一天突然觉得身边认识的是一群程序员 突然想 要不要也去试试... 众好友都觉得我该去做个老师,可是我怕我会误人子弟,祸害祖国下一代..... 要不要 要不要 学Ja ...
- 总结了零基础学习Java编程语言的几个基础知识要点
很多Java编程初学者在刚接触Java语言程序的时候,不知道该学习掌握哪些必要的基础知识.本文总结了零基础学习Java编程语言的几个基础知识要点. 1先了解什么是Java的四个方面 初学者先弄清这 ...
- 【零基础学习iOS开发】【转载】
原文地址:http://www.cnblogs.com/mjios/archive/2013/04/24/3039357.html 本文目录 一.什么是iOS 二.主流手机操作系统 三.什么是iOS开 ...
- 李洪强iOS开发之【零基础学习iOS开发】【01-前言】01-开篇
从今天开始,我就开始更新[零基础学习iOS开发]这个专题.不管你是否涉足过IT领域,也不管你是理科生还是文科生,只要你对iOS开发感兴趣,都可以来阅读此专题.我尽量以通俗易懂的语言,让每个人都能够看懂 ...
- 【零基础学习iOS开发】【01-前言】01-开篇
本文目录 一.什么是iOS 二.主流手机操作系统 三.什么是iOS开发 四.学习iOS开发的目的 五.学习iOS开发的前提 从今天开始,我就开始更新[零基础学习iOS开发]这个专题.不管你是否涉足过I ...
- 零基础学Java,PayPal技术专家手把手带你入门
在最权威的 TIOBE 编程语言排名榜单上,Java 常年稳居第一,可以说是世界上应用最为广泛的一门语言. 同时,在微服务.云计算.大数据.Android App 开发等领域,Java 也是当之无愧的 ...
- 零基础学Java第五节(面向对象一)
本篇文章是<零基础学Java>专栏的第五篇文章,文章采用通俗易懂的文字.图示及代码实战,从零基础开始带大家走上高薪之路! 本文章首发于公众号[编程攻略] 类与对象 在哲学体系中,可以分为主 ...
- 零基础学习hadoop到上手工作线路指导
零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易.在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结.所以索性就自己学习了.整个过程整理一下,给大家参考,欢迎讨论,共同学习. ...
- salesforce 零基础学习(六十八)http callout test class写法
此篇可以参考: https://developer.salesforce.com/docs/atlas.en-us.apexcode.meta/apexcode/apex_classes_restfu ...
- 零基础学习Hadoop
零基础学习hadoop,没有想象的那么困难,也没有想象的那么容易.在刚接触云计算,曾经想过培训,但是培训机构的选择就让我很纠结.所以索性就自己学习了.整个过程整理一下,给大家参考,欢迎讨论,共同学习. ...
随机推荐
- Ubuntu mysql安装与使用
Ubuntu 下安装 mysql 运行下面的shell代码 #安装mysql sudo apt-get -y install mysql-server sudo apt-get -y install ...
- 一文读懂什么是渲染管线(7k字)
01 | 渲染基础 渲染(Render)定义 渲染在电脑绘图中是指软件从模型生成图像的过程,通俗讲就是在计算机里面给虚拟世界"拍照".渲染主要分为两种,一种是预渲染(pre-ren ...
- IDEA插件和个性化配置推荐
插件推荐 我自己现在使用的一些插件和一些自己感觉比较舒服配置分析给大家 idea如何安装插件: 如果打开设置没有看到,直接搜索plugins 然后在这里搜索即可 CodeGlance 小地图 和vsc ...
- axios 基于拦截器的取消(重复)请求
axios 基于拦截器的取消(重复)请求 // 添加请求拦截器 axios.interceptors.request.use((config) => { // 准备发请求之前, 取消未完成的请求 ...
- node 中第三方模块的加载过程原理
node 中第三方模块的加载过程原理 凡是第三方模块都必须通过 npm 来下载 使用的时候就可以通过require('包名') 的方式来进行加载才可以使用 不可能有任何一个第三方包和核心模块的名字是一 ...
- .NET Protobuf包装器库
Wodsoft Protobuf Wrapper 内容 关于 需求 安装 用法 序列化 反序列化 字段定义 字段排序 非空构造函数对象 获取Protobuf包装器 高级 支持的属性类型与Protobu ...
- R数据分析:生存分析与有竞争事件的生存分析的做法和解释
今天被粉丝发的文章给难住了,又偷偷去学习了一下竞争风险模型,想起之前写的关于竞争风险模型的做法,真的都是皮毛哟,大家见笑了.想着就顺便把所有的生存分析的知识和R语言的做法和论文报告方法都给大家梳理一遍 ...
- 时间处理,类似"xxxx-xx-xxTxx:xx:xx187+0000"格式
后端返回的时间:"2020-04-24T09:12:51.187+0000" 目标显示时间:2020-04-24 09:12:51 <!DOCTYPE html> ...
- [atAGC054C]Roughly Sorted
考虑对于确定的排列$\{p_{i}\}$,如何求出其(交换后)会得到的排列-- 令$cnt_{x}$为在$i$之前比$x$大的元素个数(其中$p_{i}=x$),显然排列合法当且仅当$cnt_{i}\ ...
- [bzoj5416]冒泡排序
结论:一个序列是好序列当且仅当其不存在长度为3的下降子序列 证明:考虑提示,一个长度为3的下降子序列必然会交换三次, 而这三次带来的收益实际上只有2,因此不合法 同时还可以得到:第i个数,要么是前缀最 ...