Sort on an object [java]

Asked

Viewed 76 times

0

Cheers guys, I’m having a doubt about a project I’m doing just to learn more about the language. following, I have a txt file in which I have to read it and separate the different contents (name, Parents , heightdepth, accessibility, hostility, kmFromLondon, temperature, wonderValue and a fact about the site) then output it neatly by the "rating" of the site hospitality.

What’s in the file is this:

Amazonia,Brazil,60,10,10,8100,30,4,The Amazon rainforest occupies some 5.5 million square kilometres of South America.
Iguassu Falls,Brazil|Argentina,82,11,50,10064,25,4,Two hundred and seventy waterfalls flow along nearly 3 kilometres of rivers.
Niagra Falls,USA|Canada,50,18,69,5804,20,4,Adventurous tourists can take a cruise on the river below into the falls' mist.
Giant's Causeway,Northern Ireland,12,19,17,592,15,2,Legend has it that is is a former 'walkway' to Scotland.
Great Barrier Reef,Australia,60,10,10,15292,28,4,Over 30 species of whale and 15000 species of fish live here.
Mount Everest,Tibet|Nepal,8840,7,95,7424,-10,4,The highest mountain on Earth is located in the Himalayas.
Mount Vesuvius,Italy,1281,18,95,1630,30,1,The only volcano in mainland Europe to have erupted in the last 100 years.
Old Faithful,USA,55,14,65,7432,118,2,Over half of the world's geysers are located in Yellowstone national park.
Sahara Desert,African Union,3445,14,84,3800,35,3,Covers part of North Africa and is almost the same size as the USA.
Great Rift Valley,African Union,1470,14,12,5887,25,4,The valley was formed by activity between tectonic plates 35 million years ago.
Gobi Desert,Mongolia|China,2700,9,84,7279,30,3,The desert has been the location of many fossil finds.
Ngorongoro Crater,Tanzania,610,14,19,5804,30,2,Home to almost 25000 animals including masses of flamingoes around Lake Magadi.
Perito Morena Glacier,Argentina,60,9,82,13230,-5,3,The 5 kilometre wide glacier is well known for its process of rupturing.
Mount Fuji,Japan,3776,13,69,8671,25,2,Although classed as active its last eruption was in 1707.
Mont Blanc,Italy|France,4808,18,85,808,0,2,The highest mountain in Europe and a popular skiing destination.
The Dead Sea,Israel|Jordan,418,13,91,3666,25,1,The lowest point on the surface of the Earth and is really two large lakes.
The Matterhorn,France|Italy|Switzerland,4478,17,85,840,-5,2,Not the highest mountain in the Alps but perhaps the most breathtaking.
Uluru,Australia,346,10,70,14993,35,4,A massive monolith made from sandstone infused with minerals that reflect in the sunlight.
Lake Baikal,Russia,1637,8,55,6613,-30,2,An immense depth of 1637 metres and contains 20% of the worlds fresh water.
Kilauea,The Hawaiian Islands,1247,9,65,11783,30,3,Hawaiian legend considers the island to be the home of a volcano goddess.
Guilin Caves,China,220,9,16,9101,30,2,The people of Guilin have had to take refuge in them during times of conflict.
Giant Sequoia,USA,84,15,2,8570,30,2,The largest species of tree found only in California.
Mount Erebus,Antarctica,3794,4,95,17059,-49,3,Has continually erupted since 1972 and has a permanent lava lake within its summit.
Grand Canyon,USA,1600,15,80,8296,30,4,A vast and breathtaking spectacle stretching across the Arizona desert.

then next, I created an object that way,

public class Wonders {
    String name;
    List countries = new ArrayList();
    int heightDepth;
    int accessibility;
    int hostility;
    int kmFromLondon;
    int temperature;
    int wonderValue;
    String fact;
    List compare = new ArrayList();

and then

        String unftxt[];
        unftxt = new String[24];
        Wonders w[] = new Wonders[unftxt.length];



        try (Scanner sfile = new Scanner(new File(fName))) {

           while(sfile.hasNextLine()){
               unftxt[ctrl] = sfile.nextLine();
               ctrl++;
           }//end while .hasnextLine()
        }//try

        for(int i=0;i<unftxt.length;i++){
            String[] parts = unftxt[i].split(",");
            w[i] = new Wonders();
            w[i].name = parts[0];
            w[i].countries.add(Arrays.toString(parts[1].split("\\|")));
            w[i].heightDepth = Integer.parseInt(parts[2]);
            w[i].accessibility = Integer.parseInt(parts[3]);
            w[i].hostility = Integer.parseInt(parts[4]);
            w[i].kmFromLondon = Integer.parseInt(parts[5]);
            w[i].temperature = Integer.parseInt(parts[6]);
            w[i].wonderValue = Integer.parseInt(parts[7]);
            w[i].fact = parts[8];

        }

I am new in the programming, I am a few hours stopped in this problem, my question is: as I will order the array of object w by the hospitality and if the hospitality is equal by the hospitality and by the country

