简体   繁体   中英

Selection Sort of the shoes stored in the Array based on the Shoe Id in ascending order

I am trying to use selection sort to sort shoes in the array based on the shoeId. The sort is in ascending order. I am wring selection sort recursive way. The one problem I am facing is in sortShoesRecurse method. IT looks like it doesn't like that compareTo method I am using there but I shoed use compareTo method.

<pre> <code>
if(sc.compare(sh[indexWithMinValue], sh[forwardIndex]) > 0)
</pre> </code>

when I run the program I receive this error:

<pre> <code>

java.lang.NullPointerException
at shoepkg.ShoeComparator.compare(ShoeComparator.java:8) 
    //line 8 in the code
    // if (obj1.getId() == obj2.getId())

    at shoepkg.ShoeProcessor.sortShoesRecurse(ShoeProcessor.java:43)
    //if(sc.compare(sh[indexWithMinValue], sh[forwardIndex]) > 0) 

at shoetestpkg.TestShoe.main(Shoe.java:28)
    //bp.sortShoesRecurse(0);

  </pre> </code>




<pre> <code>

    public class TestShoe {


    public static void main(String[] args) {

    ShoeProcessor s = new Shoe();
    Shoe s1 = new Shoe(7, "Black");
    Shoe s2 = new Shoe(10, "Red");

    try {
        s.addShoe(s1);
                    s.addShoe(s2);

    }catch(ShoeException bex){
        System.out.println("Shoe Exception:  "  + bex);
    }


    }
    }

    public class ShoeProcessor
    {
    private Shoe [] sh;
    private int numShoes=0;
    private ShoeComparator<Shoe> sc;

    public ShoeProcessor()
    {
    sh = new Shoe [10];
    sc=new ShoeComparator<Shoe>();
    }


    public void addShoe(Shoe s) throws ShoeException
   {
    if(s.getId() < 0) {
        throw new ShoeException(s);
    }
    else {
        if(numShoes<10){
            sh[numShoes]=s;
            numShoes++;
        }
    }
    }

    public void sortShoesRecurse(int startIndex)
    {
        if ( startIndex >= sh.length - 1 ) {
            return;
        }

        int indexWithMinValue=startIndex;


        for(int forwardIndex=startIndex+1; forwardIndex<sh.length;forwardIndex++) {
            if(sc.compare(sh[indexWithMinValue], sh[forwardIndex]) > 0) {
                indexWithMinValue = forwardIndex;
            }
        }   
        Shoe temp= sh[startIndex];
        sh[startIndex]=sh[indexWithMinValue];
        sh[indexWithMinValue]= temp;

        sortShoesRecurse(startIndex+1);
    } 

    public Book[] getBooks() {
        return books;
    }
    }

    package shoepkg;

    public class ShoeComparator<T extends Shoe>
    {

    public int compare(T obj1, T obj2)
    {
            if (obj1.getId()== obj2.getId())
            {
                return 0;
            }
            if (obj1.getId() > obj2.getId())
            {
            return 1;
            }
            else if  (obj1.getId() < obj2.getId())
            {
                return -1;
            }
            return 0;
    }
   }

</pre> </code>

I made some updates to the code after some advices and it is current code. Still get some errors which also were updated on the top. Thank you for your help.

I do have to compare objects based on the Id.

First of all, let's break down the line of code that is throwing your error:

sh[indexWithMinValue].getId().sc.compareTo(sh[forwardIndex].getId()) > 0

So:

sh[indexWithMinValue].getId()

Get a Shoe object from your Shoe array and call the getId() method.

.sc

Ask whatever getId() returned for it's 'sc' property.

compareTo(sh[forwardIndex].getId()) > 0

And compare the 'sc' property to an 'Id' from another Shoe object within the array.

You might start to see your problem now :) (hint: the int returned from getId() doesn't have a 'sc' property.)

Second, let's look at your ShoeComparator's compare method

public int compare(T obj1, T obj2)

It takes 2 objects, not one!

There are 2 ways to easily solve this conflict:

1: properly make a call to your ShoeComparator's compare() implementation:

if (sc.compare(sh[indexWithMinValue, sh[forwardIndex]) > 0)

This way you properly use your compare() implementation and it 'should' no longer throw errors! This works since your compare() method internally makes the calls to getId() and compares it, you don't have to do this before calling this method.

2: drop your entire ShoeComparator class and make your Shoe class implement the Comparable interface, this looks like this:

public class Shoe implements Comparable<Shoe> {

    private int id;

    // rest of your Shoe class

    @Override
    public int compareTo(Shoe shoe) {
        if (id == shoe.getId())
            return 0; // Shoes are the same!

        if (id > shoe.getId())
            return 1; // I'm bigger than the other Shoe!

        if (id < shoe.getId())
            return -1; // I'm smaller :((

        return 0;
    }

}

You can then modify your if statement to look like this:

if (sh[indexWithMinValue].compareTo(sh[forwardIndex]) > 0) {

You are seeming to do this in a very cumbersome way, while this may not answer your direct question, it will hopefully help you in the future:

You should maintain a List<Shoe> shoes somewhere, holding the Shoe s.

Now sorting it in Java 8, assuming int getShoeId() is available, is very easy, it would be:

shoes.sort(Comparator.comparingInt(Shoe::getShoeId));

And that's it! What I use here is somewhat more sophisticated though, basically Shoe::getShoeId() is a method reference, that is being called on a Shoe and returns an int . Then Comparator.comparingInt(...) does the magic to create the Comparator<Shoe> , and then finally shoes.sort(...) simply sorts the list.

In Java 7 you would need to write your custom comparator, which I always have found to be tricky, so I'd advise to use Java 8, which will be available for public release on 18 March 2014.

My guess is that in you Show class you have declared id has Primitive int :

  int id;

Since int is of primitive type you cannot invoke functions on it. Change the type of member variable 'id' to Integer and it will work :

  Integer id;

  public Integer getId()
   {
     return id;
   }

I would recommend you to compare the Shoe Objects themselves rather than exposing comparison via the ids. In that case you can define 'id' as primitive int.

  public class Shoe implements Comparable<Shoe>
  {

      public int compaare(Shoe obj)
      {
         return id - obj.id;
      }
  }

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM