在java中计算数据的最佳实践

时间:2015-06-09 10:04:32

标签: java data-processing

假设有一个数据池采用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
}

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

更新: 我将尝试使用散列映射而不是Luke

建议的ListArray来执行此操作

1 个答案:

答案 0 :(得分:2)

重型解决方案:数据库

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

创建一个名为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;
}