# Sorting a Vector by Fields of Objects Stored in it

• 06-09-2013, 08:37 AM
Willriker
Sorting a Vector by Fields of Objects Stored in it
Hello all!

I am going back to relearn Java. I never really got it in college. So, I am going back through my old texts, doing the exercises to get back into it. The good news is that, this time through, things are making much more sense. Until now...

I have a vector filled with objects of type Address. Each of the address objects contains three fields: Name, Date of Birth, and Address. I want to provide three methods. Each of these methods will order the vector by a field. But, I am stuck.

My initial thought was to perform a bubble sort. Well, that is what i found people call what i wanted to do during my unsuccessful attempts to research an answer to my own question. Apparently, bubble sorts are frowned upon... everywhere I look, people talk about implementing comparable and comparator. These are new to me. Despite that, i tried to implement them to sort my vector. The operative word being 'Tried'.

I will include the code I am using below, starting with the class that I am using to construct the Vector of addresses. This is also the class that i was attempting to put my comparable/comparator. At first, I am trying to sort by the Date of Birth (dob). That segment is at the bottom of this segment of code.

Code:

```package Learning; import java.util.*; public class AddressBook implements Comparable<Address>{                 private Vector <Address>v;//cast the vector so its elements are of type <Address>                 /* Constructor requires an object of type Address         * make a vector object, all elements are of type <Address>         * initial capacity is 1, increments by 2 as needed         */         public AddressBook(Address a) {                 v = new Vector <Address> (1,2);                 v.add(0, a);                         }                 //add an element to the vector, at v.size()+1, its capacity will automatically increment by 2 if needed.         public void addAddress(Address a) {                 v.add(0, a);         }                 //getter Methods         public String getName(int index) {                 Address a = v.get(index);                 return a.getName();         }                 public String getDOB(int index) {                 Address a = v.get(index);                 return a.getDOB();         }                 public String getAddress(int index) {                 Address a = v.get(index);                 return a.getAddress();         }                 public int getSize() {                 return v.size();         }                 //toString Method         public String toString(int index) {                 return getName(index) + " " + getDOB(index) + " lives at "+ getAddress(index);         }                 //sorts by DOB         @Override         public int compareTo(Address other) {                 return this.dob.compareTo(other.getDOB());         } }//end of class```
in this class I define the objects that I insert into the vector (above):
package Learning;

Code:

```import java.util.Date; public class Address {         private Name obj;         private String name;         private Date obj2;         private String dob;         private String address;         //Constructor         public Address(String first, String middle, String middleInitial, String last, String address, int yearDOB, int monthDOB, int dayDOB) {                 obj = new Name(first, middle, middleInitial, last);                 name=obj.toString();                 obj2= new Date(yearDOB, monthDOB, dayDOB);                 dob= "(" + Integer.toString(obj2.getMonth()) + " " + Integer.toString(obj2.getDate())+ ", "                                 + Integer.toString(obj2.getYear()) + ")";                 this.address=address;         }                 //getter methods         public String getName() {                 return name;         }                 public String getDOB() {                 return dob;         }                 public String getAddress() {                 return address;         }                 //setter methods         //either middle or middle initial must be a null value         public void setName(String first, String middle, String middleInitial, String last) {                 obj.setFirst(first);                 obj.setMiddle(middle);                 obj.setMiddleInitial(middleInitial);                 obj.setLast(last);                 name=obj.toString();         }                 public void setDOB(int yearDOB, int monthDOB, int dayDOB) {                 obj2.setYear(yearDOB);                 obj2.setMonth(monthDOB);                 obj2.setDate(dayDOB);                 dob="(" + Integer.toString(obj2.getMonth()) + " " + Integer.toString(obj2.getDate()) + ", "                                 + Integer.toString(obj2.getYear()) + ")";         }                 public void setAddress(String address) {                 this.address=address;         }                 //toString method         public String toString() {                 return getName() + ", " + getDOB() + " lives at " + getAddress();         } }//end of class```
The name field in the Address object uses Class Name that I wrote before:

Code:

