2016-06-10 104 views
0

我有这个任务。 输入是TreeMap中的TreeMap,无法从第二张地图获取值

IP=192.23.30.40 message='Hello&derps.' user=destroyer 
IP=192.23.30.41 message='Hello&yall.' user=destroyer 
IP=192.23.30.40 message='Hello&hi.' user=destroyer 
IP=192.23.30.42 message='Hello&Dudes.' user=destroyer 
end 

输出是:

child0: 
192.23.33.40 => 1. 
child1: 
192.23.30.40 => 1. 
destroyer: 
192.23.30.42 => 2. 
mother: 
FE80:0000:0000:0000:0202:B3FF:FE1E:8329 => 1. 
unknown: 
192.23.155.40 => 1. 
yetAnotherUsername: 
192.23.50.40 => 2. 

基本上我有打印每IP和多少邮件每一个用户,他们在格式已将

username: 
IP => count, IP => count… (last must be with dot in end) 

的问题是我不知道如何添加(第27行代码为trow异常,也不知道为什么)+1给IP。 以及如何捕获最后一个键的最后一个值。

package notReady; 

import java.util.Scanner; 
import java.util.TreeMap; 

/** 
* Created by Philip on 10-Jun-16. 
*/ 
public class Problem09_02_UserLogs { 
    public static void main(String[] args) { 
     Scanner scanner = new Scanner(System.in); 
     TreeMap<String, TreeMap<String, Integer>> map = new TreeMap<>(); 

     while (true) { 
      String in = scanner.nextLine(); 
      if (in.equals("end")) { 
       break; 
      } 
      String[] input = in.split(" "); 
      String ip = input[0].replaceAll("IP=", ""); 
      String user = input[2].replaceAll("user=", ""); 

      if (!map.containsKey(user)) { 
       map.put(user, new TreeMap<>()); 
       map.get(user).put(ip, 1); 
      }else { 
       Integer tempCount = (map.get(user).get(ip)) + 1; 
       map.get(user).put(ip, tempCount); 
      } 
     } 

     for (String person : map.keySet()) { 
      System.out.printf("%s: \n", person); 
      for (String ips : map.get(person).keySet()) { 
       System.out.printf("%s => %d.", ips, map.get(person).get(ips)); 
      } 
      System.out.println(); 
     } 
    } 
} 

这是下一个测试,这里一切正常。 输入:

IP=FE80:0000:0000:0000:0202:B3FF:FE1E:8329 message='Hey&son' user=mother 
IP=192.23.33.40 message='Hi&mom!' user=child0 
IP=192.23.30.40 message='Hi&from&me&too' user=child1 
IP=192.23.30.42 message='spam' user=destroyer 
IP=192.23.30.42 message='spam' user=destroyer 
IP=192.23.50.40 message='' user=yetAnotherUsername 
IP=192.23.50.40 message='comment' user=yetAnotherUsername 
IP=192.23.155.40 message='Hello.' user=unknown 
end 

输出:

destroyer: 
192.23.30.40 => 2, 192.23.30.41 => 1, 192.23.30.42 => 1. 

回答

1

我不得不猜测(我不会指望行,看看有什么是第27行),但它可能是这一行:Integer tempCount = (map.get(user).get(ip)) + 1;。看看你的代码:上面的3行将空的树形图放入map,用户是关键。然后你为某些ip添加一个计数。 但是如果该用户的下一个IP是不同您现在可以尝试从地图获取不存在的键的值,并向其添加1。

例子:

user = "ThomasGo" 
ip1 = "1.2.3.4" 

填补了地图后,你就会有这样的事情:

Map[key:"ThomasGo"->Map[key:"1.2.3.4"->1]] 

现在下面的调用应该会成功:

Integer tempCount = map.get("ThomasGo").get("1.2.3.4") + 1; 

然而,考虑下一个呼叫使用不同的IP,例如“2.2.2.2”:

Integer tempCount = map.get("ThomasGo").get("2.2.2.2") + 1; 

由于内部地图不包含IP map.get("ThomasGo").get("2.2.2.2")将返回null。接下来,系统会尝试解除空值以便为其添加1,但拆箱失败并带有NullPointerException。

为了解决这个问题,你必须检查你是否真的得到了一个ip计数,如果不是只把1放到内部映射。

例子:

Map<String, Integer> ipMap = map.get("ThomasGo"); 

//no map found for the username 
if(ipMap == null) { 
//create a new inner map and put it into the outer map and keep the reference for further use 
ipMap = new TreeMap<>(); 
map.put("ThomasGo", ipMap); 
} 

//check whether the ip is in the inner map 
Integer ipCount = ipMap.get(ip); 
if(ipCount == null) { 
    //no count in the map so just put 1 
    ipMap.put(ip, 1); 
} 
else { 
    //already a count in the map so overwrite it with count + 1 
    ipMap.put(ip, ipCount + 1); 
} 

,如何捕捉到最后一个关键的最后一个值。

这实际上很简单,至少如果我正确理解您的要求:您不需要。只需打印每个IP映射并在第一个之前添加一个逗号(可以使用布尔标志),在循环之后而不是System.out.println();之后,您可以打印System.out.println(".");,它打印一个点,然后打印一个换行符。

+0

感谢您的帮助:)对不准确的错误。 – Phil