Сложная сортировка Java - PullRequest
       1

Сложная сортировка Java

5 голосов
/ 23 января 2011

Я застрял в том, что у меня есть объектная книга, в которой есть три переменные

String title
int Year
String authorName

Я должен отсортировать книги по одной, двум или всем трем переменным в порядке возрастания или убывания, я реализовалпорядок названий, но я застрял в том, что делать, когда люди выбирают более одной переменной для заказа.

Вот мой код:

Класс книги:

import java.util.ArrayList;


public class Book{

String title;
String authorName;
int editionYear;

public Book(String title, String authorName, int editionYear){
    this.title = title;
    this.authorName = authorName;
    this.editionYear = editionYear;

}

public String getBookInfo(){

    ArrayList bookInfo = new ArrayList();
    bookInfo.add(this.title);
    bookInfo.add(this.authorName);
    bookInfo.add(this.editionYear);
    return bookInfo.toString();
}

}

BookSorter Class:

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

public class BookSorter{

private String sortkey;
private String order;
Book[] Books;

public BookSorter(Book Book1, Book Book2, Book Book3, Book Book4){
    this.Books = new Book[] {Book1, Book2, Book3, Book4};
}

public Book[] sortByTitle(boolean sortorder){
    Comparator<Book> byTitle = new TitleComparator(sortorder);
    Arrays.sort(Books, byTitle);
    for(int i=0;i<4;i++) System.out.println(Books[i].title);
    return Books;
}
}

TitleComparator:

import java.util.Comparator;

class TitleComparator implements Comparator<Book> {

boolean ascending;

public TitleComparator(boolean ascending){
    this.ascending = ascending;
}

public int compare(Book Book1, Book Book2){
    if(ascending == true){
        if(Book1.title.compareToIgnoreCase(Book2.title) > 0) return 1;
        else if(Book1.title.compareToIgnoreCase(Book2.title) < 0) return -1;
        else return 0;
    }else{
        if(Book2.title.compareToIgnoreCase(Book1.title) < 0) return -1;
        else if(Book2.title.compareToIgnoreCase(Book1.title) > 0) return 1;
        else return 0;
    }
}
}

Хотя я мог бы немного поработать над компаратором, но я действительно застрял в том, как смоделировать такую ​​вещь, спасибозаранее

Ответы [ 4 ]

3 голосов
/ 23 января 2011

Напишите 3 класса компараторов, каждый из которых сравнивает определенный атрибут, а затем общий класс компаратора, который принимает упорядоченный список компараторов.

Или используйте удобный класс из библиотеки, например org.apache.commons.collections.comparators.ComparatorChain .

Edit:

ОП спрашивает:

как я могу написать этот общий компаратор:

Что-то вроде:

// private List<Comparator<?>> comparators;  // initialized in constructor

// compare method(book1, book2):
//     note that while result == 0, books have had equal attributes so far
//     once result is != 0, the books are now ordered - no need to compare further
//     if we run out of comparators and result still == 0, books are equal.

//     initialize iterator to list of comparators
//     int result = 0;
//     while result == 0 && still more comparators
//         get current comparator from iterator
//         result = comparator.compare(book1, book2); // compare current attribute
//     end-while
//     return result
2 голосов
/ 23 января 2011

Это звучит как домашнее задание. Поэтому я собираюсь дать вам несколько советов.

1. First see if Title1==Title2.
    1.1 if YES then see if year1==year2
            1.1.1 if YES then see if authorName1==authorName2
              1.1.1.1 If YES then they are equal (return 0)
              1.1.1.2 else if NO compare author1 and author2 (return 1 or -1)
     1.2 else if NO then compare year1 and year2 (return 1 or -1)
2. else if NO then compare title1 and title2 (return 1 or -1)
2 голосов
/ 23 января 2011

Восходящий / нисходящий может быть реализован намного проще, потому что он просто «инвертирует» результат сравнения. И вы можете «повторно» использовать результаты из методов compareToIgnoreCase:

public int compare(Book book1, Book book2) {       
   int result = book1.title.compareToIgnoreCase(book2.title);
   return ascending ? result : result * -1;
}

Другие компараторы очень похожи (ограничивая выборки методом сравнения):

public int compare(Book book1, Book book2) {       
   int result = book1.author.compareToIgnoreCase(book2.author);
   return ascending ? result : result * -1;
}

public int compare(Book book1, Book book2) {
   Integer year1 = book1.year;   
   Integer year2 = book2.year;
   int result = year1.compareTo(year2);
   return ascending ? result : result * -1;
}
1 голос
/ 23 января 2011

Компаратор Group позволяет сортировать по нескольким свойствам.Вы также можете использовать Bean Comparator , чтобы вам не приходилось писать собственные компараторы.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...