java 中统计数据的最佳做法
Best practise for counting data in java
假设有一个 CSV 文件的数据池,其中我们有一个键值对,但键不是唯一的。要求是筛选每一行并将 CSV 数据转换成有用的东西。我将使用以下格式的游戏日志作为示例:
player, pointChange, timestamp
我想做的(这似乎是一个常见的操作)是创建一个摘要 - 随着时间的推移有多少点。我的想法是创建一个代表单个条目的内部 class:
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);}
}
实际挑战:
原始数据大小未知,逐行读取。有没有好的practice/recommended方法来处理这样的数据。我正在考虑制作所有 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 来做到这一点
重解:数据库
如果您要有很多记录,更合适,您希望在一个会话中执行 parsing/inserting 一次,然后处理 later/multiple 次,如果您要不断附加数据。数据库使处理数据集变得非常容易。
创建一个名为 frames
的 table,包含 player
(varchar)、point_change
(int) 和 timestamp
(datetime) 或类似字段.在解析步骤中,只需插入行。然后你可以select distinct player from frames;
得到所有玩家。或 select player, sum(pointChange) from frames group by player;
为特定玩家获得积分。或者在 where 子句中包含时间戳以获得特定 window 时间点。
轻解:HashMap
如果你打算这样做一次更合适。或者,如果记录太少,可以 运行 很多次。它避免了整个 'setting up a database' 步骤。
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;
}
假设有一个 CSV 文件的数据池,其中我们有一个键值对,但键不是唯一的。要求是筛选每一行并将 CSV 数据转换成有用的东西。我将使用以下格式的游戏日志作为示例:
player, pointChange, timestamp
我想做的(这似乎是一个常见的操作)是创建一个摘要 - 随着时间的推移有多少点。我的想法是创建一个代表单个条目的内部 class:
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);}
}
实际挑战: 原始数据大小未知,逐行读取。有没有好的practice/recommended方法来处理这样的数据。我正在考虑制作所有 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 来做到这一点重解:数据库
如果您要有很多记录,更合适,您希望在一个会话中执行 parsing/inserting 一次,然后处理 later/multiple 次,如果您要不断附加数据。数据库使处理数据集变得非常容易。
创建一个名为 frames
的 table,包含 player
(varchar)、point_change
(int) 和 timestamp
(datetime) 或类似字段.在解析步骤中,只需插入行。然后你可以select distinct player from frames;
得到所有玩家。或 select player, sum(pointChange) from frames group by player;
为特定玩家获得积分。或者在 where 子句中包含时间戳以获得特定 window 时间点。
轻解:HashMap
如果你打算这样做一次更合适。或者,如果记录太少,可以 运行 很多次。它避免了整个 'setting up a database' 步骤。
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;
}