```package Learning; // Testing of this Class is in Chapter3Exercises.java public class Name {         private String first;         private String middle;         private String middleInitial;         private String last;         private boolean surnameFirst = false;                 //constructor for instances, objects, of type Name         public Name(String a, String b, String c, String d) {                 first = a;                 middle = b;                 middleInitial = c;                 last = d;         }                         //getter methods         public String getFirst() {                 return first;         }                 public String getMiddle() {                 return middle;         }                 public String getMiddleInitial() {                 return middleInitial;         }                 public String getLast() {                 return last;         }                 public boolean getSurnameFirst() {                 return surnameFirst;         }                 //setter methods         public void setFirst(String e) {                 first = e;         }                 public void setMiddle(String f) {                 middle = f;         }                 public void setLast(String g) {                 last = g;         }                 public void setMiddleInitial(String h) {                 middleInitial = h;         }                 public void setSurnameFirst(boolean i) {                 surnameFirst = i;         }                 //toString method         public String toString() {                 if (middle==null && middleInitial==null && surnameFirst==false) {                         return getFirst() + " " + getLast();                 }                 if (middle==null && middleInitial==null && surnameFirst==true) {                         return getLast() + ", " + getFirst();                 }                 if (middle==null && middleInitial!=null && surnameFirst==false) {                         return getFirst() + " " + getMiddleInitial() + ". " + getLast();                 }                 if (middle==null && middleInitial!=null && surnameFirst==true) {                         return getLast() + ", " + getFirst() + " " + getMiddleInitial() + ".";                 }                 if (middle!=null && middleInitial==null && surnameFirst==false) {                         return getFirst() + " " + getMiddle() + " " + getLast();                 }                 if (middle!=null && middleInitial==null && surnameFirst==true) {                         return getLast() + ", " + getFirst() + " " + getMiddle();                 } else {                         return "You must enter at least a first name and a surname.";                 }         } }```
I am hoping someone can point out how to do this one. Actually, I'm really hoping someone can take the time to explain how to sort by dob. Then i can go and try to sort by the other fields using what i learned.
• 06-09-2013, 10:03 AM
JosAH
Re: Sorting a Vector by Fields of Objects Stored in it
Normally the interface Comparable<X> is only implemented by a class X (or subclasses thereof); use the Comparator<X> instead, so any class can compare objects X. You have to have three implementations, one for each sort criterium.

kind regards,

Jos
• 06-09-2013, 06:03 PM
Willriker
Re: Sorting a Vector by Fields of Objects Stored in it
Thank you for taking the time to reply, but I must be misunderstanding your advice. When I replace implements Comparable (in class AddressBook) it wants a compare() method instead of compareTo(). And since I am dealing with strings, dont I need to use the compareTo() method?
• 06-09-2013, 06:34 PM
JosAH
Re: Sorting a Vector by Fields of Objects Stored in it
Quote:

Originally Posted by Willriker
Thank you for taking the time to reply, but I must be misunderstanding your advice. When I replace implements Comparable (in class AddressBook) it wants a compare() method instead of compareTo(). And since I am dealing with strings, dont I need to use the compareTo() method?

Yep, if you want your class to implement the Comparator<X> interface, your class has to implement the compare(X a, X b) method; don't ask me why those names are different, but who cares? If you want to compare two Addresses by their name, say, all you have to do is create a small class like this:

Code:

```public class AddressByName implements Comparator<Address> {   public int compare(Address a, Address b) {       return a.getName().compareTo(b.getName());   } }```
Similar reasoning applies with small classes that compare Adresses by other fields. Note that this little class uses the compareTo( ... ) method of the String class to do the actual comparison.

kind regards,

Jos
• 06-11-2013, 10:02 PM
Willriker
Re: Sorting a Vector by Fields of Objects Stored in it
Sorry I have not gotten back to you. I have been trying to get this to work. I got rid of the comparator stuff from class AddressBook (above) and created a new class to hold them, along with the corresponding getter methods. I am putting it below this line:

Code:

```package Learning; import java.util.Comparator; public class AddressBookComparator {                 /* setting up comparators         * these comparators will compare each argument to the next one in the series.         * the comparator will continue to loop until all comparisons return 0 or less         * if o1<o2 a value of -1 is returned         * if o1=o2 a value of 0 is returned         * if o1>o2 a value of 1 is returned         */         public class CompareByName implements Comparator<Address> {                 @Override                 public int compare(Address o1, Address o2) {                         return o1.getName().compareToIgnoreCase(o2.getName());                 }         }         public class CompareByDOB implements Comparator<Address> {                 @Override                 public int compare(Address o1, Address o2) {                         return o1.getDOB().compareTo(o2.getDOB());                 }         }                 public class CompareByAddress implements Comparator<Address> {                 @Override                 public int compare(Address o1, Address o2) {                         return o1.getAddress().compareToIgnoreCase(o2.getAddress());                 }         }                 //getter methods         public Comparator<Address> getCompareByName() {                 return new CompareByName();         }                 public Comparator<Address> getCompareByDOB() {                 return new CompareByDOB();         }                 public Comparator<Address> getCompareByAddress() {                 return new CompareByAddress();         } }//End of Class```
So, now I try to call this in my main method. But, it wont compile.

