Question

I finally understood the various possibilities of Comparable from java.util.Collections;

I can order an object, for example "Beer" with attributes float content, String name and String origin in any order that I want, combining them how I want.

Now the question: I have the following classes (code provided last):

  • Building()
  • Address();

Building can be one of three types, for example Dwelling, House, Bungalow.

Now, task is "to sort all buildings, first by the city (ascending), second by the street (ascending) and then by the street number (ascending).

Normally I would simply sort the list first by city, then by street and then by number. Of course after the first sort its solution would get mixed up by the following sorts.

Thats why I searched the net and found Comparable.

Thing is: It did work with the beer example, but does not with the address. Cause it is implemented as an ArrayList, and as I found out, it just works for Arrays.

But even if it did, the Addresses themselves are not an Array, but part of the Object Building.

So how on god's earth is one supposed to solved this? I think I spent more than 8 hours with this cr*p, and the students are supposed to solve similiar issues within 2 - 3 hours.

Any suggestions are appreciated.

Thanks,

Neo

import java.util.List;


public abstract class Building {

private Address address;
private List<Owner> owners;


public abstract double getCostRate(double costs);

public void setAddress(Address address) {
    this.address = address;
}

public Address getAddress() {
    return address;
}

public List<Owner> getOwners() {
    return owners;
}
}

Class Address:

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.Comparator;

import de.uni_mannheim.informatik.swt.pm.extended.ComparatorCityStreetNumber;

 public class Address implements Comparable<Address> {
private String street;
private int houseNr;
private int zip;
private String city;
private String country;

public String getStreet() {
    return street;
}

public void setStreet(String street) {
    this.street = street;
}

public int getZip() {
    return zip;
}

public void setZip(int zip) {
    this.zip = zip;
}

public String getCity() {
    return city;
}

public void setCity(String city) {
    this.city = city;
}

public String getCountry() {
    return country;
}

public void setCountry(String country) {
    this.country = country;
}

public void setHouseNr(int houseNr) {
    this.houseNr = houseNr;
}

public int getHouseNr() {
    return houseNr;
}

/**
 * eclipse is able to generate the equals method automatically ;)
 */
@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (obj == null)
        return false;
    if (getClass() != obj.getClass())
        return false;
    Address other = (Address) obj;
    if (city == null) {
        if (other.city != null)
            return false;
    } else if (!city.equals(other.city))
        return false;
    if (country == null) {
        if (other.country != null)
            return false;
    } else if (!country.equals(other.country))
        return false;
    if (houseNr != other.houseNr)
        return false;
    if (street == null) {
        if (other.street != null)
            return false;
    } else if (!street.equals(other.street))
        return false;
    if (zip != other.zip)
        return false;
    return true;
}

Comparator:

 public class ComparatorCityStreetNumber implements Comparator<Address> {

public int compare(Address a1, Address a2) {

    if (a1.getCity().compareTo(a2.getCity()) == 0) {
        if (a1.getStreet().compareTo(a2.getStreet()) == 0) {
            if (a1.getHouseNr() > a2.getHouseNr()) {
                return -1;
            } else {
                return a1.getStreet().compareTo(a2.getStreet());
            }
        } else if (a1.getCity().compareTo(a2.getCity()) > 0) {

            return -1;

        } else {
            return 1;
        }
    }
    return 0;
}
 }
Was it helpful?

Solution 2

I found my mistake, it was in the last equasion. IF must not be this.getCity().compareTo(address.getCity()) = 0 but correctly has to be this.getCity().compareTo(address.getCity()) > 0

So, the whole code to sort after my criteria looks like this:

public int compareTo(Address address) {

    if (this.getCity().compareTo(address.getCity()) == 0) {
        if (this.getStreet().compareTo(address.getStreet()) == 0) {
            if (this.getHouseNr() > address.getHouseNr()) {
                return 1;
            } else {
                return -1;
            } // end house number
        } else {
            return this.getStreet().compareTo(address.getStreet());
        } //end street
    } else if (this.getCity().compareTo(address.getCity()) > 0) {
        return 1;
    } else {
        return -1;
    } //end city
}

OTHER TIPS

It looks like your Building is an abstract class, which gives you a hint that you must extend it.

Given that this is an assignment, I'm not going to do it for you. Instead, I will give you some pointers :-)

Create a Property object which extends Building, and implement the getCostRate method which returns zero for now. Either that, or make Building concrete.. My guess is that subclasses of Building are yet to come, so if that's the case, scratch that idea.

Now create a PropertyComparator implementation of the Comparator object.

Now, from the perspective of being able to determine your sort criteria, you should be able to write the simple logic to compare one Property with another Property, and their corresponding Addresses - if you want to go for gold, create an AddressComparator too - and make your BuildingComparator call the AddressComparator to compare the addresses.

Finally, if you have a collection of Property objects, put them into a TreeSet, but construct the TreeSet with your PropertyComparator.

Once it's in the TreeSet, it will be ordered according to your implementation.

Good luck!

You just need to implement compareTo(...) method and there is where you should put the Address comparison logic, that will be used when you call Collections.sort(...) method for a List<Address>object.

Example:

List<Address> l = new ArrayList<Address>();
// ... fill values in the list
Collections.sort(l);

This will use the logic from your compareTo(...) method in Address class. For example:

int compareTo(Address o) {
    return o.getCity().compareTo(this.getCity());
}

So this would be using the String implementation of compareTo(...) method for sorting the Addresses by city. And in this way you don't need to use the ComparatorCityStreetNumber class nor any other Comparator class.

For more information: http://docs.oracle.com/javase/7/docs/api/java/lang/Comparable.html#compareTo(T)


EDIT:

If your compareTo(...) method doesn't work you can always place this logic in the compare(Address a1, Address a2) method in your ComparatorCityStreetNumber class.

Then you don't need to implement Comparable anymore in your Address class nor implement compareTo(...) method there.

And then your sort call would be:

List<Address> l = new ArrayList<Address>();
// fill in the list with addresses
ComparatorCityStreetNumber c = new ComparatorCityStreetNumber();
Collections.sort(l, c);

So please try this and edit your question with your new output if you have other problems there.

For more information: http://docs.oracle.com/javase/7/docs/api/java/util/Comparator.html#compare(T, T)

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top