【问题标题】:Best practise for counting data in javajava中统计数据的最佳实践
【发布时间】:2015-06-09 10:04:32
【问题描述】:

假设有一个 CSV 文件的数据池,其中我们有一个键值对,但键不是唯一的。要求是筛选每一行并将 CSV 数据转换为有用的东西。我将使用格式为游戏日志的示例:

player, pointChange, timestamp

我想做的(这似乎是一个常见的操作)是创建一个摘要 - 随着时间的推移有多少点。我的想法是创建一个代表单个条目的内部类:

private class GameFrame{
    private String player;
    private int points;
    private ArrayList<String> timeline = new ArrayList<String>();
    private ArrayList<int> pointHistory = new ArrayList<int>();
    GameFrame(String player, int points, String time){
       this.player = player;
       this.points = points;
       this.time.add(time);
    }
   public String getName(){return this.player;}
   public void increment(int change){ 
      this.pointHistory.add(this.points);
      this.points += change;} //will work with negatives to decrement points as well
   public void timeProgress(String time){this.time.add(time);}
}

真正的挑战: 原始数据大小未知,逐行读取。是否有处理此类数据的良好做法/推荐方法。我正在考虑制作所有 GameFrame 对象的列表并嵌套第二个循环,如下所示:

伪代码

for(everything in the input list){
    load up line data;
    for(everything in gameFrame list){
        compare names;
        if names match - update with data
        return;}
    got out of inner loop so it's a new player.
    create entry for new player and add it to gameFrame list
}

这是一种好方法还是有更好的方法(可能先对数据进行排序或使用我不知道的库)?

更新: 我将尝试使用 hashmap 而不是 Luke 建议的 ListArray 来做到这一点

【问题讨论】:

  • 有点取决于你在这里真正想要什么数字,这可能会改变多少,等等。可以通过它并使用标准的旧 HashMap 来存储 KeyValue 对。或者,我最喜欢的:解析所有内容,将其放入数据库中。数据库非常擅长处理数据集!
  • 我认为我实际上可以在其中嵌入一个轻量级数据库 - 不久前我正在使用 HSQLdb,它运行良好,但我仍然需要以某种方式得到在我可以按名称过滤之前知道所有玩家的名字。
  • 任何数据库。为什么你需要了解球员?只要有一个frames 表与playerpointChangetimestamp。然后插入行。然后可以select distinct player from frames;获取所有玩家,select player, sum(pointChange) from frames group by player;获取积分等。
  • 但是,为一项工作引入数据库的想法很有趣。您是否也考虑过超级简单的 HashMap 解决方案?需要什么样的处理,多久一次,多少条记录?
  • 记录可能不会超过 1000。我将查看 hashmap。我仍然以 csv 文件的形式获取数据,但它不会发生变化(除非提供了新文件)——它只是为了绘制游戏的统计数据。要选择一个不同的玩家,我需要根据 Select * FROM frame where player="name"; 知道他的名字,不是吗?

标签: java data-processing


【解决方案1】:

重型解决方案:数据库

如果您要拥有大量记录,则更合适的是,您希望在一个会话中进行一次解析/插入,然后稍后/多次进行处理,并且如果您要不断地附加数据。数据库使处理数据集变得非常容易。

创建一个名为frames 的表,其中包含player (varchar)、point_change (int) 和timestamp (datetime) 或类似字段。在解析步骤中,只需插入行。然后你可以select distinct player from frames;获取所有玩家。或select player, sum(pointChange) from frames group by player; 获取特定玩家的积分。或者在 where 子句中包含时间戳以获取特定时间窗口内的分数。

轻量级解决方案:HashMap

如果你打算这样做一次更合适。或者,如果记录太少以至于可以轻松运行多次。它避免了整个“设置数据库”步骤。

HashMap<String, Integer> map = new HashMap<String, Integer>();

public void insert(String player, int scoreChange) {
    Integer value = map.get(player);
    if (value == null)
        value = 0;
    map.put(player, value + scoreChange)
}

public void getScore(String player) {
    Integer value = map.get(player);
    if (value == null)
        value = 0;
    return value;
}

【讨论】:

    猜你喜欢
    • 2011-04-23
    • 2014-03-20
    • 2016-09-17
    • 2011-03-09
    • 2012-04-28
    • 1970-01-01
    • 2011-11-23
    • 2018-07-01
    • 1970-01-01
    相关资源
    最近更新 更多