简而言之:我必须构建 iPsForDays 方法,该方法没有参数。此方法返回HashMap>使用记录并将天数从Web日志映射到当天发生的IP地址的ArrayList(包括重复的IP地址)。例如,Sep 14映射到一个IP地址,Sep 21映射到四个IP地址,Sep 30映射到五个IP地址。 我的问题是每个键(日期)的值(ArrayList)是相同的(包含相同的值)。我怎么能有不同的价值观?这是代码:
public HashMap<String, ArrayList<String>> iPsForDays(){
HashMap<String, ArrayList<String>> mapDatesToIPs = new HashMap<String,ArrayList<String>>();
ArrayList<String> ips = new ArrayList<String>();
for(LogEntry le : records){
Date d = le.getAccessTime();
String dates = d.toString().substring(4, 10);//date is a diff format
if(!mapDatesToIPs.containsKey(dates)){
ips.add(le.getIpAddress());
mapDatesToIPs.put(dates, ips);
}
else if(mapDatesToIPs.containsKey(dates)){
String ip = le.getIpAddress();
if(!ips.contains(ip)){
ips.add(ip);
}
}
}
return mapDatesToIPs;
}
答案 0 :(得分:0)
在for循环中初始化你的arraylist
for(LogEntry le : records){
ips = new ArrayList<String>();
.......
........
这将为每天创建一个新的ArrayList并存储在Map
中答案 1 :(得分:0)
您需要在for循环中声明ips
,如下面的代码所示,但是还有其他问题。请参阅代码中的注释和以下说明
public HashMap<String, ArrayList<String>> iPsForDays(){
HashMap<String, ArrayList<String>> mapDatesToIPs = new HashMap<String,ArrayList<String>>();
for(LogEntry le : records){
Date d = le.getAccessTime();
String dates = d.toString().substring(4, 10);//date is a diff format
if(!mapDatesToIPs.containsKey(dates)){
//Changed Below
String ip = le.getIpAddress();
ArrayList<String> ips = mapDatesToTps.get(dates);
//If you need unique then why ArrayList not HashSet?
if(!ips.contains(ip)){
mapDatesToTps.get(dates).add(ip);
}
}
else if(mapDatesToIPs.containsKey(dates)){
/Added Here
ArrayList<String> ips = new ArrayList<String>();
String ip = le.getIpAddress();
}
}
return mapDatesToIPs;
}
您在for循环外定义了对象,因此每次使用相同的对象时都是如此。解决方案是为每个键创建新的Object。但是我也建议进行以下更改: -
contains
是一个非常激烈的阵列操作!答案 2 :(得分:0)
您只创建ips
ArrayList的一个实例。无论您对此ArrayList所做的任何更改都将反映在整个地图中。您必须创建此ArrayList的新实例才能实现您想要实现的目标。
只需将此ArrayList<String> ips = new ArrayList<String>();
移到for
循环条件中即可。此外,您必须更改代码,以便在地图中已存在新对象时将其添加到列表中。
以下是更正后的代码段:
public HashMap<String, ArrayList<String>> iPsForDays(){
HashMap<String, ArrayList<String>> mapDatesToIPs = new HashMap<String,ArrayList<String>>();
for(LogEntry le : records){
Date d = le.getAccessTime();
String dates = d.toString().substring(4, 10);//date is a diff format
if(!mapDatesToIPs.containsKey(dates)){
/* Move Here */
ArrayList<String> ips = new ArrayList<String>();
ips.add(le.getIpAddress());
mapDatesToIPs.put(dates, ips);
}
else if(mapDatesToIPs.containsKey(dates)){
String ip = le.getIpAddress();
/* Retrieve List */
ArrayList<String> ips = mapDatesToIPs.get(dates);
ips.add(ip);
}
}
return mapDatesToIPs;
}
答案 3 :(得分:0)
这里我修改了你的代码。所以你需要检查map是否包含日期,如果没有,那么检查arraylist ips是否为null,如果为null则表示我们刚刚进入循环,因此无需添加到地图,只需初始化arraylist并开始添加IP。
public HashMap<String, ArrayList<String>> iPsForDays(){
HashMap<String, ArrayList<String>> mapDatesToIPs = new HashMap<String,ArrayList<String>>();
ArrayList<String> ips = null;
String previous_date = null;
for(LogEntry le : records){
Date d = le.getAccessTime();
String dates = d.toString().substring(4, 10);//date is a diff format
if(!mapDatesToIPs.containsKey(dates)){
if (ips != null && ips.size>0){ //Check whether we have any ips list or it is running for first time, if first then it will be null, so no need to add to mapDatesToIps.
mapDatesToIPs.put(previous_date, ips);
}
previous_date = dates;
ips = new ArrayList<String>();
ips.add(le.getIpAddress());
mapDatesToIPs.put(previous_date, null);
}
else if(mapDatesToIPs.containsKey(dates)){
String ip = le.getIpAddress();
if(!ips.contains(ip)){
ips.add(ip);
}
}
}
//This is necessary as when for loop iteration is over, it will not go to if block but will directly exit so required to check if we do not have ips in list then add it against the last date value we have in previous_date variable.
if (ips != null && ips.size>0){
mapDatesToIPs.put(previous_date, ips);
}
return mapDatesToIPs;
}