-1

I got this task I'm supposed to solve: create a class whose constructor parses text in the CSV format (don't have to worry about escaping and quoting for now). The second argument to the constructor is the name of the field by which subsequent searching will be done. Assume that the values in that field are unique. The class should implement interface CSVSearch:

interface CSVSearch {
    CSVRecord find(String key); // returns null if nothing is found
}

interface CSVRecord {
    String getField(String name);
}

And then I have a sample usage:

CSVSearch csvByName = new YourCSVSearch(
"ip,name,desc\n"+
"10.0.0.1,server1,Main Server\n"+
"10.0.0.5,server2,Backup Server\n",
"name");

csvByName.find("server2").getField("ip") -> "10.0.0.5"
csvByName.find("server9") -> null

The entire code should take between 20-30 lines.

What baffled me here, first of all, is that by implementing CSVSearch interface it supposed to return CSVRecord object. But CSVRecord is an interface, so I can't have it as an object, right?

Second of all, if I'm having interfaces to implement, how am I supposed to chain their methods (csvByName.find("server2").getField("ip"))?

I started to write my solution:

public class CSVfinder {

public static void main(String[] args) {

    CSVparser csvByName = new CSVparser("ip,name,desc\n"
            + "10.49.1.4,server1,Main Server\n"
            + "10.52.5.1,server2,Backup Server\n", "name");
    }
}

class CSVparser implements CSVSearch, CSVRecord {

    String lines[];
    String keys[];
    String values[];

    public CSVparser(String text, String key_name) {
        lines = text.split("\n");
        keys = lines[0].split(",");
    }

    public String getField(String name) {
        // TODO Auto-generated method stub
        return null;
    }

    public CSVRecord find(String key) {
        // TODO Auto-generated method stub
        return null;
    }
}

interface CSVSearch {
    CSVRecord find(String key); // returns null if nothing is found
}

interface CSVRecord {
    String getField(String name);
}

I'm lost here... How would you solve it?

Igal
  • 5,833
  • 20
  • 74
  • 132
  • 2
    `But CSVRecord is an interface, so I can't have it as an object, right?` - Your implementation of `CSVSearch` would return something that implements `CSVRecord`. – August Sep 28 '14 at 15:22
  • 1
    The chaining is automatic: `csvByName.find("server2")` returns an object of type `CSVRecord`, so the expression `csvByName.find("server2")` is of type `CSVRecord`. And `CSVRecord` has a method `getField()`. So you can do `csvByName.find("server2").getField("ip")`. Which is equivalent to `CSVRecord record = csvByName.find("server2"); record.getField("ip");` – JB Nizet Sep 28 '14 at 15:26
  • @JBNizet Again, something that I don't understand: how am I supposed to return here `csvByName.find("server2")` something of type CSVRecord if CSVRecord is an interface, and not an object? – Igal Sep 28 '14 at 15:36
  • 1
    You create a class (for example MyCoolCSVRecord), which implements CSVRecord. And inside the find() method, you return an instance of MyCoolCSVRecord. Since MyCoolCSVRecord implements CSVRecord, it **IS A** CSVRecord. That's the fundamental aspectof OO: polymorphism. – JB Nizet Sep 28 '14 at 15:39
  • http://stackoverflow.com/questions/56860/what-is-the-liskov-substitution-principle reading this will help you understand what is going on a bit. – ultrajohn Sep 28 '14 at 15:39

2 Answers2

2

First a general thought about interfaces:

When an object is of a class that implements an interface, then it can be stored in a variable of the interface type.

For instance, SomeInterface variable1 = new SomeInterfaceImplementation(); is totally valid.

However, you must keep in mind, that you cannot call any of the methods, defined in the implementation (even public ones) on the varaible, if they are not declared (or inherited) in the interface definition.

That said, the general structure for your problem's solution in addition to the interface definitions would be like:

public class MyCSVSearch implements CSVSearch {

    // Some constructor that would accept the file/text to parse and parse it with a good logic

    public CSVRecord find(String key) {

        MyCSVRecord record = new MyCSVRecord(); // Note this is your class that implements CSVRecord.

        // The logic to store the record details into the record object

        return record; // As said initially, it is ok to return an object of MyCSVRecord as it implements CSVRecord.
    }

}

public class MyCSVRecord implements CSVRecord {

    // May be you need some properties to store the data (perhaps a hash map).

    public String getField(String name) {
        // Return the relevant field from the properties
    }

}

As for chaining - you are correct. Simply calling csvByName.find("server2").getField("ip") would indeed work.

Gurusharan S
  • 365
  • 1
  • 7
1

Look at the sample , it says YourCSVSearch . That's the point of Interfaces , every student in your class (you said this is an assignment ) will come up with his own way of parsing a CSV formatted file , but still everyone has to implement those 2 interfaces so they are obliged to define (override) the 2 functions : getField() and find() .

The point of it is when a dev gives a task to another dev , he expects him to give a result which he ( the 1st dev) can use in his own program ... to simplify it : your teacher could write a whole program using the 2 fuctions getField() and find() without knowing how they work , simply cuz he doesn't need to , he expects you to have made them properly , and then expects the result he "forced" .

Now to answer the question "how is that even possible" ... you need to learn about abstract classes and about interfaces . Although Interface might not seem an object , when a Class implements it there should be a definition of the abstract Method inside the interface , the instance of that class is the Object of type "that interface" , Example :

lets say I'm developing a geometry application with some other devs , so the general idea here would be geometrical forms which would have a surface and a perimeter , but i want other devs to take care of these , so , i make the interface Form :

public interface Form {
  public double perimeter();
  public double surface();
}

so the first dev decides to make the Circle , so he would do this :

public class Circle implements Form {
 //as soon as u implement form any IDE would tell u to implement the abstract methods
  double r;

  public Circle(double r){
    this.r=r;
  }
  @Override //not necessary but this shows that you are defining the method now
  public double surface(){
   return Math.PI*r*r;
  }
  public double perimeter(){
  return 2*math.PI*r;
  }

now the first dev can make instances of type Form like this :

Form circle = new Circle(10);
System.out.println("the circle's surface is :"+circle.surface());

Form is the interface and thus can be called a "type" , Circle is the Object that implements Form then its actually a Form , so any instance of Circle is also a Form , just like anything in JAVA is in fact an Object .

To apply this to your assignment , you have to make classes that implements those interfaces and define the methods ur own way . As for the link you mentioned

csvByName.find("server2").getField("ip")

csvByName is a CSVSearch then has the method find wich returns a CSVRecord which in its turn has the method getField defined in it ... so that's correct use .

Now that's about interface , you can read more about it : here

About how to make the parser ( finding the record and IP ) that ur gonna have to do yourself, just like any parser , read the text or data , find the keyword/letter... and retrieve the data , like for example :

name: ali age: 21
name: X   age: 30

as you can see after "name:" you have the value and same for "age:" , you read the file and search for these keywords . you can read about parsing CSV here

Take your time learning inheritance as it will come in handy a lot later(that's why i made this long post :P ) , you will almost have to deal with this every time you use someone Else's API , good luck .

vlatkozelka
  • 909
  • 1
  • 12
  • 27
  • Thank you very much for taking time and writing this thorough answer! It helped me a lot! I'm really sorry I can't accept more than one answer... – Igal Sep 28 '14 at 16:43