简体   繁体   English

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

[英]Java Sorting: sort an array of objects by property, object not allowed to use Comparable

I have a class, Library, that contains an array of Book objects, and I need to sort the array based off the properties of Book, either Title or PageNumber. 我有一个类,包含一个Book对象的数组,我需要根据Book的属性(Title或PageNumber)对数组进行排序。 The problem is im not allowed to use the Comparable class with Book. 问题是我不允许将Comparable类与Book一起使用。 How would you recommend I sort the array of Books in library? 您如何推荐我在图书馆中排列图书? Write my own sort? 写我自己的那种? Or is there an easier way? 或者有更简单的方法吗? If you need snippets of code, just ask! 如果您需要代码片段,请询问!

You can provide a Comparator for comparing any type you wish, Comparable or otherwise. 您可以提供Comparator来比较您希望的任何类型, Comparable或其他类型。

For Arrays and Collections you use 对于您使用的数组和集合

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

Even sorted collections like TreeSet can take a custom Comparator 甚至像TreeSet这样的已排序集合也可以使用自定义Comparator

eg 例如

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
   }
});

If you can use Comparators , write one for each type of sorting you need, eg, ascending for book title and descending for page number. 如果您可以使用Comparators ,请为您需要的每种类型的排序编写一个,例如,升序用于书名,降序用于页码。 The compare method of a Comparator must return positive if the first argument is larger than the second, negative if the first is smaller and zero if they are equal. 如果第一个参数大于第二个参数,则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()));
    }
}

坚持你的图书馆:

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

Expanding @PeterLawrey's answer to Java 8, you can now use a Lambda Expression instead of a Comparable<T> delegate: 扩展@ 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));

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

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