19

Bookオブジェクトの配列を含むクラスLibraryがあり、Bookのプロパティ(TitleまたはPageNumber)に基づいて配列を並べ替える必要があります。問題は、BookでComparableクラスを使用することを許可されていません。ライブラリ内の書籍の配列を並べ替えることをどのように推奨しますか?私自身のソートを書きますか?または、もっと簡単な方法はありますか?コードのスニペットが必要な場合は、質問してください。

4

4 に答える 4

27

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
   }
});
于 2012-09-16T19:04:28.470 に答える
8

を使用できる場合はComparators、必要な並べ替えの種類ごとに1つずつ記述します。たとえば、本のタイトルは昇順、ページ番号は降順です。aのcompareメソッドはComparator、最初の引数が2番目の引数よりも大きい場合は正を返し、最初の引数が小さい場合は負を返し、等しい場合はゼロを返す必要があります。

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()));
    }
}
于 2012-09-16T19:47:17.157 に答える
1

これをライブラリに貼り付けます。

java.util.Collections.sort(bookList, bookComparator);
于 2012-09-16T19:07:42.603 に答える
0

@PeterLawreyのJava8に対する回答を拡張すると、デリゲートの代わりにLambda式を使用できるようになります。Comparable<T>

Collections.sort(books, (firstBook, secondBook -> b1 is greater return +1, 
                                                  if b2 is smaller return -1 otherwise 0));
于 2015-12-05T13:08:09.327 に答える