总结arraylist中的特定数据

时间:2017-10-11 15:04:40

标签: java arraylist

我正在寻找一种基于特定条件在我的ArrayList中总结一些特定数据的好方法,但我无法按预期工作。我的ArrayList包含以下数据序列Domain,IP,Total Number,例如:

[gmail.com", "172.11.0.89", 1, gmail.com", "172.11.0.89", 60, "gmail.com", "192.168.0.66", 13] 

我尝试做的是遍历ArrayList并检索IP地址。之后,我将获得下一个total number的索引。我将通过整个ArrayList检查任何类似的IP。如果我找到类似的IP,我会做同样的事情并总结total number与之前的total number。例如,172.11.0.89的总数应包含61,因为60 + 1 = 61.

但我没有得到那个输出。这是我的示例输出:

[gmail.com", "172.11.0.89", 1, gmail.com", "172.11.0.89", 60, "gmail.com", "192.168.0.66", 13] 
The IP "172.11.0.89"
The IP "172.11.0.89"
The IP "192.168.0.66"
The Data in Final Data is :["172.11.0.89", 1, "172.11.0.89", 75, "172.11.0.89", 149, "192.168.0.66", 223]

这是我的源代码:

System.out.println(domainDailyData1);
for(int l = 1;l<domainDailyData1.size();l+=3)  // getting the total count 
  {
     String tempIP1 = domainDailyData1.get(l);
     System.out.println("The IP "+tempIP1);
     for(int e = 1;e<domainDailyData1.size();e+=3)
     {
         String tempIP2 = domainDailyData1.get(l);

          if(tempIP2.equals(tempIP1))
           {
              String str1 = domainDailyData1.get(e+1);

              int temp1 = Integer.parseInt(str1);
              num1 += temp1;
           }
     }
         FinalData1.add(tempIP1);
         FinalData1.add(String.valueOf(num1));

 }
   System.out.println("The Data in Final Data is :"+FinalData1);

1 个答案:

答案 0 :(得分:3)

修复错误

正如提到的评论,你忘了初始化一些变量。首先,正如您未在代码中明确定义的那样,我认为FinaData1List<String>

  1. 您忘了初始化num1
  2. 您需要记住您已经扫描了特定的IP地址
  3. 在你的第二个for循环中,你混淆了迭代器:你使用了get(l)而不是get(e)。使用get(l),您将始终tempIP2.equals(tempIP1) = true作为tempIP1 = domainDailyData1.get(l)
  4. 通过更正,您的代码如下所示:

    public static void main(String... aArgs) {
       List<String> domainDailyData1 = Arrays.asList(new String[]{
            "gmail.com", "172.11.0.89", "1",
            "gmail.com", "172.11.0.89", "60",
            "gmail.com", "192.168.0.66", "13"});
    
        // >>> convention: don't use capital letter as the first letter of a variable
        List<String> finalData1 = new ArrayList<>();
    
        // getting the total count 
        for (int l = 1; l < domainDailyData1.size(); l += 3) {
            String tempIP1 = domainDailyData1.get(l);
    
            // 2. to avoid looping an IP that you already counted
            if (!finalData1.contains(tempIP1)) {
    
                System.out.println("The IP " + tempIP1);
    
                // 1. num1 initialisation
                int num1 = 0;
    
                for (int e = 1; e < domainDailyData1.size(); e += 3) {
    
                    // 3. iterator confusion
                    String tempIP2 = domainDailyData1.get(e);
    
                    if (tempIP2.equals(tempIP1)) {
                        String str1 = domainDailyData1.get(e + 1);
                        int temp1 = Integer.parseInt(str1);
                        num1 += temp1;
                    }
                }
    
                finalData1.add(tempIP1);
                finalData1.add(String.valueOf(num1));
            }
        }
    
        System.out.println("The Data in Final Data is :" + finalData1);
    }
    

    使用代码中的输入进行测试。

    Java流:更有趣

    如果您碰巧使用Java 8,那么您可以使用流播放一些内容。我们的想法是严重依赖于您的列表始终正确排序的事实:

      

    对于[0,list.size()]中的任何i,您有:

         
        
    • 如果i % 3 = 0则您拥有域名

    •   
    • 如果i % 3 = 1则您拥有 IP地址(格式无关紧要)

    •   
    • 如果i % 3 = 2您有访问次数,这是正确的整数

    •   
         

    这也意味着列表大小始终是3的倍数:list.size() % 3 = 0

    因此,我会做如下:

    1. 找到所有IP地址
    2. 找到下一个视图计数元素并将其相加
    3. 给出:

      public static void main(String... aArgs) {
      
          List<String> domainDailyData1 = Arrays.asList(new String[]{
              "gmail.com", "172.11.0.89", "1",
              "gmail.com", "172.11.0.89", "60",
              "gmail.com", "192.168.0.66", "13"});
      
          // Result is a map as it is a pairing <IpAddress, Count>
          Map<String, Integer> countMap = Stream
                  // Start with index = 1 and then jump by step of 3                
                  .iterate(1, i -> i + 3)
                  // Get the number of ip address to scan. A row a basically the 
                  // triplet {domain, ip address, count} as I defined for the input.
                  //
                  // Integer division: if list size is below 3, then the result is
                  // 0 and nothing happens. If the list size is not a multiple of
                  // 3, for example, 11, then the result is 3 and last rows (index
                  // from 8 to 10) are ignored
                  .limit(domainDailyData1.size() / 3)
                  // optional line but if you want to know what's currently happening...
                  .peek(i -> System.out.println("Checking IP Address: " + domainDailyData1.get(i)))
                  // Result is a map as it is a pairing <IpAddress, Count>
                  .collect(Collectors.toMap(
                          // The key is of course the ip address which is at 
                          // position i. What's nice with Map is that if a another
                          // identical ipaddress is found, the key are merged. That's
                          // why it is necessary to define a merge function
                          i -> domainDailyData1.get(i),
                          // fetch the count associated with index i. As one never
                          // trust unknown input, any invalid count means zero
                          i -> {
                              try {
                                  // Just get the count. The i+1 is not supposed
                                  // to trigger the ArrayOutOfBoundException as 
                                  // guaranteed by the .limit() above
                                  Integer count = Integer.parseInt(domainDailyData1.get(i + 1));
                                  return count;
                              }
                              catch (NumberFormatException e) {
                                  // silent exception catching but you can do
                                  // anything here
                                  return 0;
                              }
                          },
                          // If two ip addresses are found, just sum the count
                          // The static method reference form is Integer::sum
                          (oldCount, newCount) -> oldCount + newCount
                      )
                  );
      
          System.out.println(countMap);
      }
      

      如果要复制粘贴以进行测试

      • 没有解释
      • 并使用静态方法参考
      • 没有peek()
      • 不是地图定义,直接打印结果:

      代码是:

      public static void main(String... aArgs) {
      
          List<String> domainDailyData1 = Arrays.asList(new String[]{ "gmail.com", "172.11.0.89", "1", "gmail.com", "172.11.0.89", "60", "gmail.com", "192.168.0.66", "13"});
      
          Stream
              .iterate(1, i -> i + 3)
              .limit(domainDailyData1.size() / 3)
              .collect(Collectors.toMap(
                      i -> domainDailyData1.get(i),
                      i -> {
                          try {
                              return Integer.parseInt(domainDailyData1.get(i + 1));
                          }
                          catch (NumberFormatException e) {
                              return 0;
                          }
                      },
                      Integer::sum))
              .entrySet()
              .stream()
              .forEach(System.out::println);
      }
      

      这很有趣,所以这段代码显然不是100%防错。

      来源: