Java Sorting:按属性对对象数组进行排序,对象不允许使用Comparable

Posted

技术标签:

【中文标题】Java Sorting:按属性对对象数组进行排序,对象不允许使用Comparable【英文标题】:Java Sorting: sort an array of objects by property, object not allowed to use Comparable 【发布时间】:2012-09-09 02:36:54 【问题描述】:

我有一个类 Library,它包含 Book 对象数组,我需要根据 Book 的属性(Title 或 PageNumber)对数组进行排序。问题是我不允许将 Comparable 类与 Book 一起使用。你会如何推荐我对图书馆中的书籍数组进行排序?写我自己的排序?或者有没有更简单的方法?如果你需要 sn-ps 的代码,尽管问!

【问题讨论】:

你能用Comparator吗? 我可以在图书馆,但不能在书。 这种限制是人为的,比如在作业中,还是有其他原因? 这是一个作业,太人为了。 【参考方案1】:

您可以提供Comparator 来比较您希望的任何类型,Comparable 或其他。

对于您使用的数组和集合

Arrays.sort(array, myComparator);
Collections.sort(list, myComparator);

即使是像 TreeSet 这样的排序集合也可以使用自定义比较器

例如

Collections.sort(books, new Comparator<Book>() 
   public int compare(Book b1, Book b2) 
      return if b1 is greater return +1, if b2 is smaller return -1 otherwise 0
   
);

【讨论】:

Comparator 是一个独立的类,是您的类的补充。有很多方法可以做到,但一个常见的选择是使用匿名类,添加了一个示例。 您可以在需要对集合进行排序的任何地方使用它。也就是说,它可以在任何地方,最好的地方取决于你。 就像示例一样。如果没有填充整个数组,则需要使用 Arrays.sort(array, start, end, comparator); 我能够确认这确实是一个用户错误,在我调用 sort 时我的比较器为空。感谢您帮助整理@PeterLawrey。 没有双关语:)【参考方案2】:

如果您可以使用Comparators,请为您需要的每种排序类型写一个,例如,书名升序,页码降序。如果第一个参数大于第二个参数,Comparatorcompare 方法必须返回正数,如果第一个参数小于第二个参数,则返回负数,如果它们相等,则返回零。

import java.util.Comparator;
import java.util.List;
import java.util.Arrays;

class Book
    String title;
    int pageNumber;

    public Book(String title, int pageNumber)
        this.title = title;
        this.pageNumber = pageNumber;
    

    String getTitle() return title; 
    int getPageNumber() return pageNumber; 

    public String toString()
        return "(" + title + ", " + pageNumber + " pages)";
    


public class Library

    // These variables are static because you don't need multiple copies
    // for sorting, as they have no intrinsic state.
    static private Comparator<Book> ascTitle;
    static private Comparator<Book> descPageNumber;

    // We initialize static variables inside a static block.
    static 
        ascTitle = new Comparator<Book>()
            @Override
            public int compare(Book b1, Book b2)
                return b1.getTitle().compareTo(b2.getTitle());
            
        ;

        descPageNumber = new Comparator<Book>()
            @Override
            public int compare(Book b1, Book b2)
                // Java 7 has an Integer#compare function
                return Integer.compare(b1.getPageNumber(), b2.getPageNumber());
                // For Java < 7, use 
                // Integer.valueOf(n1).compareTo(n2);
                // DO NOT subtract numbers to make a comparison such as n2 - n1.
                // This can cause a negative overflow if the difference is larger 
                // than Integer.MAX_VALUE (e.g., n1 = 2^31 and n2 = -2^31)
            
        ;
    

    private Book[] books;
    public Book[] getBooks() return books; 

    public void sortAscTitle()
        Arrays.sort(books, ascTitle);
    

    public void sortDescPageNumber()
        Arrays.sort(books, descPageNumber);
    

    public Library(Book[] books)
        this.books = books;
    

    public static void main(String[] args)
        Library library = new Library( new Book[]
            new Book("1984", 123), 
            new Book("I, Robot", 152), 
            new Book("Harry Potter and the Philosopher's Stone", 267),
            new Book("Harry Potter and the Goblet of Fire", 759),
            new Book("The Bible", 1623)
        );

        library.sortAscTitle();
        System.out.println(Arrays.toString(library.getBooks()));

        library.sortDescPageNumber();
        System.out.println(Arrays.toString(library.getBooks()));
    

【讨论】:

谢谢!非常好!我使用了 Peter 的建议,这种实现方式在我的课堂上表现得更好一些,但是,这也很棒,而且我在返回时遇到了麻烦,所以看到这些代码真的对我有很大帮助!非常感谢!每次我需要对任何东西进行排序时,我都会回到这个问题以供参考!【参考方案3】:

把这个贴在你的图书馆里:

java.util.Collections.sort(bookList, bookComparator);

【讨论】:

booklist 将是数组的名称,对吗? bookComparator 呢? bookComparator 将是 Comparator 接口的实现实例,该接口考虑了书籍的特定属性(例如,标题、ISBN 等)。在这个例子中 bookList 是一个很容易从数组中获取的 List,但你可以坚持使用数组并执行以下操作:Arrays.sort(bookArray, bookComparator);【参考方案4】:

扩展 @PeterLawrey 对 Java 8 的回答,您现在可以使用 Lambda Expression 而不是 Comparable&lt;T&gt; 委托:

Collections.sort(books, (firstBook, secondBook -> b1 is greater return +1, 
                                                  if b2 is smaller return -1 otherwise 0));

【讨论】:

以上是关于Java Sorting:按属性对对象数组进行排序,对象不允许使用Comparable的主要内容,如果未能解决你的问题,请参考以下文章

在Java中按属性值对对象ArrayList进行排序

按对象属性对 javascript 对象数组进行排序

按属性对 EmberJS 对象数组进行排序

按对象属性对 javascript 对象数组进行排序

PHP - 按对象属性对对象数组进行排序[重复]

javascript 按对象属性对对象数组进行排序