1

I want to create three methods which I can use to sort an ArrayList, which reads a list of countries from a text file by the name of the country (alphabetically), the amount of habitants and the size of the country. I know how to sort them by the names but I am lost on how to sort by habitants and sizes.

This is how the text file is structured; name of country, habitants, size and capital.

Belgien     10584534   30528    Bryssel
Bosnien     4590310    51129    Sarajevo    
Cypern      854000     9250     Nicosia
Serbien     7276195    77474    Belgrad

I've made a method which reads the file and sorts it with Collections.sort(), but as stated earlier I dont know how to even begin on the other two methods.

My code so far:

public class Land {
    static boolean valid = true;

    public static boolean sortNames() {
        File file = new File("europa.txt");
        ArrayList<String> list = new ArrayList<String>();
        try{
            Scanner scan = new Scanner(file);
            while(scan.hasNextLine()){
                list.add(scan.nextLine());
            }
            scan.close();
        }
        catch (FileNotFoundException e) {
            e.printStackTrace();}
        ListIterator iterator = list.listIterator();
        Collections.sort(list);

        System.out.println("Country:       Inhabitants: Size:       Capital: \n");
        for (String element : list) {
            System.out.println(element);
        }

        return valid;
    }

    public static void main(String[] args) {
        System.out.print("\n" + sortNames());
    }
}

The code as it is now prints:

Country:       Inhabitants: Size:       Capital:
Albanien        3581655    28748        Tirana
Belgien         10584534   30528        Bryssel
Bosnien         4590310    51129        Sarajevo
jossann
  • 11
  • 2
  • 1
    You need to introduce a class called something like `Country` which has a `name`, `inhabitants`, `size` and `capital`. When you read a `nextLine` you need to split that line into the different data components, construct a `Country` instance from that and put that into a `ArrayList`. Then you can sort that list by referring to https://stackoverflow.com/q/2784514/2442804 – luk2302 Apr 09 '19 at 13:08
  • 1
    The main problem is your design: You are reading every line just as a simple String. To actually do something usefull with that data you would first need to create a more usefull Data structure and create a custom class that holds the country name, inhabitants, size and capital as seperate fields. – OH GOD SPIDERS Apr 09 '19 at 13:08
  • Finally a comparator or just extend the comparable. – Aniket Sahrawat Apr 09 '19 at 13:14

2 Answers2

3

Don't just read and store the lines as a whole, but split them up in fields and create decent 'Country' objects. Store these objects in a List. You can use the Collections.sort(list, comparator) to sort your countries based on different implemetations based on the fields of your country objects.

public static boolean sortNames() {
    File file = new File("europa.txt");
    ArrayList<Country> list = new ArrayList<Country>();
    try {
        Scanner scan = new Scanner(file);
        while(scan.hasNextLine()){
            String line = scan.nextLine();
            Country country = new Country();
            // Split the line and fill the country object
            list.add(country);
        }
        scan.close();
    }
    catch (FileNotFoundException e) {
        e.printStackTrace();
    }
    Collections.sort(list, new Comparator<Country>(){
      @Override
      public int compare(Country c1, Country c2) {
        return c1.getName().compareTo(c2.getName());
      }
    });
    // You can create different comparators and sort based on inhabitants, capital, or even a combination of fields...

    System.out.println("Country:       Inhabitants: Size:       Capital: \n");
    for (Country element : list) {
        System.out.println(element.getName() + ", " + element.getInhabitants() /*etc*/);
    }

    return valid;
}

public class Country {
  private String name;
  private int inhabitants;
  private int size;
  private String capital;

  // constructor
  // getters and setters
}
TheWhiteRabbit
  • 1,253
  • 1
  • 5
  • 18
2

For java 8 and above:

You should split the rows up and create Country objects with fields:

nameOfCountry, habitants, size, capital

After that you could use the List.sort() method as follows:

list.sort(Comparator.comparing(Country::getNameOfCountry)
                        .thenComparing(Country::getHabitants)
                        .thenComparing(Country::getSize));
Dave94
  • 41
  • 1
  • 6
  • 2
    This approach is far better than another answer with only one problem: OP does not has a `class Country`. – Aniket Sahrawat Apr 09 '19 at 13:27
  • What would be the best way to split the rows? I have never done that before so i dont know what that code would look like – jossann Apr 09 '19 at 14:26
  • Use String.split() function, e.g.: scan.nextLine().split("/t")[0]. This will return with the countries name. "/t" means split the line by tabulators. You can change it to anything (space, semicolon, etc.). – Dave94 Apr 09 '19 at 14:37