java 数据分析 用户信息_零基础学习java------22----------社交用户分析案例,反射(概念,获取配置文件的3种方式),手机号段上网日志流量统计...

这篇博客通过Java实现社交用户关系分析,包括获取好友数量、共同好友的算法,并探讨了反射的概念和获取配置文件的三种方式。此外,还展示了如何分析HTTP日志以计算用户上网流量最高的网站和省份Top3。
摘要由CSDN通过智能技术生成

1. 社交用户关系数据分析案例

数据样例:

7eea9ea6667ab5ad6746b41e9e2f71d6.png

需求:

1. 获取每个人的好友个数,并按照好友数量排序

2. 获取任意两个人的共同好友

3.获取所有人两两共同好友

1.

public classSimpleFriendsDemo1 {public static voidmain(String[] args) {

HashMap map = new HashMap<>();try(//获取缓冲字符流,读取并切割数据

BufferedReader br = new BufferedReader(new FileReader("E:\\javafile\\simpleFriend.txt"));

){

String line= null;while((line = br.readLine())!= null) {

String[] split= line.split(":");

String uid= split[0];

String[] fsn= split[1].split(",");//以uid为key,好友数量为value存入map

map.put(uid,fsn.length);

}//获取每个人的好友数量

Set> entrySet =map.entrySet();for (Entryentry : entrySet) {

System.out.println(entry.getKey()+"好友的个数为"+entry.getValue());

}//安好友数量进行排序(降序)

ArrayList> list = new ArrayList<>(entrySet);

Collections.sort(list,(o1,o2)->o2.getValue()-o1.getValue());

System.out.println(list); //[F=7, A=6, E=5, G=5, H=5, B=4, C=4, D=4, O=4, K=3, L=3, M=3, I=2, J=2]

} catch(Exception e) {//TODO Auto-generated catch block

e.printStackTrace();

}

}

}

2.

错误代码:

public classSimpleFriendsDemo2 {public static voidmain(String[] args) {try(//获取缓冲字符流,读取并切割数据

BufferedReader br = new BufferedReader(new FileReader("E:\\javafile\\simpleFriend.txt"));

){

String line1=br.readLine();

String line2=br.readLine();

String uid1= line1.split(":")[0];

String[] fs1= line1.split(":")[1].split(",");

String uid2= line2.split(":")[0];

String[] fs2= line2.split(":")[1].split(",");

List list1 =Arrays.asList(fs1);

List list2 =Arrays.asList(fs2);

list1.retainAll(list2);

System.out.println(uid1+"和"+uid2+"的共同好友是:"+list1);

}catch(Exception e){

e.printStackTrace();

}

}

}

运行结果:

a7a6259f114f83142dd04875de6994fd.png

原因:由asList得到的集合是不能进行增删操作的,即数据不能更改,而retainAll方法对list1中的元素是进行了操作的,所以此处要创建一个新的集合将list1中的数据传进去,正确代码如下

public classSimpleFriendsDemo2 {public static voidmain(String[] args) {try(//获取缓冲字符流,读取并切割数据

BufferedReader br = new BufferedReader(new FileReader("E:\\javafile\\simpleFriend.txt"));

){

String line1=br.readLine();

String line2=br.readLine();

String uid1= line1.split(":")[0];

String[] fs1= line1.split(":")[1].split(",");

String uid2= line2.split(":")[0];

String[] fs2= line2.split(":")[1].split(",");

List list1 =Arrays.asList(fs1);

List list2 =Arrays.asList(fs2);

List list11 = new ArrayList<>(list1);

list11.retainAll(list2);if(list11 != null && list11.size()>0) {

System.out.println(uid1+"和"+uid2+"的共同好友是:"+list11); //A和B的共同好友是:[C, E]

}

}catch(Exception e){

e.printStackTrace();

}

}

}

方法封装形式的代码

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

/**

* 获取两个人的共同好友 数据 文件

* 获取 Map>

* 方法的封装 获取一个数据 传递 返回数据 void

* @author hang*/

