在Java中按值对自定义对象数组进行排序

4

我正在做一项CS-101的任务,只被允许使用一个数组。我有一个长这样的数组:

[Song, Song, Album, Fiction, Movie, Nonfiction, Song]

这里是背景层级(根据我的任务要求):
在最高级别上,你将拥有一个名为Library的类。Library将有三个子类:Music、Book和Movie。Music将有两个子类:Song和Album。Book将有两个子类:Fiction和Nonfiction。Movie、Fiction、Nonfiction、Song和Album将没有任何子类。
我目前正尝试编写一种方法,用于按ISBN号对书籍进行排序。因此,小说和非小说是我的图书类的子类,而该类是Library的子类。
我将所有内容储存在Library myLibrary[] = new Library [100]中。
我不确定如何仅从书籍中检索ISBN并对它们进行排序,因为我只允许使用一个数组;否则,我很乐意制作一本书的数组,然后单独对它们进行排序。
我可以利用哪些提示/算法来完成这项任务?
更新
如果需要,我可以发布更多代码。但是,这个问题目前更加关注方法。

1
一旦书籍被排序,您是否关心音乐和电影在数组中的位置? - gtgaxiola
暂时不需要。我会有一个单独的方法来排序它们。 - ardavis
4个回答

3
这里的关键是正确设置继承,然后实现Comparable接口。 参见此处的示例:Java Comaprable,然后对父类型的数组调用.sort(在您的情况下,这将是myLibrary.sort();)。 这是一个基本类型排序的示例:Primitive type array sort 因此,以下是步骤:
  1. 在子类型上实现Comparable
  2. 创建父类型的数组并填充它
  3. 在数组上调用sort。
祝你好运!

1

请检查这是否有效(当前在选项卡上,因此无法运行代码)。

我认为在对书籍进行排序后,它们会向数组的一侧饱和。请告诉我结果。

/* book sorting is in decreasing order of ISBN, followed by non book items
The books will be at the beginning of array, other items towards the end */
Arrays.sort(myLibrary, new Comparator<Library>()
    {
        int compare(Library l1, Library l2){
            //if both are books then compare ISBN and return appropriate
            if((l1 instanceof Book) && (l2 instanceof Book)){
                Book b1=(Book)l1; Book b2=(Book)l2;
                if(b1.getISBN()<b2.getISBN) {
                    return -1;
                } else if(b1.getISBN()>b2.getISBN()) {
                    return 1;
                } else {
                    return 0;
                }
            }
            else {//if either one, or none are Book

                //if only l1 is Book, l2 is not
                if(l1 instanceof Book){
                    return 1;
                }

                //if only l2 is Book, l1 is not
                if(l2 instanceof Book){
                    return -1;
                }

                //none are Book
                return 0;
            }
        }
    }
);

那么每个非书项都等于每本书吗?这不可能是正确的。(首先,它违反了要求 x.compareTo(y) == 0 意味着对于所有的 zsgn(x.compareTo(z)) == sgn(y.compareTo(z))。让 xz 是不同的书,让 y 是一个非书项。)请注意,这可以通过始终在 l1l2 中恰好有一个是 Book 时返回 1-1 来修复。 - Ted Hopp
但是 l1,l2 是库引用,可能并不需要 Library 拥有 ISBN 属性;它是特定于 Book 的。 - Bharat Sinha
抱歉,比较ISBN号码之前需要将Library实例转换为Book对象。我已经编辑了代码以反映更改。在我看来,它现在可以工作了。 - Jit B

1

这里是您需要的内容...

如我在之前的回答中所提到的,编写一个新的Comparator并将其用于比较Library对象。

注意:我没有检查null值,但您应该这样做...

class LibraryComparator implements Comparator<Library> {
    public int compare(Library l1, Library l2){
         // If Both are Book instance do the comparison
         if(l1 instanceof Book && l2 instanceof Book){
              // Assuming ISBN is a String or Long field in your class Book
              return ((Book)l1).getISBN().compareTo(((Book)l2).getISBN());
         } else {
         // Otherwise no change in ordering
              return 0;
              // You could specify sorting logic for Movie and Music here as well
         }
    }
}

然后你可以像这样对数组进行排序:

Arrays.sort(myLibrary, new LibraryComparator());

0

不试图给出算法的实际实现,您应该进行原地排序,其中优先级可以通过以下方式完成:

1. 书籍比音乐和电影更具优先级

2. 如果两个对象都是书,则优先级基于ISBN


那么也许可以通过首先将书籍放在前面来对整个库进行排序?然后只有在对象是“Book”的实例时才进行排序? - ardavis
我是指在排序时,您已经将书籍移动到了前面,请看原地快速排序。 - gtgaxiola
我将这个标记为答案,因为这是我用来完成作业的。其他答案也可能是正确的。 - ardavis

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接