0

The method I am working on is readDataFromFile(). It reads a file that has data separated with Tabs such as:

Bird    Golden Eagle    Eddie
Mammal  Tiger   Tommy
Mammal  Lion    Leo
Bird    Parrot  Polly
Reptile Cobra   Colin

This is what I have been asked to do however I may not fully understand how to create this, any help would be much appreciated.

Question I have been given:

Spaces at the beginning or end of the line should be ignored. You should extract the three substrings and then create and add an Animal object to the zoo. You should ignore the first substring ("Bird" in the above example) as it is not required for this part of this project. Also note that, similar to the code you should have commented out, the addAnimal() method will require a third parameter "this" representing the owner of the collection. On successful completion of this step you will have a "basic" working version of readDataFromFile()

Zoo class:

public class MyZoo
{
   private String zooId;
   private int nextAnimalIdNumber;
   private TreeMap<String, Animal> animals;
   private Animal animal;

   public MyZoo(String zooId)
   {
      this.zooId = zooId.trim().substring(0,3).toUpperCase();
      nextAnimalIdNumber = 0;
      animals = new TreeMap<String, Animal>();
   }

   public String allocateId()
   {
      nextAnimalIdNumber++;
      String s = Integer.toString(nextAnimalIdNumber);
      while ( s.length()<6 )
         s = "0" + s;
      return zooId + "_" +  s;
   }

   public void addAnimal(Animal animal)
   {
      animals.put(animal.getName(), animal);
      this.animal = animal;
   }

   public void readDataFromFile() throws FileNotFoundException
   {
      int noOfAnimalsRead = 0;

      String fileName = null;

      JFrame mainWindow = new JFrame();
      FileDialog fileDialogBox = new FileDialog(mainWindow, "Open", FileDialog.LOAD);
      fileDialogBox.setDirectory("."); 
      fileDialogBox.setVisible(true);

      fileName = fileDialogBox.getFile();
      String directoryPath = fileDialogBox.getDirectory();

      File dataFile = new File (fileName);
      Scanner scanner = new Scanner(dataFile);
      //System.out.println("The selected file is " + fileName);

      scanner.next();
      while(scanner.hasNext())
      {
      String name = scanner.nextLine();
      System.out.println("Animal: " + name);
      }
    }

Animal Class:

public class Animal
{
   private String id;
   private String species;
   private String name;
   public Animal(String species, String name, MyZoo owner)
   {
      id = owner.allocateId();
      this.species = species;
      this.name  = name;
   }

   public String getId()
   {
      return id;
   }

   public String getName()
   {
      return name;
   }

   public String getSpecies()
   {
      return species;
   }

   public String toString()
   {
      return id + "  " + name + ": a " + species;
   }
}
  • Seems to be a recurrent questio these days [Reading tab separated data JAVA](https://stackoverflow.com/q/51304739/4391450). But you will find my answer below. – AxelH Jul 13 '18 at 13:08

2 Answers2

2
while( scanner.hasNext() ) {
    String fileLine = scanner.nextLine()
    String[] animalNames = fileLine.split("\t")
    ...
}

You already are using a scanner in your code, so I'm assuming you know in general how the scanner works. The above code first reads in the next line of input, as a String. So, for example, after that first bit,

fileLine := "Bird    Golden Eagle    Eddie"

Then, I declare an Array of strings called animalNames, and set it equal to fileLine.split("\t"). This is a method you can call on a String - what it does is it returns an array of substrings, delimited by whatever you give it. In this case, I give the function "\t", which is the character that represents a tab. So, after this line,

animalNames := {"Bird", "Golden Eagle", "Eddie"}

Since you now have an array of strings, you can do the rest of the assignment by picking items out of it - for example,

animalNames[0] := "Bird"
animalNames[1] := "Golden Eagle"
animalNames[2] := "Eddie"
Green Cloak Guy
  • 18,876
  • 3
  • 21
  • 38
  • I'm not 100% familiar with using a split() method, however i am currently looking it up. Would you be able to give me a partial answer just so i can decipher the code and understand? – Melissa Stewart Jul 12 '18 at 17:05
  • Could this also be done WITHOUT using the split() method? – Melissa Stewart Jul 12 '18 at 17:15
  • @MelissaStewart `fileLine.split("\t")` will take a given line, and will "split" it at each tab (`\t`) character. It will return an array of substrings where each substring was previously separated by a tab in `fileLine` – Jacob Boertjes Jul 12 '18 at 17:17
  • Can this be done with the use of a split function? maybe something like: String name = scanner.next(); & String species= scanner.next(); ? – Melissa Stewart Jul 12 '18 at 17:28
  • 1
    You can - the `.split()` function is pretty much an abstraction for using the `.find()` and `.substring()` functions a bunch. Using `scanner.next()` would be difficult, though, because it wouldn't discriminate between different kinds of whitespace (and, for example, "Golden Eagle" would be separated into two tokens, which is not what you want). If you go that route, you'd need to [set the scanner's delimiters](https://stackoverflow.com/questions/28766377/how-do-i-use-a-delimiter-in-java-scanner) first. I recommend using `.split()`, though, as it's how this kind of problem is usually solved – Green Cloak Guy Jul 12 '18 at 17:49
0

You can simply use Scanner.next to read your file (here I used a String that match what you could find in the file)

Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern

String data = "Bird\tGolden    Eagle \t Eddie\nMammal \t Tiger  Tommy";
Scanner scanner = new Scanner(data);

while (scanner.hasNext()) {
    System.out.println("Animal: " + scanner.next());
}
scanner.close();

Output :

Animal: Bird
Animal: Golden
Animal: Eagle
Animal: Eddie
Animal: Mammal
Animal: Tiger
Animal: Tommy

This will used the delimiter from Scanner as defined in the class

A Scanner breaks its input into tokens using a delimiter pattern, which by default matches whitespace

And we can see the default value using

System.out.println(scanner.delimiter());

\p{javaWhitespace}+

AxelH
  • 13,322
  • 2
  • 21
  • 50