public classTestDemo2 {

@SuppressWarnings("resource")public static voidmain(String[] args) {//Map> map = getUserFsInfo();

getSameFriends("A", "B");

}/**

* 获取任意两个人的共同好友

* @param uid1 好友1 id

* @param uid2 好友2 id

* @return 返回这两个人的好友列表数据*/

public static ListgetSameFriends(String uid1 , String uid2){//map 获取map

Map> map =getUserFsInfo();//分别获取两个人的好友列表信息

List list1 = map.get(uid1);

List list2 = map.get(uid2);//获取两个人的共同好友 将两个集合的共同数据存储在前面集合中

list1.retainAll(list2);//如果两个人的好友存在交集 返回

if(list1!=null && list1.size()>0){ //说明有数据 两个好友有交集

System.out.println(uid1 +"和" + uid2 +"的共同好友是"+list1);returnlist1;

}return null;

}/**

* 获取存储用户以及用户好友列表的map数据

* @return*/

private static Map>getUserFsInfo() {

Map> map = new HashMap<>();try (BufferedReader bfr = new BufferedReader(new FileReader("d:/data/好友.txt"));) {

String line= null;while ((line = bfr.readLine()) != null) {

String[] split= line.split(":");

String uid= split[0];

String fsstr= split[1];

String[] arr= fsstr.split(",");//将数组 长度 list长度固定 元素不允许修改

List list =Arrays.asList(arr);//创建新的list存储数据

ArrayList fsList = new ArrayList<>(list);//强每个人对应的好友列表存储在map集合中

map.put(uid, fsList);

}

}catch(Exception e) {//TODO Auto-generated catch block

e.printStackTrace();

}//调用方法返回 一个存储每个人和其对应的每个人的好友列表的map集合

returnmap;

}

}

View Code

3.

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classTestDemo3 {public static voidmain(String[] args) {//每个人所对应的好友列表

Map> map =getUserFsInfo();//获取所有的用户uid

List list =getAllUsers();//嵌套循环 获取前一个和后一个人的用户uid

for (int i = 0; i < list.size() - 1; i++) { //第一个遍历到倒数第二个

String uid1 = list.get(i);//A

List fs1 = map.get(uid1);for (int j = i + 1; j < list.size(); j++) { //从第二个遍历到最后同一个

String uid2 = list.get(j); //B c d e f

List fs2 = map.get(uid2);//由于 交集的方法会对源集合的数据发生改变 所以要创建新的集合

List fs = new ArrayList<>(fs2);//交集

fs.retainAll(fs1);if (fs != null && fs.size() > 0) {

System.out.println(uid1 + "和" + uid2 + "的好友是" +fs);

}

}

}//list遍历方式1

/** for (String string : list) { System.out.println(string); List

* fs = map.get(string); }*/}/**

* 获取所有的用户列表

*

* @return*/

private static ListgetAllUsers() {//创建list集合存储所欲的用户的uid

List list = new ArrayList<>();//读取数据 将 uid 放在list中

try (BufferedReader bfr = new BufferedReader(new FileReader("d:/data/好友.txt"));) {

String line= null;while ((line = bfr.readLine()) != null) {

String[] split= line.split(":");

String uid= split[0];//将所有的用户存储在list集合中

list.add(uid);

}

}catch(Exception e) {//TODO: handle exception

}returnlist;

}/**

* 获取存储用户以及用户好友列表的map数据

*

* @return*/

private static Map>getUserFsInfo() {

Map> map = new HashMap<>();try (BufferedReader bfr = new BufferedReader(new FileReader("d:/data/好友.txt"));) {

String line= null;while ((line = bfr.readLine()) != null) {

String[] split= line.split(":");

String uid= split[0];

String fsstr= split[1];

String[] arr= fsstr.split(",");//将数组 长度 list长度固定 元素不允许修改

List list =Arrays.asList(arr);//创建新的list存储数据

ArrayList fsList = new ArrayList<>(list);//强每个人对应的好友列表存储在map集合中

map.put(uid, fsList);

}

}catch(Exception e) {//TODO Auto-generated catch block

e.printStackTrace();

}//调用方法返回 一个存储每个人和其对应的每个人的好友列表的map集合

returnmap;

}

}

