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
,请为您需要的每种排序类型写一个,例如,书名升序,页码降序。如果第一个参数大于第二个参数,Comparator
的 compare
方法必须返回正数,如果第一个参数小于第二个参数,则返回负数,如果它们相等,则返回零。
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<T>
委托:
Collections.sort(books, (firstBook, secondBook -> b1 is greater return +1,
if b2 is smaller return -1 otherwise 0));
【讨论】:
以上是关于Java Sorting:按属性对对象数组进行排序,对象不允许使用Comparable的主要内容,如果未能解决你的问题,请参考以下文章