Code:

```package Learning; import java.util.Collections; import java.util.List; public class Chapter3Exercises {         /**         * @param args         */         public static void main(String[] args) {                //testing instances, objects, of type AddressBook                 Address obj13 = new Address("E", null, "S", "Capo", "31 Ridge Road", 1962, 3, 10);                 Address obj14 = new Address("M", null, "L", "Capo", "3 Wood Avenue", 1760, 1, 30);                 Address obj15 = new Address("J", "David", null, "Capo", "31 Ridge Road", 2011, 5, 2);                 AddressBook obj16 = new AddressBook(obj13);                 obj16.addAddress(obj14);                 obj16.addAddress(obj15);                 for (int index=0; index<obj16.getSize(); index++) {                         System.out.println(obj16.toString(index));                 }                 AddressBookComparator comparers = new AddressBookComparator();                 Collections.sort(obj16.getName(0), comparers.getCompareByName());                 for (int index=0; index<obj16.getSize(); index++) {                         System.out.println(obj16.toString(index));                 }                         }//End of Class```
I think the Collections.sort line is giving me an issue. If I enter obj16.getName(), for the first parameter, I am asked for an index. That isn't much of a surprise because the getter function i wrote required an input. I guess I should start at 0. So, I place 0 as the index. Once i do this, then the word sort gets red lined. with the error message

"The method sort(List<T>, Comparator<? super T>) in the type Collections is not applicable for the arguments (String, Comparator<Address>)"

I don't know.. I think i am heading in the correct direction though.

Its my understanding that while comparator will give the 1, 0, or -1 value, the Collections.sort is the line that will actually put things into the correct order.
• 06-12-2013, 11:35 PM
Willriker
Re: Sorting a Vector by Fields of Objects Stored in it
• 06-14-2013, 01:45 AM
Willriker
Re: Sorting a Vector by Fields of Objects Stored in it
this is becoming very frustrating :/

i cant get rid of this error message:
Quote:

The method sort(List<T>, Comparator<? super T>) in the type Collections is not applicable for the arguments (String, Comparator<Address>)
I have a red squiggle under the word sort in my main (line 22)
• 06-14-2013, 06:32 AM
DarrylBurke
Re: Sorting a Vector by Fields of Objects Stored in it
If you're human, please use meaningful variable names. Names like obj13 / 14 / 15 / 16 may be fine for a discussion between bots.

Have you read the API for Collections#sort(...)? what is the Type of the first parameter to that method? Is the parameter you provide of that Type?

db
• 06-15-2013, 01:20 AM
Willriker
Re: Sorting a Vector by Fields of Objects Stored in it
I thought that vectors implement the list interface. Thus making it a part of the collections group. And, sort requires a List. Now I dont know why there is an issue.
• 06-15-2013, 09:59 AM
JosAH
Re: Sorting a Vector by Fields of Objects Stored in it
Yep, a Vector implements the List interface but an obj16.getName(0) doesn't and that's what you're passing to the sort method.

kind regards,

Jos
• 06-15-2013, 04:18 PM
Willriker
Re: Sorting a Vector by Fields of Objects Stored in it

Ill post the code below for people who want to search before asking. Thank you, once again, for pointing me in the right direction.

Including this class, just for reference, so anyone can see what each individual address entry into the vector looks like.
Code:

```package Learning; import java.util.Date; public class Address {         private Name obj;         private String name;         private Date obj2;         private String dob;         private String address;                 /*Constructor*/         public Address(String first, String middle, String middleInitial, String last, String address, int yearDOB, int monthDOB, int dayDOB) {                 obj = new Name(first, middle, middleInitial, last);                 name=obj.toString();                 obj2= new Date(yearDOB, monthDOB, dayDOB);                 dob= "(" + Integer.toString(obj2.getMonth()) + " " + Integer.toString(obj2.getDate())+ ", "                                 + Integer.toString(obj2.getYear()) + ")";                 this.address=address;         }                 //getter methods         public String getName() {                 return name;         }                 public String getDOB() {                 return dob;         }                 public String getAddress() {                 return address;         }                 //setter methods         //either middle or middle initial must be a null value         public void setName(String first, String middle, String middleInitial, String last) {                 obj.setFirst(first);                 obj.setMiddle(middle);                 obj.setMiddleInitial(middleInitial);                 obj.setLast(last);                 name=obj.toString();         }                 public void setDOB(int yearDOB, int monthDOB, int dayDOB) {                 obj2.setYear(yearDOB);                 obj2.setMonth(monthDOB);                 obj2.setDate(dayDOB);                 dob="(" + Integer.toString(obj2.getMonth()) + " " + Integer.toString(obj2.getDate()) + ", "                                 + Integer.toString(obj2.getYear()) + ")";         }                 public void setAddress(String address) {                 this.address=address;         }                 //toString method         public String toString() {                 return getName() + ", " + getDOB() + " lives at " + getAddress();         } }//end of class```
This class holds ALL of my comparators, one comparator for each sort I want to perform. It also holds a getter method for each comparator.
Code:

```package Learning; import java.util.Comparator; public class AddressBookComparator {                 /* setting up comparators         * these comparators will compare each argument to the next one in the series.         * the comparator will continue to loop until all comparisons return 0 or less         * if o1<o2 a value of -1 is returned         * if o1=o2 a value of 0 is returned         * if o1>o2 a value of 1 is returned         */         public class CompareByName implements Comparator<Address> {                 @Override                 public int compare(Address o1, Address o2) {                         return o1.getName().compareToIgnoreCase(o2.getName());                 }         }         public class CompareByDOB implements Comparator<Address> {                 @Override                 public int compare(Address o1, Address o2) {                         return o1.getDOB().compareTo(o2.getDOB());                 }         }                 public class CompareByAddress implements Comparator<Address> {                 @Override                 public int compare(Address o1, Address o2) {                         return o1.getAddress().compareToIgnoreCase(o2.getAddress());                 }         }                 //getter methods         public Comparator<Address> getCompareByName() {                 return new CompareByName();         }                 public Comparator<Address> getCompareByDOB() {                 return new CompareByDOB();         }                 public Comparator<Address> getCompareByAddress() {                 return new CompareByAddress();         } }//End of Class```
This is the class that holds the vector of address's. It holds getter/add/ToString/ and now the sort procedures for each type of sort I want to have available to the main method.
```package Learning; import java.util.*; public class AddressBook {                 private Vector <Address>v;//cast the vector so its elements are of type <Address>                 /* Constructor requires an object of type Address         * make a vector object, all elements are of type <Address>         * initial capacity is 1, increments by 2 as needed         */         public AddressBook(Address a) {                 v = new Vector <Address> (1,2);                 v.add(0, a);                         }                 //add an element to the vector, at v.size()+1, its capacity will automatically increment by 2 if needed.         public void addAddress(Address a) {                 v.add(0, a);         }                 //getter Methods         public String getName(int index) {                 Address a = v.get(index);                 return a.getName();         }                 public String getDOB(int index) {                 Address a = v.get(index);                 return a.getDOB();         }                 public String getAddress(int index) {                 Address a = v.get(index);                 return a.getAddress();         }                 public int getSize() {                 return v.size();         }                 //toString Method         public String toString(int index) {                 return getName(index) + " " + getDOB(index) + " lives at "+ getAddress(index);         }                 //sorting procedure methods         public void sortByName() {                 AddressBookComparator comparators = new AddressBookComparator();                 Collections.sort(v, comparators.getCompareByName());                        }                 public void sortByDOB() {                 AddressBookComparator comparators = new AddressBookComparator();                 Collections.sort(v, comparators.getCompareByDOB());         }                 public void sortByAddress() {                 AddressBookComparator comparators = new AddressBookComparator();                 Collections.sort(v, comparators.getCompareByAddress());         } }//end of class```
```                //testing instances, objects, of type AddressBook                 Address obj13 = new Address("E", null, "S", "Capo", "31 Ridge Road", 1962, 3, 10);                 Address obj14 = new Address("M", null, "L", "Capo", "3 Wood Avenue", 1760, 1, 30);                 Address obj15 = new Address("J", "David", null, "Capo", "31 Ridge Road", 2011, 5, 2);                 AddressBook obj16 = new AddressBook(obj13);                 obj16.addAddress(obj14);                 obj16.addAddress(obj15);                 for (int index=0; index<obj16.getSize(); index++) {                         System.out.println(obj16.toString(index));                 }                 obj16.sortByName();                 for (int index=0; index<obj16.getSize(); index++) {                         System.out.println(obj16.toString(index));                 }                 obj16.sortByDOB();                 for (int index=0; index<obj16.getSize(); index++) {                         System.out.println(obj16.toString(index));                 }                 obj16.sortByAddress();                 for (int index=0; index<obj16.getSize(); index++) {                         System.out.println(obj16.toString(index));                 }```