web-dev-qa-db-fra.com

Tri Java: trier un tableau d'objets par propriété, objet non autorisé à utiliser Comparable

J'ai une classe, Library, qui contient un tableau d'objets Book, et je dois trier le tableau en fonction des propriétés de Book, Title ou PageNumber. Le problème n'est pas autorisé à utiliser la classe Comparable avec Book. Comment recommanderiez-vous que je trie le tableau de livres dans la bibliothèque? Écrire ma propre sorte? Ou y a-t-il un moyen plus facile? Si vous avez besoin d'extraits de code, il suffit de demander!

9
samuraiseoul

Vous pouvez fournir un Comparator pour comparer tout type de votre choix, Comparable ou autre.

Pour les tableaux et les collections que vous utilisez

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

Même les collections triées comme TreeSet peuvent utiliser un comparateur personnalisé.

par exemple.

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
   }
});
19
Peter Lawrey

Si vous pouvez utiliser Comparators, écrivez-en un pour chaque type de tri requis, par exemple, croissant pour le titre du livre et décroissant pour le numéro de page. La méthode compare d'une Comparator doit renvoyer positive si le premier argument est plus grand que le deuxième, négatif si le premier est plus petit et zéro si elles sont égales.

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()));
    }
}
5
Bruno Kim

Collez ceci dans votre bibliothèque:

Java.util.Collections.sort(bookList, bookComparator);
1
David Soroko

En élargissant la réponse de @ PeterLawrey à Java 8, vous pouvez maintenant utiliser un expression lambda au lieu d'un délégué Comparable<T>:

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