View Code

2. 反射(此处结合day20的内容一起看)

2.1 一些概念

反射是一种动态获取类信息的技术,可以根据类的全类型,类的字节码,class属性获取所有字节码的Class类,在java的高级编程和javaee框架中应用广泛

获取到字节码对象以后,可以获取类的任意内容,可以操作类中的任意方法、属性和构造方法等等

对于动态获取类信息的理解:此处的动态体现在使用字符串获取对象(全类名的形式),字符串可以从文件里读取,那么修改文件内容字符串会变化,跟着对象也就变化了

6ce683be38ee266f31f4e0c3b1160e18.png

Class类是一个解析.class文件的工具类,类似于IO类可以读取内容。Class类解析了字节码文件就能知道里面的所有内容了,就可以依此为基础创建对应字节码的java对象了

2.2 读取项目配置文件的三种方式

(1). 使用本项目的类获取类加载器

Properties p = newProperties();

p.load(ReadProperties.class.getClassLoader().getResourceAsStream("bean.properties"));

(2). 获取配置文件的输入流

Properties p = newProperties();

p.load(new FileInputStream(new File("conf/bean.properties")));

(3). 使用ResourceBundle类

ResourceBundle b = ResourceBundle.getBundle("bean");

String name= b.getString("className");

3. 日志流量案例

在给的http.log日志文件中,是电信运营商记录用户上网访问某些网站行为的日志记录数据,一条数据中有多个字段用空格分隔。例如:"18611132889 http://v.baidu.com/tv 20 5000"是一条上网行为,第一个字段代表手机号码,第二个字段代表请求网站的URL,第三个字段代表请求发送的数据即上行流量(20字节),第四个字段代表服务器响应给用户的流量即下行流量(5000字节)。

部分数据截图:

ef46ca8cd767fb2ece3e1f82009b4b01.png

需求:

(1)计算出用户上网流量总流量(上行+下行)最高的网站Top3

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classTest1 {

@SuppressWarnings("resource")public static voidmain(String[] args) throws Exception {//域名 key:站点 value:总流量

Map map = new HashMap<>();

BufferedReader br= new BufferedReader(new FileReader("d:/data/http.log"));

String line= null;while((line = br.readLine())!=null){//System.out.println(line);

String[] split = line.split("\\s");if(split.length>=4){

String url= split[1] ;

String[] split2= url.split("\\.");if(split2.length==3){

String phone= split[0] ;

String downData= split[2] ;

String upData= split[3] ;

String yuming= split2[1] ;

Integer sum= Integer.parseInt(upData)+Integer.parseInt(downData);//判断map中是否有相同的key值

/*1

* if(map.containsKey(yuming)){

sum += map.get(yuming);

map.put(yuming, sum) ;

}

map.put(yuming, sum) ;

*2 map.get("")返回value 根据value判断*/Integer res= map.getOrDefault(yuming, 0);

sum+=res ;

map.put(yuming, sum);

}

}

}//对map数据进行排序操作

br.close();

}

}

View Code

(2)根据个的手机号段归属地规则,计算出总流量最高的省份Top3

首先定义一个javabean用来存储各个字段

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classPhoneBean {privateString prefix;privateString phone;privateString province;privateString city;privateString isp;publicPhoneBean() {

}public void set(String prefix, String phone, String province, String city, String isp) {this.prefix =prefix;this.phone =phone;this.province =province;this.city =city;this.isp =isp;

}publicString getPrefix() {returnprefix;

}public voidsetPrefix(String prefix) {this.prefix =prefix;

}publicString getPhone() {returnphone;

}public voidsetPhone(String phone) {this.phone =phone;

}publicString getProvince() {returnprovince;

}public voidsetProvince(String province) {this.province =province;

}publicString getCity() {returncity;

}public voidsetCity(String city) {this.city =city;

}publicString getIsp() {returnisp;

}public voidsetIsp(String isp) {this.isp =isp;

}

}

View Code