    1. Work with lists instead of arrays, they are more flexible. 2) search the API documentation for a method sort who receives a Comparator and learn how to create one to use in this method (or better yet, make your class Wonders implement the interface Comparable).

1 answer

2


An alternative is your class Wonders implement the interface Comparable. She will force you to implement the method compareTo(T o).

The method compareTo(T o) is called as follows:

int result = object.compareTo(otherObject)

This way the return will be:

  • -1 if the left object is smaller
  • 0 if the objects are equal
  • 1 if the left object is larger

A way to implement in your class this method would be:

import java.util.ArrayList;
import java.util.List;
import java.util.Objects;

@SuppressWarnings("rawtypes")
public class Wonders implements Comparable<Wonders> {

  private String name;
  private List   countries = new ArrayList();
  private int    heightDepth;
  private int    accessibility;
  private int    hostility;
  private int    kmFromLondon;
  private int    temperature;
  private int    wonderValue;
  private String fact;
  private List   compare   = new ArrayList();

  @Override
  public int compareTo(Wonders other) {
    Objects.requireNonNull(other, "Outro objeto não pode ser nulo.");

    Integer thisHostility = this.hostility;
    Integer otherHostility = other.getHostility();

    int resultHostility = thisHostility.compareTo(otherHostility);

    if (resultHostility == 0) {

      if (Objects.nonNull(name) && Objects.isNull(other.name)) {
        return -1;
      } else if (Objects.isNull(name) && Objects.nonNull(other.name)) {
        return 1;
      } else {
        return name.compareTo(other.name);
      }
    } else {
      return resultHostility;
    }
   }
      ... // getters e setters aqui
    }

This compareTo(T o) which I have implemented, order first by hostility, and if they are equal in order name.

Note: I did not order the second field by country, because you have a list of countries. Then I was in doubt how you would like to order by listing.

Then you have to change your array Wonders by a TreeSet<Wonders>. The TreeSet will guarantee you the ordering of the elements from the method compareTo(T o) implemented in your class Wonders.

String unftxt[];
unftxt = new String[24];
Set<Wonders> wonders = new TreeSet<>();

try (Scanner sfile = new Scanner(new File(""))) {
  int ctrl = 0;

  while (sfile.hasNextLine()) {
    unftxt[ctrl] = sfile.nextLine();
    ctrl++;
  } 
}  catch (Exception e) {
  e.printStackTrace();
}

Wonders wonder;

for (int i = 0; i < unftxt.length; i++) {
  String[] parts = unftxt[i].split(",");
    wonder = new Wonders();
    wonder.setName(parts[0]);
    wonder.setCountries(Arrays.asList((parts[1].split("\\|")))); 
    wonder.setHeightDepth(Integer.parseInt(parts[2]));
    wonder.setAccessibility(Integer.parseInt(parts[3]));
    wonder.setHostility(Integer.parseInt(parts[4]));
    wonder.setKmFromLondon(Integer.parseInt(parts[5]));
    wonder.setTemperature(Integer.parseInt(parts[6]));
    wonder.setWonderValue(Integer.parseInt(parts[7]));
    wonder.setFact(parts[8]);
}

for (Wonders w : wonders) {
  System.out.println(String.format("%s - %s", w.getHostility(), w.getName()));

}

  • To a field int (or any other primitive type), it makes no sense to check if it is null - in the case of hostility, will be made the autoboxing to Integer, and it will never be null (because int, for default, is initialized with zero, so you will always have a value - see). And within the class you don’t need to use the getter to access members of other. In short, the comparison between hostility could come down to int resultHostility = Integer.compare(hostility, other.hostility). And to access the name, you can use other.name (doesn’t need the getter).

  • You’re right, I created the wrapper by so I could use the compareTo(T t) but I forgot I was with primitives at the time of comparison. Thanks for warning, I edited the comment.

  • You also don’t need to assign the value to a Integer, this class has a static method that compares two values int directly: Integer.compare(hostility, other.hostility) - https://docs.oracle.com/javase/8/docs/api/java/lang/Integer.html#compare-int-int-

  • This one I’ve never really used... can save a few lines using it.

  • It’s not about saving lines, it’s about doing things you don’t need. In this case, when doing Integer thisHostility = this.hostility; you are creating an object Integer unnecessary (apart from the fact that occupy more memory than a int), because you can do the same thing directly with values int, then you have no reason to use the Integer there. Perhaps the question of memory is insignificant in such a small program, but the main issue is clearer, concise code, no unnecessary lines: https://answall.com/a/400495/112052

  • Anyway, +1 for the answer :-)

  • Perfect, I fully agree with your note. Thank you

  • Thanks guys helped me a lot +1

Show 3 more comments

Browser other questions tagged

You are not signed in. Login or sign up in order to post.