我正在寻找一种基于特定条件在我的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);
答案 0 :(得分:3)
正如提到的评论,你忘了初始化一些变量。首先,正如您未在代码中明确定义的那样,我认为FinaData1
是List<String>
。
num1
get(l)
而不是get(e)
。使用get(l)
,您将始终tempIP2.equals(tempIP1) = true
作为tempIP1 = domainDailyData1.get(l)
通过更正,您的代码如下所示:
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 8,那么您可以使用流播放一些内容。我们的想法是严重依赖于您的列表始终正确排序的事实:
对于[0,list.size()]中的任何i,您有:
如果
i % 3 = 0
则您拥有域名如果
i % 3 = 1
则您拥有 IP地址(格式无关紧要)如果
i % 3 = 2
您有访问次数,这是正确的整数这也意味着列表大小始终是3的倍数:
list.size() % 3 = 0
。
因此,我会做如下:
给出:
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%防错。
来源: