JCH1530
JCH1530

Reputation: 61

Java application that reads in a csv file and compares data in each row

I am fairly new to programming and have just been set the task of creating an application that will read in a .csv file name from a user input before then running a series of tests. Ultimately the program needs to compare each row (each row in the csv file represents one router) and return which routers need a patch based on set criteria. The format of the CSV file will look like this with the headings 'Hostname', 'IP Address', 'Patched?', Os Version, and Notes which do not necessarily need to be included -

A.example.COM,  1.1.1.1, NO,    11,   Faulty fans
b.example.com,  1.1.1.2, no,    13,   Behind other routers
C.EXAMPLE.COM,  1.1.1.3, no,    12.1    
d.example.com,  1.1.1.4, yes,   14  
c.example.com,  1.1.1.5, no,    12,   Case a bit loose
e.example.com,  1.1.1.6, no,    12.3    
f.example.com,  1.1.1.7, No,    12.2    
g.example.com,  1.1.1.6, no,    15

So the program needs to return the name of any routers that do not share the same Hostname and IP Address as any other router, has a current OS version of 12 or higher, or has not already been patched.

So far I have tried to read in each individual line as a Java object and compare from there however I have had no success. Any suggestions on a good way to go about making this program work would be greatly appreciated, thanks.

Upvotes: 0

Views: 420

Answers (3)

BetaDev
BetaDev

Reputation: 4674

Working Solution for you csv format. See how contains method works using equals and hashCode.
You need to override equals and hashcode methods to compare and to use the contains() method

Here is the solution for your csv that you have posted here.

package csv;

import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 *
 * @author Shailesh Singh
 */
public class CSV {
    public static void main(String[] args) {
        List<Router> routers = new ArrayList<Router>();
        String fileToParse = "aaa.csv";
        BufferedReader fileReader = null;
        try
        {
            String line = "";
            fileReader = new BufferedReader(new FileReader(fileToParse));
            while ((line = fileReader.readLine()) != null) 
            { 
                String[] tokens = line.split("\\,", -1);
                //First level filter based on your requirement.
                if(Float.parseFloat(tokens[3])>=12 || tokens[2].toLowerCase().equals("no")){// this will check whether os version greater than 12 or pached no
                    routers.add(new Router(tokens[0], tokens[1], tokens[2], tokens[3], tokens[4]));
                }
            }
        } 
        catch (Exception e) {
            e.printStackTrace();
        } 
        finally
        {
            try {
                fileReader.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }

        List<Router> uniqueList = new ArrayList<Router>();
        System.out.println(routers);
        System.out.println("\n..........................................");
        for (Router router : routers) {
            //Loop through all the objects and store in a new unique array list
            //contains method works based on equals and hashcode
            if (!uniqueList.contains(router)) {
                uniqueList.add(router);
            }
        }
        System.out.println(uniqueList);
    }

}

Now Router.java

package csv;

/**
 *
 * @author Shailesh Singh
 */
public class Router {
    private String hostName;
    private String ip;
    private String patched;
    private String osVersion;
    private String note;

    public Router(String hostName, String ip, String patched, String osVersion, String note) {
        this.hostName = hostName;
        this.ip = ip;
        this.patched = patched;
        this.osVersion = osVersion;
        this.note = note;
    }

    public String getHostName() {
        return hostName;
    }

    public void setHostName(String hostName) {
        this.hostName = hostName;
    }

    public String getIp() {
        return ip;
    }

    public void setIp(String ip) {
        this.ip = ip;
    }

    //Getters and setters.....................
    //Define all

    @Override
    public String toString() {
        return "Router{" + "hostName=" + hostName + ", ip=" + ip + ", patched=" + patched + ", osVersion=" + osVersion + ", note=" + note + '}'+"\n";
    }

    @Override
    public boolean equals(Object obj) {
        if (obj == this) {
            return true;
        }
        if (obj == null || obj.getClass() != this.getClass()) {
            return false;
        }

        Router r = (Router) obj;
        if((hostName == r.hostName || (hostName != null && hostName.equals(r.getHostName()))) && (ip == r.ip || (ip != null && ip .equals(r.getIp())))){
            return true;
        }
        else{
            return false;
        }
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = 1;
        result = prime * result
                + ((hostName == null) ? 0 : hostName.hashCode());
        result = prime * result
                + ((ip == null) ? 0 : ip.hashCode());
        return result;
    }


}

Notice that the equals() method and the hashCode() method overridden in Router Class.

The important part of this Solution is

............................
    List<Router> uniqueList = new ArrayList<Router>();
    System.out.println(routers);
    System.out.println("\n..........................................");
    for (Router router : routers) {
        //Loop through all the objects and store in a new unique array list
        //contains method works based on equals and hashcode
        if (!uniqueList.contains(router)) {//contains seeks equals and hashcode()
            uniqueList.add(router);
        }
    }
    System.out.println(uniqueList);

Upvotes: 1

AttitudeL
AttitudeL

Reputation: 309

Here are my suggestions:

  1. Create a class (let's call it "Router") that contains "hostName" - String, "ipAddresss" - String, "patched" - Boolean, "osVersion" - Double and "notes" - String. Add related setters and getters.
  2. Create a list "routers" that contains a list of "Router" classes and initialize it to empty.
  3. Create a method that takes a Router object as the parameter. First compare the "osVersion". Then iterates through the "routers" list. During the iteration compare the given Router object against each Router object you encounter. If there are duplicates don't do anything, otherwise add this object to the list after the iteration.
  4. Iterate through each line of the CSV file and parse each row into "Router" object and invoke the method you created from #3.
  5. The "routers" should contain the final result after the program finishes.

Upvotes: 1

Nikolay Kosev
Nikolay Kosev

Reputation: 124

First ask yourself what data structure would be best for your end result.

  1. You need a structure that do not allow duplicates - id say a hashmap would be good for that.
  2. You have 3 criterias for enlisting the line in your output
    • not patched - the easiest of them all criterias
    • version over 12 still nothing hard about it
    • no duplicates

Id advice getting clarification on what priorities for them - because a line can be "no" as patched, verstion over 9000, and have bazilion duplicates - what you do then ? But lets say you have independant criterias - i.e. you check, you enlist two hashMaps union them. One for the duplicates, one for the other two (more mechanical criterias). The final result would be things that suit one of those criterias out there. You can build logic to check with the previous hashmaps - if it is already set in previous list - you can skip adding them. But this will be a tradeoff on using more CPU and less memory. Depending of the size of your inputs you can decide what is better for you.

Now for checking for duplicates - you can check with a hashmap(very fast) for duplicate and add a counter to that record. When you finish with your input - those with counter == 1 would be the one you are looking for.

By the way - set up automatic loading,from file or directly from test code. Typing those listings from a console is a tiresome and uneeded process while developing. Good luck.

Upvotes: 1

Related Questions