定义工具类(PhoneUtils)用来将各个字段存入javabean中

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classPhoneUtils {

@SuppressWarnings("resource")public static voidmain(String[] args) throws Exception {

getPhoneList();

}/**

* 将数据号段数据封装在map中

* 以手机的前七位作为key

* 对应的一行数据的javaBean作为value

* @return

* @throws FileNotFoundException

* @throws IOException*/

private static MapgetPhoneMap() throws FileNotFoundException, IOException {

Map map = new HashMap<>() ;

BufferedReader br= new BufferedReader(new FileReader("d:/data/手机号段规则.txt"));

String line= null;

br.readLine();//去除头信息

while ((line = br.readLine()) != null) {

System.out.println(line);

String[] split= line.split("\\s");

String prefix= split[0];

String phone= split[1];

String province= split[2];

String city= split[3];

String isp= split[4];

PhoneBean bean= newPhoneBean();//将每行数据封装在javabean

bean.set(prefix, phone, province, city, isp);//将数据放在map中

map.put(phone, bean) ;

}

br.close();returnmap;

}/**

* 将数据号段数据封装在list中

* @return

* @throws FileNotFoundException

* @throws IOException*/

private static ListgetPhoneList() throws FileNotFoundException, IOException {

List list = new ArrayList<>();

BufferedReader br= new BufferedReader(new FileReader("d:/data/手机号段规则.txt"));

String line= null;

br.readLine();//去除头信息

while ((line = br.readLine()) != null) {

System.out.println(line);

String[] split= line.split("\\s");

String prefix= split[0];

String phone= split[1];

String province= split[2];

String city= split[3];

String isp= split[4];

PhoneBean bean= newPhoneBean();//将每行数据封装在javabean

bean.set(prefix, phone, province, city, isp);//将数据放在list中

list.add(bean);

}

br.close();returnlist;

}

}

View Code

获取总流量最高的省份Top3

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classTest2 {

@SuppressWarnings("resource")public static voidmain(String[] args) throws Exception {

Map map = PhoneUtils.getPhoneMap();//10万//存储运算结果的map 省key 流量value

Map pMap = new HashMap<>() ;

BufferedReader br= new BufferedReader(new FileReader("d:/data/http.log"));

String line ;while((line = br.readLine())!=null){//System.out.println(line);

String[] split = line.split("\\s");

String tel= split[0];//流量数据

String upData = split[2];

String downData= split[3];//根据手机号的前七位获取对应的手机数据

PhoneBean bean = map.get(tel.substring(0, 7));//手机号对应的省份

String province =bean.getProvince();

Integer sum= pMap.getOrDefault(province, 0);

sum+=Integer.parseInt(upData)+Integer.parseInt(downData) ;

pMap.put(province, sum);

}

Set ksys =pMap.keySet();for (String string: ksys) {

System.out.println(string+":"+pMap.get(string));

}//map排序

br.close();

}

}

View Code

此处的代码每次访问都要加载(但实际加载一次就行了),数据量若特别大的话,就耗费时间,解决办法是,使用静态代码块(随类的加载而加载一次)

Map map = PhoneUtils.getPhoneMap();//10万

换成静态代码块,如下

static Map

static{

map=PhoneUtils.getPhoneMap();

}

(3)根据给的手机号段运营商规则,计算出总流量最高的运营商Top3

8f900a89c6347c561fdf2122f13be562.png

961ddebeb323a10fe0623af514929fc1.png

public classTest3 {

@SuppressWarnings("resource")public static voidmain(String[] args) {try(BufferedReader br = new BufferedReader(new FileReader("d:/data/http.log"));){

Map map =PhoneUtils.getPhoneMap();

Map iMap = new HashMap<>();

String line ;while((line = br.readLine())!=null){

String[] split= line.split("\\s");

String tel= split[0] ;

String up= split[2] ;

String down= split[3] ;

PhoneBean bean= map.get(tel.substring(0, 7));

String isp=bean.getIsp();

Integer sum= iMap.getOrDefault(isp, 0);

sum+=Integer.parseInt(up)+Integer.parseInt(down);

iMap.put(isp, sum) ;

}//map排序

}catch(Exception e) {//TODO: handle exception

}

}

}

View Code

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值