Page 1 of 2 12 LastLast
Results 1 to 20 of 21
  1. #1
    gcampton Guest

    Default Sorting/Searching Objects with multiple types.

    I need to implement sorting and searching using arrays.sort and binary search.
    only problem is the book I am reading really only covers simple integer array sorting, which looks fine and easy.
    But I have an array of 50+ Vehicles that need to be sorted that look like this:
    Java Code:
    	private String vRego, vMake, vModel;
    	private double vPrice;
    	private int vOdometer, vYear, vLoadLimit;
    	private VType vtype;
    	private VColor vcolor;
    	private VCondition vcondition;
    
    public Car (String vRego, VType vtype, String vMake, String vModel, VColor vcolor, double vPrice, 
    	int vOdometer, int vYear, VCondition vcondition)
    {
    	super();
            // sets and this.enum=enum etc
    }
    
    public Truck (String vRego, String vMake, String vModel, VColor vcolor, double vPrice, 
    	int vOdometer, int vYear, VCondition vcondition, int vLoadLimit)
    {
    	super();
            // sets and this.enum=enum etc
    }
    The API says that:
    sort
    public static void sort(Object[] a)
    Sorts the specified array of objects into ascending order, according to the natural ordering of its elements. All elements in the array must implement the Comparable interface. Furthermore, all elements in the array must be mutually comparable (that is, e1.compareTo(e2) must not throw a ClassCastException for any elements e1 and e2 in the array).
    This sort is guaranteed to be stable: equal elements will not be reordered as a result of the sort.

    The sorting algorithm is a modified mergesort (in which the merge is omitted if the highest element in the low sublist is less than the lowest element in the high sublist). This algorithm offers guaranteed n*log(n) performance.
    Does that mean I will run into trouble, being that car and truck have slightly different parameters?, not everything in the objects are strings therefore cannot be compared using x.compareTo(y)?

    Or will it do what I'm hoping it will and sort in alphabetical order according to the registration number strings eg. RTS-231 > ARK-823. ???

  2. #2
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    Both Car and Truck inherit from Vehicle, I presume, and does Vehicle implement Comparable<Vehicle> where the compareTo sorts by registration number? If so, I don't see a problem here.

    edit: Or you could create a Comparator<Vehicle> helper class that has a compare method that again uses Vehicle.getRegistrationNumber() (or whatever the method is called) to get registration numbers and compare them.

  3. #3
    gcampton Guest

    Default

    Ah ok thanks fubar, I kind of did notice that statement about having to implement comparable but choose to ignore it :P

    the hierarchy is as you mentioned, but I have not implemented comparable yet. And Vehicle is actually a blank class, as the Truck and Car objects have slightly different parameters that need to be in a certain order I simply implemented them each in their own class. Ill list the code at the bottom.

    I just checked the API I'm guessing it's java.util.comparator ->

    This still states that elements must be comparable just like sort, I'm not quite sure what it means by elements as I am comparing objects.

    if I have an object a that is:
    AOBJ (boolean,String,int,Double,int,String) and
    BOBJ (boolean,String,double,int,boolean,int) can these still be comparable? because the first parameter in each object is similar?
    Or does it not matter what the object actually contains, so long as it has data that can be compared... sorry I'm confused :o

    Java Code:
      private String vRego, vMake, vModel;
      private double vPrice;
      private int vOdometer, vYear, vLoadLimit;
      private VColor vcolor;
      private VCondition vcondition;
    
    public Truck (String vRego, String vMake, String vModel, VColor vcolor, double vPrice, 
    	int vOdometer, int vYear, VCondition vcondition, int vLoadLimit)
    {
    	super();
    	setVRego(vRego);
    	setVMake(vMake);
    	setVModel(vModel);
    	this.vcolor=vcolor;
    	setVPrice(vPrice);
    	setVOdometer(vOdometer);
    	setVYear(vYear);
    	this.vcondition=vcondition;
    	setVLoadLimit(vLoadLimit);
    }
    
    //--------
    public void setVRego(String vRego)
    {
        this.vRego=vRego;
    }
    
    //--------
    public String getVRego()
    {
        return vRego;
    }
        
        ...
        ...
    
    //--------
    public String toString()
    {
        return String.format("%s, %s, %s, %s, %s, %s, %s, %s, %s, %s\n",
        	this.getClass().getName(), getVRego(), getVMake(), getVModel(), vcolor,
        	getVPrice(), getVOdometer(), getVYear(), vcondition, getVLoadLimit());
    }
    all sets and gets are very standard, and exactly the same as rego,
    Car has an included VType vtype { SEDAN, COUPE, HATCH, WAGON, VAN, UTE, LIMO } which is directly after cars vRego, and does not contain load limit, while truck has load limit but does not have types.

    I'm thinking maybe I need to place 'type' at the end of the parameters, as I need to be able to handle unregistered vehicles, xxx-xxx and these need to default to the next sort, which would be make or model or something. perhaps year...

    :( :o
    Last edited by gcampton; 10-18-2009 at 07:38 AM.

  4. #4
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    For two objects to be compared, there must be a logical way to write a compare(obj1, obj2) method or a compareTo(obj2) method.

    In my mind, all vehicles are connected by, well quite simply -- vehicle, and again the key to the comparison resides here. If all vehicles have a VRego, and if this is the basis for comparison, then this should be a property of the Vehicle class, regardless of what fields Car or Truck have.

    Thus for most comparisons to work (not all!) the objects need to share a method, via either inheritance or by sharing the same interface, and the compareTo or compare methods would use this shared method to come up with an int that tells where one object ranks relative to another.

    I suppose you could try to create a Comparator that has the ability to compare two or more disparate types, perhaps by using the instanceof operator, but it smells of an abomination to me.
    Last edited by Fubarable; 10-18-2009 at 07:48 AM.

  5. #5
    gcampton Guest

    Default

    fair enough.

  6. #6
    gcampton Guest

    Default

    Cannot find symbol constructor Vehicle()

    Is the error message I get after changing it around to what it should be, also it doesn't like the private enums, as I am directly calling them from Truck and Car via toString, I thought children inherited all members, including variables, I guess I am mistaken....

    Time to read up more on heirarchy to resolve this mess... bbl

    EDIT: ignore that error ^^ realized I forgot to change ---> super();
    Last edited by gcampton; 10-18-2009 at 09:37 AM.

  7. #7
    gcampton Guest

    Default

    I have completely muffed this up now, I thought it was ok, implemented all similar parms in Vehicle() and took them out of car and truck, then it complained that enums were declared private in Vehicle, so I made them public, it still kept saying they were private, so I simply put them as private definitions of car and truck, however this caused my derived classes to overwrite rather than overload....

    Java Code:
    Car, LOLZ-01, COUPE, SKYLINE-GT, NISSAN, null, 18500.0, 134720, 2003, null
    
    Car, LISA69, HATCH, BARINA, HOLDEN, null, 9890.0, 89241, 2001, null
    
    Truck, LMF-40, MACK, Lv49, null, 65000.0, 45763, 1995, null, 5000
    
    Press ENTER to continue...
    As you can see, all areas that are enumerated except for vtype which is Car specific has come out as null.
    I'm not quite sure how to get around this unless I don't declare any enums in Vehicle() ... is there another way?

  8. #8
    gcampton Guest

    Default

    kinda fixed, I worked out how to set/get enums by trying various things until it worked, and then changing toString... Now for comparable, anybody have any examples I can use?
    Java Code:
    public void setVColor(VColor vcolor)
    {
        this.vcolor=vcolor;
    }
    public VColor getVColor()
    {
        return vcolor;
    }

  9. #9
    gcampton Guest

    Default

    As far as I can tell from the java tutorials online, comparable and comparator are part of the collection interface, and the examples given are using arrayList and tree, etc. which I have not covered yet. As far as I have read it has been stated that for data that will be changed or for array sizes that are unknown arrayList is best to use, but in other case arrays are fine. Is there no easy sort for object arrays? I don't particularly want to rewrite all my code, but if it's in my best interest I will.

  10. #10
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    You can sort without collections, with just arrays, or with your own static sorting utility method if desired.

    What are your sort criteria? In other words, what is your compareTo (if Comparable is extended) or your compare (if you will create a Comparator) look like?

  11. #11
    gcampton Guest

    Default

    I guess i want to compare rego, and then make -> model as backups.
    so going by the tutorials something like this:

    Java Code:
    import java.util.*;
    
    public class VehicleSort
    {
        Static final Comparator<Vehicle> SORT_ORDER = new Comparator<Vehicle>()
        {
            public int compare(Vehicle v1, Vehicle v2)
            {
                return v2.getRego().compareTo(v1.getRego());
            }
        };
    
    // Vehicle driver class
    
    // this is where I'm stuck...
    
    
        List<Vehicle>v = new ArrayList<Vehicle>(vehicles);
        Collections.sort(v, SORT_ORDER);
        System.out.println(v);
    so "v" is my new arrayList? and will this accept my array "brokenArray[][]" and create a new arrayList from my array?
    My problem is because I haven't covered arrayList, and Collections class I don't really understand what half these methods are doing. And how I would tweak them to my liking. Also it's not calling comparator or public int compare(Vehicle v1, Vehicle v2) So i don't understand how it is sorting an array...

    yes I just listed Collections.... because that is all that is covered, from what I can find.
    Last edited by gcampton; 10-18-2009 at 05:55 PM.

  12. #12
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    I'm not sure what you mean by the two-dimensional array, as you never mentioned that previously.

    Again, you can sort a one-dimensional array without resorting to creating a collection via the utility class Arrays and its sort method.

    Also, I'm concerned in your example that you've flipped the order of comparison in the compare method. In other words, according to standards as I understand them I believe that this:
    Java Code:
    return v2.getRego().compareTo(v1.getRego());
    should be:
    Java Code:
    return v1.getRego().compareTo(v2.getRego());
    Otherwise your sort will be inverted.
    Last edited by Fubarable; 10-18-2009 at 06:14 PM.

  13. #13
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    For instance, say you had the simple Vehicle class:
    Vehicle.java
    Java Code:
    public class Vehicle {
       private String registration = "";
       
       public Vehicle(String registration) {
          this.registration = registration;
       }
       
       public void setRegistration(String registration) {
          this.registration = registration;
       }
       
       public String getRegistration() {
          return registration;
       }
       
       @Override
       public String toString() {
          return "Vehicle " + registration;
       }
    
    }
    You could sort an array of this with ease:
    VehicleSort.java
    Java Code:
    import java.util.Arrays;
    import java.util.Comparator;
    
    public class VehicleSort {
       static final Comparator<Vehicle> SORT_ORDER = new Comparator<Vehicle> () {
    
          public int compare(Vehicle v1, Vehicle v2) {
             return v1.getRegistration().compareTo(v2.getRegistration());
          }
          
       };
       
       public static void main(String[] args) {
          Vehicle[] vehicles = {
                   new Vehicle("z"),
                   new Vehicle("m"),
                   new Vehicle("c"),
                   new Vehicle("b"),
                   new Vehicle("f"),
                   new Vehicle("d"),
                   new Vehicle("s"),
                   new Vehicle("a")
          };
          
          System.out.println(Arrays.toString(vehicles));
          Arrays.sort(vehicles, VehicleSort.SORT_ORDER);
          System.out.println(Arrays.toString(vehicles));
       }
       
    }

  14. #14
    gcampton Guest

    Default

    Quote Originally Posted by Fubarable View Post
    I'm not sure what you mean by the two-dimensional array, as you never mentioned that previously.

    Again, you can sort a one-dimensional array without resorting to creating a collection via the utility class Arrays and its sort method.

    Also, I'm concerned in your example that you've flipped the order of comparison in the compare method. In other words, according to standards as I understand them I believe that this:
    Java Code:
    return v2.getRego().compareTo(v1.getRego());
    should be:
    Java Code:
    return v1.getRego().compareTo(v2.getRego());
    Otherwise your sort will be inverted.
    Sorry I should have mentioned it was multidimensional before.

    it could be a single array easily enough, I'm not quite sure why I made it multi, at the time seemed to make more sense as I'm dealing with different kinds of vehicles, so I made 1 row per vehicle eg.
    [TRUCK][TRUCK][TRUCK][TRUCK]
    [CAR][CAR][CAR][CAR][CAR][CAR][CAR][CAR]
    [MOTOCYCLE][MOTOCYCLE][MOTOCYCLE]

    as far as the compareTo line that is the exact line taken from:
    http://java.sun.com/docs
    Java Code:
    import java.util.*;
    public class EmpSort {
        static final Comparator<Employee> SENIORITY_ORDER =
                                     new Comparator<Employee>() {
            public int compare(Employee e1, Employee e2) {
                return e2.hireDate().compareTo(e1.hireDate());
            }
        };

  15. #15
    gcampton Guest

    Default

    Quote Originally Posted by Fubarable View Post
    VehicleSort.java
    Java Code:
    import java.util.Arrays;
    import java.util.Comparator;
    
    public class VehicleSort {
       static final Comparator<Vehicle> SORT_ORDER = new Comparator<Vehicle> () {
    
          public int compare(Vehicle v1, Vehicle v2) {
             return v1.getRegistration().compareTo(v2.getRegistration());
          }
          
       };
       
       public static void main(String[] args) {
          Vehicle[] vehicles = {
                   new Vehicle("z"),
                   new Vehicle("m"),
                   new Vehicle("c"),
                   new Vehicle("b"),
                   new Vehicle("f"),
                   new Vehicle("d"),
                   new Vehicle("s"),
                   new Vehicle("a")
          };
          
          System.out.println(Arrays.toString(vehicles));
          Arrays.sort(vehicles, VehicleSort.SORT_ORDER);
          System.out.println(Arrays.toString(vehicles));
       }
       
    }
    Nice, I guess I will use this, and change my array to single dimension. Thanks for all your help I really appreciate it.

  16. #16
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    My example is a bit over-simplified. Also, if it were my program, I'd make Vehicle abstract.

    If you wanted to get fancy, you could put a bunch of different Comparators into an enum and then use this to sort any which way you'd like.

  17. #17
    gcampton Guest

    Default

    Quote Originally Posted by Fubarable View Post
    My example is a bit over-simplified. Also, if it were my program, I'd make Vehicle abstract.

    If you wanted to get fancy, you could put a bunch of different Comparators into an enum and then use this to sort any which way you'd like.
    final int CAR=0, TRUCK=1;

    yea Vehicle is abstract, Truck and Car both extend it I never make a object of type vehicle... When I read from my file and create my array, I use selection if (String.split[0].equals("CAR")) -> brokenArray[CAR][CarCount++]
    or (String.split[1].equals("TRUCK")) -> brokenArray[TRUCK][TruckCount++],
    I don't quite see how you could use enums in that way...
    Last edited by gcampton; 10-20-2009 at 12:42 AM.

  18. #18
    Fubarable's Avatar
    Fubarable is offline Moderator
    Join Date
    Jun 2008
    Posts
    19,315
    Blog Entries
    1
    Rep Power
    26

    Default

    enums are kind of a cross between constants and classes. An enum of this structure would work easily...
    Java Code:
    import java.util.Comparator;
    
    public enum Sorts {
       REGISTRATION(new Comparator<Vehicle>() {
          public int compare(Vehicle v1, Vehicle v2) {
             return v1.getRegistration().compareTo(v2.getRegistration());
          }
       }),
       YEAR(new Comparator<Vehicle>() {
          public int compare(Vehicle v1, Vehicle v2) {
             return new Integer(v1.getYear()).compareTo(v2.getYear());
          }
       }),
       MAKE_YEAR(new Comparator<Vehicle>() {
          public int compare(Vehicle v1, Vehicle v2) {
             if (v1.getMake().compareTo(v2.getMake()) == 0) {
                return new Integer(v1.getYear()).compareTo(v2.getYear());
             } else {
                return v1.getMake().compareTo(v2.getMake());
             }
          }
       })
       ;
       
       private Sorts(Comparator<Vehicle> comparator) {
          this.comparator = comparator;
       }
       private Comparator<Vehicle> comparator;
       public Comparator<Vehicle> getComparator() {
          return comparator;
       }
    }

  19. #19
    gcampton Guest

    Default

    Hmmmm weird, So how would you use this enum? and what benefits is there to having an enum class over a normal sorting class?

    Seems even more complicated to me, as now your not just defining a method that says sort array using MAKE -> now sort array using YEAR -> now sort array using REGISTRATION...

    example we have 5 vehicles:

    TRUCK TRUCKIN Mack LFR8 BLACK 110,990.00 23921 2005 GOOD
    CAR xxx-xxx SEDAN Ford GTX BLACK 45,000.00 6932 2006 EXCELLENT
    CAR LMF-40 COUPE Ford GTS BLACK 38,000.00 12311 2005 GOOD
    TRUCK BIG-MACK Mack LFV12 RED 180,000.00 213889 2002 GOOD
    CAR xxx-xxx WAGON Ford Falcon SILVER 17,599 89,455 2003 AVERAGE


    unregistered vehicles will have xxx-xxx as their rego so first I would want to sort array by the elements that make the least sense to sort by(most un-natural) working my way up to most wanted sort(most natural). so that way instead of having all FORDS one after the other with no other sorting pattern they would be sorted correctly, and by the same token having all unregistered vehicles simply in a group but not sorted in any other way would be pretty useless. As the real reason we want to sort is so we can binary search.

    I would want these vehicles first sorted by model so they would look like:
    falcon -> gts -> gtx -> lfr8 -> lfv12

    CAR xxx-xxx WAGON Ford Falcon SILVER 17,599 89,455 2003 AVERAGE
    CAR LMF-40 COUPE Honda GTS BLACK 38,000.00 12311 2005 GOOD
    CAR xxx-xxx SEDAN Ford GTX BLACK 45,000.00 6932 2006 EXCELLENT
    TRUCK TRUCKIN Mack LFR8 BLACK 110,990.00 23921 2005 GOOD
    TRUCK BIG-MACK Mack LFV12 RED 180,000.00 213889 2002 GOOD

    Then sorted by make:
    ford -> ford -> honda -> mack -> mack

    CAR xxx-xxx WAGON Ford Falcon SILVER 17,599 89,455 2003 AVERAGE
    CAR xxx-xxx SEDAN Ford GTX BLACK 45,000.00 6932 2006 EXCELLENT
    CAR LMF-40 COUPE Honda GTS BLACK 38,000.00 12311 2005 GOOD
    TRUCK TRUCKIN Mack LFR8 BLACK 110,990.00 23921 2005 GOOD
    TRUCK BIG-MACK Mack LFV12 RED 180,000.00 213889 2002 GOOD

    moving on to registration =>

    TRUCK BIG-MACK Mack LFV12 RED 180,000.00 213889 2002 GOOD
    CAR LMF-40 COUPE Honda GTS BLACK 38,000.00 12311 2005 GOOD
    TRUCK TRUCKIN Mack LFR8 BLACK 110,990.00 23921 2005 GOOD
    CAR xxx-xxx WAGON Ford Falcon SILVER 17,599 89,455 2003 AVERAGE
    CAR xxx-xxx SEDAN Ford GTX BLACK 45,000.00 6932 2006 EXCELLENT

    I am in no real hurry anyway I can wait, as it is I am already about 5 weeks ahead of my class. While I have pretty much implemented my whole program and only have sorting and searching left, rest of the class are still just learning about arrays, have not covered try/catch/finally or IO File handling or Date class. So I'm in no great rush to learn this, I just find it annoying the book we are using does not cover it well. And I have found it hard to find useful info I can teach myself with online (same problem I had with enums). I have the next 6 weeks or so to sit around and twiddle my thumbs waiting to learn about it in class. :) :)

  20. #20
    PhHein's Avatar
    PhHein is offline Senior Member
    Join Date
    Apr 2009
    Location
    Germany
    Posts
    1,429
    Rep Power
    7

Page 1 of 2 12 LastLast

Similar Threads

  1. Replies: 2
    Last Post: 10-07-2009, 07:24 PM
  2. Multiple types in Vector - type checking
    By Excession in forum Advanced Java
    Replies: 5
    Last Post: 07-13-2008, 08:06 PM
  3. Hastable - Multiple Types
    By sopna sajith in forum Advanced Java
    Replies: 3
    Last Post: 06-29-2008, 05:40 AM
  4. Can I use vectors to store multiple types of objects
    By Nathand in forum Advanced Java
    Replies: 6
    Last Post: 04-28-2008, 08:55 AM
  5. Replies: 0
    Last Post: 04-14-2008, 09:39 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
  •