零基础学习java------26--------获取省访问量的top3,APP版本数据分析,事务,json,json字符串与对象间的相互转换,求电影平均分

一. day23中的ip,url案例(前面答案错了)

思路分析:

       1.创建javabean,用来存储ip.txt各字段的信息

  2. 创建java工具类,封装相应的方法

    (1) 加载读取ip.txt文档,获取各字段,将之封装进javabean,并将javabean存储至list中去(ip地址为区间范围,用map满足不了需求),以便后面能通过access.log内的ip找到其在ip.txt所属的javabean

    (2)将ip转译为长整型数

    (3)利用二分法查找access.log内的ip在ip.txt所属的javabean(返回javabean,即可得到所属的省份)

  3. 统计各省的访问量

java工具类以及javabean见day23

public class IpTest {
    // 将数据的加载放入静态代码块
            static List<IpBean> list = null;
            static {
                list = IpUtils.loadIpToList();
            }
    public static void main(String[] args) {
        Map<String, Integer> map = readData();
        // 排序
        Set<Entry<String, Integer>> entrySet = map.entrySet();
        ArrayList<Entry<String, Integer>> list = new ArrayList<>(entrySet);
        Collections.sort(list, new Comparator<Entry<String, Integer>>(){
            @Override
            public int compare(Entry<String, Integer> o1, Entry<String, Integer> o2) {
                return o2.getValue()-o1.getValue();
            }
        });
        for (Entry<String, Integer> entry : list) {
            System.out.println(entry);
        }
    }
    public static Map<String, Integer> readData() {
        Map<String, Integer> map = new HashMap<>();
        // 获取以province为key,访问量为value的map
//        Integer sum = 1;
        try (
                BufferedReader br = new BufferedReader(new FileReader("E:\\javafile\\access.log"));
                ){
            String line = null;
            while((line=br.readLine()) != null) {
                String[] split = line.split("\\|");
                String ip = split[1];
                //将ip转译成长整型
                Long ip1 = IpUtils.parseStrIpToLongIp(ip);
                //利用二分查找获取ip1对应的javabean
                IpBean bean = IpUtils.binaryOfIp(ip1, list);
                String province = bean.getProvince();
                Integer count = map.getOrDefault(province, 0);
                map.put(province, ++count);
//                if(map.containsKey(province)) {  这种叠加访问量的方式不知道错在哪
//                    map.put(province, ++sum);
//                }else {
//                    map.put(province, 1);
//                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return map;
    }
}

运行结果:

 

 

 

二. APP版本数据分析

1.数据

 

 

 

 

 

 2. 需求:

  统计出每天的app版本升级情况(最小版本,和最大版本),此外日期要按时间升序排列

 

 

 

 3. 思路分析

(1)以日期,用户名,app名,新版本下载渠道为key,装有version的Set为value,将数据封装至map

(2)将map的value值排序(升序),可得出每天最早的版本和最后更新的版本

(3)创建AppBean,用来存放上图各字段的值

(4)对AppBean中的时间字段进行排序(升序)-----> 将时间(String)转译成date格式, 使用date1.before(date2)

代码如下

AppBean

public class AppBean {
    private String date;
    private String userName;
    private String appName;
    private String store;
    private String minVersion;
    private String maxVersion;
    
    public AppBean() {
        
    }

    public AppBean(String date, String userName, String appName, String store, String minVersion, String maxVersion) {
        super();
        this.date = date;
        this.userName = userName;
        this.appName = appName;
        this.store = store;
        this.minVersion = minVersion;
        this.maxVersion = maxVersion;
    }


    public String getDate() {
        return date;
    }

    public void setDate(String date) {
        this.date = date;
    }

    public String getUserName() {
        return userName;
    }

    public void setUserName(String userName) {
        this.userName = userName;
    }

    public String getAppName() {
        return appName;
    }

    public void setAppName(String appName) {
        this.appName = appName;
    }

    public String getStore() {
        return store;
    }

    public void setStore(String store) {
        this.store = store;
    }

    public String getMinVersion() {
        return minVersion;
    }

    public void setMinVersion(String minVersion) {
        this.minVersion = minVersion;
    }

    public String getMaxVersion() {
        return maxVersion;
    }

    public void setMaxVersion(String maxVersion) {
        this.maxVersion = maxVersion;
    }

    @Override
    public String toString() {
        return "AppBean [date=" + date + ", userName=" + userName + ", appName=" + appName + ", store=" + store
                + ", minVersion=" + minVersion + ", maxVersion=" + maxVersion + "]";
    }
}
View Code

实现类

public class appTest {
    public static void main(String[] args) throws Exception {
        // 将日期按从小到大的顺序排列
        ArrayList<AppBean> list = loadDataToBean();
        Collections.sort(list, new Comparator<AppBean>() {
            @Override
            public int compare(AppBean o1, AppBean o2) {
                try {
                    String str1 = o1.getDate();
                    String str2 = o2.getDate();
                    SimpleDateFormat simpleDateFormat = new SimpleDateFormat("yyyy-MM-dd");
                    Date date1 = simpleDateFormat.parse(str1);
                    Date date2 = simpleDateFormat.parse(str2);
                    return date1.before(date2) ?-1:1;
                } catch (ParseException e) {
                    e.printStackTrace();
                }
                return 0;
                
            }
        });
        System.out.println(list);
    }
    // 将数据封装至AppBean
    public static ArrayList<AppBean> loadDataToBean() {
        // 获取缓冲字符流,读取并切割数据
        Map<String, Set<String>> map = new HashMap<>();
        ArrayList<AppBean> arrayList = new ArrayList<>();
        try (
                BufferedReader br = new BufferedReader(new FileReader("E:/javafile/app.txt"));
                ){
            String line = null;
            while((line= br.readLine()) != null) {
                String[] split = line.split(",");
                String date = split[0];
                String userName = split[1];
                String appName = split[2];
                String store = split[3];
                String version = split[5];
                // 将数据封装至map
                String key = date +","+ userName+","+ appName+","+ store;
                Set<String> vs = map.getOrDefault(key, new HashSet<>());
                vs.add(version);
                map.put(key, vs);
            }
            // 
            Set<Entry<String, Set<String>>> entrySet = map.entrySet();
            for (Entry<String, Set<String>> entry : entrySet) {
                //  对value(set)进行排序
                Set<String> set = entry.getValue();
                if(set.size()>1) {
                    ArrayList<String> list = new ArrayList<>(set);
                    Collections.sort(list, (o1,o2)->o1.compareTo(o2));
                    //获取list种的第一个和最后一个
                    String minVersion = list.get(0);
                    String maxVersion = list.get(list.size()-1);
                    String key = entry.getKey();
                    String[] split = key.split(",");
                    // 向 AppBean 封装数据,并将之存储至List中
                    AppBean bean = new AppBean(split[0], split[1], split[2], split[3], minVersion, maxVersion);
                    arrayList.add(bean);
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return arrayList;
    }
}
View Code

 

三  事务(https://www.cnblogs.com/huanongying/p/7021555.html)

1. 概念

  一组逻辑上的操作,在这组逻辑操作中的所有sql语句在执行的过程中要么全部成功,要么全部失败。mysql默认的是一个sql语句一个事务,其会自动提交并执行sql

2. 事务的基本要素(ACID)

(1)原子性(Atomicity):事务开始后所有操作,要么全部做完,要么全部不做,不可能停滞在中间环节。事务执行过程中出错,会回滚到事务开始前的状态,所有的操作就像没有发生一样。也就是说事务是一个不可分割的整体,就像化学中学过的原子,是物质构成的基本单位

(2)一致性(Consistency):事务开始前和结束后,数据库的完整性约束没有被破坏。比如A向B转账,不可能A扣了钱,B却没有收到钱

(3)隔离性(Isolation):同一时间,只允许一个事务请求同一事务,不同的事务之间没有任何干扰。比如A正在从一张银行卡中取出钱,在A取钱的过程结束前,B不能向这张转账。

(4)持久性(Durability):事务完成后,事务对数据库的所有更新将被保存到数据库,不能回滚

3. 事务的并发问题

(1)脏读:事务A读取了事务B更新的数据,然后B回滚操作(读取了未提交的数据),那么A读取到的数据是脏数据

(2)不可重复读:事务A多次读取同一数据,事务B在事务A多次读取的过程中,对数据作了更新并提交,导致事务A多次读取同一数据时,结果不一致

(3)幻读:系统管理员A将数据库中所有学生的成绩从具体的分数改为ABCDE等级,但是系统管理员B就在这个时候插入了一条具体分数的记录,当系统管理员A改结束后发现还有一条记录没有改过来,就好像发生了幻觉一样,这就叫环读

小结:不可重复读和幻读很容易混淆,不可重复读侧重于修改,幻读侧重于新增或删除。解决不可重复读的问题只需锁住满足条件的行,解决幻读需要锁表

4. Mysql事务隔离级别

 

 

 

 

四. json

  Json是一种数据格式,简单并且容易解析,常用于网络之间数据传输,一个json即为一个对象

 

Json字符串与json对象之间的相互转换

  使用阿里巴巴开发的fastjson工具

数据:

 

 转换代码

public class JsonDemo {
    public static void main(String[] args) {
        try (
                BufferedReader br = new BufferedReader(new FileReader("E:/javafile/move.txt"));
                ){
            String line =null;
            while((line = br.readLine()) != null) {
                System.out.println(line);
                //json字符串---->对象
                Movie m = JSON.parseObject(line, Movie.class);
                System.out.println(m);
                // 对象--->字符串
//                String mstr = JSON.toJSONString(m);
//                System.out.println(mstr);
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

 

求每个用户对电影评分的平均分

 

 代码

public class AverageRate {
    public static void main(String[] args) {
        Map<String, Double> avgMap = getAvgMap();
        System.out.println(avgMap);
    }
    
    // 获取以uid为key,平均分数为值的map
    public static Map<String,Double> getAvgMap() {
        Map<String,List<Double>> map = new HashMap<String,List<Double>>();
        Map<String,Double> avgMap = new HashMap<>();
        // 获取缓冲字符流读取文件
        try (
                BufferedReader br = new BufferedReader(new FileReader("E:/javafile/move.txt"));
                ){
            String line = null;
            while((line = br.readLine()) != null) {
                // 获取以uid为key,装有date的list为值的map
                Movie m = JSON.parseObject(line, Movie.class);
                String uid = m.getUid();
                Double rate = m.getRate();
                List<Double> list = map.getOrDefault(uid, new ArrayList<Double>());
                list.add(rate);
                map.put(uid,list);
            }
            // 求平均值,并将相应的值封装进avgMap
            Set<Entry<String, List<Double>>> entrySet = map.entrySet();
            for (Entry<String, List<Double>> entry : entrySet) {
                String uid1 = entry.getKey();
                List<Double> listValue = entry.getValue();
                Double total = (double) 0;
                for(int i=0;i<listValue.size();i++){
                    total += listValue.get(i);
                }
                Double avg = total/listValue.size();
                avgMap.put(uid1,avg);
            }    
        } catch (Exception e) {
            e.printStackTrace();
        }
        return avgMap;
    }
}
View Code

 

posted @ 2019-09-12 21:15  一y样  阅读(237)  评论(0编辑  收藏  举报