Search code examples
javatext-filesjava.util.scanner

Sorting a text file in Java per line


I'm a newbie in Java and I have a file where every first line is the title of every second. For example the text file looks like this:

John Holm

blue

Anna Karina

orange

etc...

where every first line is the name of a person and every second is their favourite colour. Now I would like to use the information to for example find what is for example John Holm's favourite colour or change his favourite colour to green instead. How do I best access the data?

I tried with scanner to see all the lines where blue reoccurs, but I cannot get the code to write the previous line.

Should I split the text file into a table with name and favColour as columns or is there a way to assign the previous line to the next line as a name in Java? I also thought of splitting the file every second line. However, I am unsure which solution would be most efficient. Would be very thankful for some insights!


Solution

  • I think a solution would be to create an object containing the properties of your characters (their name and their favourite colour). So, you can create a class named like how you want to name your object (let's call it Person), and set the name and the favourite colour as attribute of your Person object:

    public class Person {
    
    private String name;
    private String favColour;
    
        public Person(String name, String favColour) { // Constructor of your object
            this.name = name; // Setting name
            this.favColour = favColour; // Setting favourite colour
        }
    
    }
    

    Now, create a main method to read your file, store the values into two lists, one containing the names, the other the colours, and then creating as many Person objects as you need:

    public class Main {
    
    public static void main(String[] args) throws IOException {
        
            File file = new File("src/wherever you stored it"); // Enter the file path as a String here
            Scanner scanner = new Scanner(file); // Create a scanner that will read your file
            List<String> names = new ArrayList<>(); // List that will contain the names read from the scanner 
            List<String> colours = new ArrayList<>(); // By the way don't forget to import *java.util.List* and *java.util.ArrayList* if your IDE doesn't do it automatically
            int index = 0; // The index that'll know whether you store a name or a colour
            try {
                while(scanner.hasNext()) { // While the scanner still reads something from the file
                    if(index%2==0) { // If the index is even
                        names.add(scanner.next()); // Add the line to the names list
                        index++;
                    } else {
                        colours.add(scanner.next()); // Else add it to the colours list
                        index++;
                    }
                }
            } catch (Exception e) { // Don't forget to import *java.io.IOException*
                System.err.println("Error: " + e.getMessage()); // You can write a custom message that will appear in your console if there's an error, e.g. if the program can't find your file
            }
            scanner.close(); // Close your scanner
            // Now you can create a new Person object
            Person p1 = new Person(names.get(0), colours.get(0)); // Create a Person object called p1, with the first element (index 0) of names and colours lists as attributes
            System.out.println(p1); // Print your Person
        }
    
    }
    

    Almost done, the last line must print some weird string. If you want to print your Person properly, you have to override the toString() method of your object:

    // In the Person class:
    @Override
    public String toString() {
        return "Name: " + this.name + "\nFavourite colour: " + this.favColour;
    }
    

    Now try again and you'll see the console prints properly what you want to see. In the case of the example you gave, your console should print:

    Name: John Holm

    Favourite colour: blue

    You can create as many Person objects as you want, and maybe store them into a list as well.

    To make this simpler, you can create a function in your Person class:

    public static Person newPerson(int i, List<String> names, List<String> colours) {
            return new Person(names.get(i), colours.get(i));
        }
    

    And you can call it in your main:

    Person p2 = Person.newPerson(1, names, colours);
    

    You can now create a method that will create new Person objects from this function, and store them into a list or whatever you want.

    To set a value, you'll have to create setters in your Person class, in order to modify the private characteristics of your Person from outside the Person class:

    public void setName(String name) {
        this.name = name;
    }
    

    You can do the same with the colour:

    public void setFavouriteColour(String colour) {
        this.favColour = colour;
    }
    

    And now, you can call these methods from your main:

    p1.setName("John Doe");
    p1.setFavouriteColour("green");
    

    You can also create a method to combine both setters:

    public void setPerson(String name, String colour) {
        this.setName(name);
        this.setFavouriteColour(colour);
    }
    

    By the way if you need these values at some point, you can also create a getter along with your setter:

    public String getName() {
        return this.name;
    }
    

    Feel free to ask anything you didn't understand or think is wrong :)