简体   繁体   English

根据鞋号按升序对存储在数组中的鞋进行选择排序

[英]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. 我正在尝试使用选择排序对基于shoeId的数组中的鞋子进行排序。 The sort is in ascending order. 排序按升序排列。 I am wring selection sort recursive way. 我正在拧选择排序递归的方式。 The one problem I am facing is in sortShoesRecurse method. 我面临的一个问题是sortShoesRecurse方法。 IT looks like it doesn't like that compareTo method I am using there but I shoed use compareTo method. IT部门似乎不喜欢我在那里使用的compareTo方法,但是我使用了compareTo方法。

<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. 我确实必须根据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. 从Shoe数组中获取Shoe对象,然后调用getId()方法。

.sc

Ask whatever getId() returned for it's 'sc' property. 询问为其“ sc”属性返回的任何getId()。

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

And compare the 'sc' property to an 'Id' from another Shoe object within the array. 并将'sc'属性与数组中另一个Shoe对象的'Id'比较。

You might start to see your problem now :) (hint: the int returned from getId() doesn't have a 'sc' property.) 您可能现在开始发现问题了:)(提示:从getId()返回的int没有'sc'属性。)

Second, let's look at your ShoeComparator's compare method 其次,让我们看一下ShoeComparator的compare方法

public int compare(T obj1, T obj2)

It takes 2 objects, not one! 它需要2个对象,而不是一个!

There are 2 ways to easily solve this conflict: 有两种方法可以轻松解决此冲突:

1: properly make a call to your ShoeComparator's compare() implementation: 1:正确调用ShoeComparator的compare()实现:

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

This way you properly use your compare() implementation and it 'should' no longer throw errors! 这样,您可以正确使用compare()实现,并且“不再”应该抛出错误! 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. 由于您的compare()方法在内部对getId()进行了调用并将其进行比较,因此您可以在调用此方法之前不必执行此操作。

2: drop your entire ShoeComparator class and make your Shoe class implement the Comparable interface, this looks like this: 2:删除整个ShoeComparator类,并使Shoe类实现Comparable接口,如下所示:

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语句修改为如下形式:

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. 您应该在某处维护List<Shoe> shoes ,并握住Shoe

Now sorting it in Java 8, assuming int getShoeId() is available, is very easy, it would be: 现在,使用int getShoeId()可用,在Java 8中对其进行排序非常简单,它将是:

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 . 不过,我在这里使用的内容稍微复杂一些,基本上Shoe::getShoeId()是方法引用,在Shoe上被调用并返回int Then Comparator.comparingInt(...) does the magic to create the Comparator<Shoe> , and then finally shoes.sort(...) simply sorts the list. 然后Comparator.comparingInt(...)神奇地创建了Comparator<Shoe> ,最后, shoes.sort(...)只是对列表进行了排序。

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. 在Java 7中,您需要编写自定义比较器,而我一直发现这很棘手,因此我建议您使用Java 8,它将在2014年3月18日公开发布。

My guess is that in you Show class you have declared id has Primitive int : 我的猜测是,在您的Show类中,您声明的id具有Primitive int:

  int id;

Since int is of primitive type you cannot invoke functions on it. 由于int是原始类型,因此您不能在其上调用函数。 Change the type of member variable 'id' to Integer and it will work : 将成员变量'id'的类型更改为Integer,它将起作用:

  Integer id;

  public Integer getId()
   {
     return id;
   }

I would recommend you to compare the Shoe Objects themselves rather than exposing comparison via the ids. 我建议您比较鞋子对象本身,而不是通过id公开比较。 In that case you can define 'id' as primitive int. 在这种情况下,您可以将“ id”定义为原始int。

  public class Shoe implements Comparable<Shoe>
  {

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

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