Results 1 to 11 of 11
  1. #1
    Willriker is offline Member
    Join Date
    Aug 2011
    Posts
    47
    Rep Power
    0

    Default 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.

    Java 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;

    Java 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:


    Java 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.

  2. #2
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,729
    Blog Entries
    7
    Rep Power
    21

    Default 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
    cenosillicaphobia: the fear for an empty beer glass

  3. #3
    Willriker is offline Member
    Join Date
    Aug 2011
    Posts
    47
    Rep Power
    0

    Default 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?

  4. #4
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,729
    Blog Entries
    7
    Rep Power
    21

    Default Re: Sorting a Vector by Fields of Objects Stored in it

    Quote Originally Posted by Willriker View Post
    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:

    Java 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
    cenosillicaphobia: the fear for an empty beer glass

  5. #5
    Willriker is offline Member
    Join Date
    Aug 2011
    Posts
    47
    Rep Power
    0

    Default 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:

    Java 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.

    Java 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.
    Last edited by Willriker; 06-12-2013 at 03:15 AM.

  6. #6
    Willriker is offline Member
    Join Date
    Aug 2011
    Posts
    47
    Rep Power
    0

    Default Re: Sorting a Vector by Fields of Objects Stored in it

    Sorting a Vector by Fields of Objects Stored in it-help-me.png

  7. #7
    Willriker is offline Member
    Join Date
    Aug 2011
    Posts
    47
    Rep Power
    0

    Default Re: Sorting a Vector by Fields of Objects Stored in it

    this is becoming very frustrating :/

    i cant get rid of this error message:
    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)

  8. #8
    DarrylBurke's Avatar
    DarrylBurke is offline Forum Police
    Join Date
    Sep 2008
    Location
    Madgaon, Goa, India
    Posts
    11,455
    Rep Power
    20

    Default 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
    If you're forever cleaning cobwebs, it's time to get rid of the spiders.

  9. #9
    Willriker is offline Member
    Join Date
    Aug 2011
    Posts
    47
    Rep Power
    0

    Default 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.

  10. #10
    JosAH's Avatar
    JosAH is offline Moderator
    Join Date
    Sep 2008
    Location
    Voorschoten, the Netherlands
    Posts
    13,729
    Blog Entries
    7
    Rep Power
    21

    Default 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
    cenosillicaphobia: the fear for an empty beer glass

  11. #11
    Willriker is offline Member
    Join Date
    Aug 2011
    Posts
    47
    Rep Power
    0

    Default Re: Sorting a Vector by Fields of Objects Stored in it

    Sorting a Vector by Fields of Objects Stored in it-its-alive.jpg

    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.
    object Address:
    Java 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.
    Object AddressBookComparator:
    Java 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.
    object AddressBook:
    Java Code:
    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

    Here is just an excerpt of the main method I use to create addresses, add them to the vector, sort the vector by field, then print out the results to the console window.
    Main:
    Java Code:
    		//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));
    		}
    Once again, thank you for helping me out.

Similar Threads

  1. Calling methods on objects stored in an array
    By Dreaming in forum New To Java
    Replies: 6
    Last Post: 10-30-2011, 01:50 AM
  2. Replies: 4
    Last Post: 09-09-2011, 04:44 AM
  3. Replies: 8
    Last Post: 08-13-2011, 07:02 PM
  4. Sorting data in a Vector
    By SBL in forum AWT / Swing
    Replies: 11
    Last Post: 11-27-2009, 04:20 AM
  5. URGENT: Sorting a vector of object by an element
    By doobybug in forum New To Java
    Replies: 1
    Last Post: 03-12-2008, 07:37 PM

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •