0

In short: I have to build the iPsForDays method, which has no parameters. This method returns a HashMap> that uses records and maps days from web logs to an ArrayList of IP addresses that occurred on that day (including repeated IP addresses). For example, Sep 14 maps to one IP address, Sep 21 maps to four IP addresses, and Sep 30 maps to five IP addresses. My issue is that to every key(date) the value(ArrayList) is the same (contains the same values). How can I have different values? Here's the code:

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;       
}
1
  • could you give sample output? Commented Feb 25, 2016 at 6:31

4 Answers 4

1

You are creating only one instance of ips ArrayList. Whatever changes you'll make to this ArrayList will be reflected throughout your Map. You'll have to create new instances of this ArrayList to achieve what you are trying to achieve.

Just move this ArrayList<String> ips = new ArrayList<String>(); inside your for loop condition. Also, you'll have to change the code to add new object to the list when it is already present in the Map.

Here is the corrected code snippet:

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;       
}
Sign up to request clarification or add additional context in comments.

1 Comment

@StMit Your Welcome! :)
0

initialize your arraylist in for loop

for(LogEntry le : records){
ips = new ArrayList<String>();
 .......
 ........

This will create a new ArrayList for every day and store in Map

Comments

0

You need to declare ips inside your for loop as in code below, however there are other issues as well. See comments in code and the description below

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;       
}

You defined your object outside the for loop, so everytime you are using same object. Solution is to create new Object for every key. However I recommended following changes too:-

  1. Get the existing ArrayList for the key and your Ip there. You were adding all Ip again in every iteration.
  2. Don't need to check unique in else if as it is the first time you adding an element in the ArrayList for the key
  3. You need to check unique in if condition. and If you need unique why don't you use HashSet? contains is quite intense operation for an Array!

Comments

0

Here i have modified your code. So thing you need to check whether map contains date, if not, then check whether arraylist ips is null or not, if null that means we just entered the loop, so no need to add to the map, simply initialize the arraylist and start adding 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;       
    }

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.