Fixing mistakes
As the comments mentioned, you forgot to initialise some variable. First of all, as you did not explicitly define in your code, I assume that FinaData1
is a List<String>
.
- you forgot to initialise
num1
- you need to remember that you already scan a specific ip address
- in your second for loop, you confused the iterator: you used
get(l)
instead of get(e)
. With get(l)
, you'll always have tempIP2.equals(tempIP1) = true
as tempIP1 = domainDailyData1.get(l)
With correction, your code looks like:
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);
}
Tested with the input in the code.
Java stream: a bit more fun
If you happen to use Java 8, then you can play a bit with stream. The idea is to heavily rely on the fact that your list is always correctly ordered:
For any i in [0, list.size()], you have:
if i % 3 = 0
then you have the domain name
if i % 3 = 1
then you have the ip address (format does not matter)
if i % 3 = 2
then you have the visit count which is a proper integer
This also means that the list size is always a multiple of 3: list.size() % 3 = 0
.
Consequently, I'll do as follow:
- find all ip address and group by it
- find the next element which is the view count and sum it
which gives:
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);
}
If you want to copy paste for testing
- without the explanation
- and with static method reference
- without the
peek()
- not map definition, directly print the result:
the code is:
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);
}
This was rather for fun so this code may obviously not be 100% error-proof.
Source: