Sorting an ArrayList: "no instance(s) of type variable(s) T exist so that bookList conforms to Comparable<? super T>"

40 Views Asked by At

I created a Java class of a booklist.

public class bookList {
    public String title, author, genre;
    public bookList (String beginTitle, String beginAuthor, String beginGenre)
    {
        title = beginTitle;
        author = beginAuthor;
        genre = beginGenre;
    }
    public String getTitle(){return title;}
    public String getAuthor(){return author;}
    public String getGenre(){ return genre;}
    public void setTitle(String titleUpdate){title = titleUpdate;}
    public void setAuthor(String authorUpdate){author = authorUpdate;}
    public void setPubDate(String genreUpdate){genre = genreUpdate;}

    @Override
    public String toString() {
        return "title: " + title + '\t'+
                "author: " + author + '\t'+
                "genre: " + genre +
                 "\n";
    }
}

Then I created a driver class, adding books to a toRead ArrayList.

import java.util.*;
public class Main {
    public static void main(String[] args) {
        int userResponse = 1;
        String title, author, genre;
        String userInput;
        Scanner scan = new Scanner(System.in);
        bookList newBook = new bookList(" ", " ", " ");
        ArrayList<bookList> toRead = new ArrayList<>();
        bookList example1 = new bookList("Mesopotamia", "Gwendolyn Leick", "history");
        bookList example2 = new bookList("A Week to be Wicked", "Tessa Dare", "romance");
        bookList example3 = new bookList("Say Yes to the Marquess", "Tessa Dare", "romance");
        bookList example4 = new bookList("Istanbul", "Thomas F. Madden", "history");
        bookList example5 = new bookList("Circe", "Madeline Miller", "fiction");
        bookList example6 = new bookList("The Song of Achilles", "Madeline Miller", "fiction");
        bookList example7 = new bookList("A Lady by Midnight", "Tessa Dare", "romance");
        bookList example8 = new bookList("When a Scot Ties the Knot", "Tessa Dare", "romance");
        bookList example9 = new bookList("Worlds of Medieval Europe", "Clifford Backman", "history");
        bookList example10 = new bookList("The Sumerians", "Samuel Noah Kramer", "history");
        Collections.addAll(toRead, example1, example2, example3, example4, example5, example6, example7, example8, example9, example10);

        System.out.println("Welcome to your to read list!");

        System.out.println("To see your reading list, enter 1,");
        System.out.println("To sort your reading list by title, type 2");
        userResponse = scan.nextInt();
        if (userResponse == 1) {
            System.out.println(toRead);
        }
        if (userResponse == 2) {
            Collections.sort(toRead); 
}
}

The Collections.sort(toRead); is underlined in red and it says "no instance(s) of type variable(s) T exist so that bookList conforms to Comparable<? super T>"

I've tried Google and other questions, but they're not helping. Any assistance is appreciated. Thank you!

(And before anyone asks, yes, this is homework. We're supposed to design and create a program. We didn't talk about sorting Array Lists in class).

2

There are 2 best solutions below

0
Mio On

As pointed out in the comments, you're not providing your program a way to sort "bookList". should it sort it based on tilte? author? something else? java isn't gonna just assume what is the natural order of "bookList".

You must tell your program to sort based on specific criteria such as title, author, or any other data field in the class.

One way to do this is by having the "bookList" class implement the Comparable interface and override the compareTo() method

public class bookList implements Comparable<bookList>{
public String title, author, genre;
public bookList (String beginTitle, String beginAuthor, String beginGenre)
{
    title = beginTitle;
    author = beginAuthor;
    genre = beginGenre;
}
public String getTitle() {
    return title;
}

public String getAuthor() {
    return author;
}

public String getGenre() {
    return genre;
}

public void setTitle(String titleUpdate) {
    title = titleUpdate;
}

public void setAuthor(String authorUpdate) {
    author = authorUpdate;
}

public void setPubDate(String genreUpdate) {
    genre = genreUpdate;
}

@Override
public String toString() {
    return "title: " + title + '\t'+
            "author: " + author + '\t'+
            "genre: " + genre +
             "\n";
}

@Override
public int compareTo(bookList other) {
    //assuming you want to sort by tilte, change it as per your requirements
    return this.title.compareTo(other.title); 
}

}

0
Abra On

I think that class bookList should be named Book since an instance of the class represents a single book and not a list. Also, after a book has been published, I don't think its author nor its title (nor even its genre) will be changed and therefore it is a good candidate for a [Java] record. Then you automatically get method toString as well as equals and hashCode. Since a [Java] record is really a class, you can make it implement [interface] Comparable – as in the other answer – but I want to provide an alternative solution so I chose to implement Comparator and also to use the stream API, in particular the sorted method.

Note that the below code uses lambda expressions (and method references).

import java.util.ArrayList;
import java.util.Comparator;
import java.util.List;

public record Book(String title, String author, String genre) {

    public static void main(String[] args) {
        Comparator<Book> bookTitleComparator = (b1, b2) -> b1.title().compareTo(b2.title);
        List<Book> bookList = new ArrayList<>();
        bookList.add(new Book("Mesopotamia", "Gwendolyn Leick", "history"));
        bookList.add(new Book("A Week to be Wicked", "Tessa Dare", "romance"));
        bookList.add(new Book("Say Yes to the Marquess", "Tessa Dare", "romance"));
        bookList.add(new Book("Istanbul", "Thomas F. Madden", "history"));
        bookList.add(new Book("Circe", "Madeline Miller", "fiction"));
        bookList.add(new Book("The Song of Achilles", "Madeline Miller", "fiction"));
        bookList.add(new Book("A Lady by Midnight", "Tessa Dare", "romance"));
        bookList.add(new Book("When a Scot Ties the Knot", "Tessa Dare", "romance"));
        bookList.add(new Book("Worlds of Medieval Europe", "Clifford Backman", "history"));
        bookList.add(new Book("The Sumerians", "Samuel Noah Kramer", "history"));
        bookList.stream()
                .sorted(bookTitleComparator)
                .forEach(System.out::println);
    }
}

Output when running above code:

Book[title=A Lady by Midnight, author=Tessa Dare, genre=romance]
Book[title=A Week to be Wicked, author=Tessa Dare, genre=romance]
Book[title=Circe, author=Madeline Miller, genre=fiction]
Book[title=Istanbul, author=Thomas F. Madden, genre=history]
Book[title=Mesopotamia, author=Gwendolyn Leick, genre=history]
Book[title=Say Yes to the Marquess, author=Tessa Dare, genre=romance]
Book[title=The Song of Achilles, author=Madeline Miller, genre=fiction]
Book[title=The Sumerians, author=Samuel Noah Kramer, genre=history]
Book[title=When a Scot Ties the Knot, author=Tessa Dare, genre=romance]
Book[title=Worlds of Medieval Europe, author=Clifford Backman, genre=history]

Since a [Java] record is really a class, you can also override any of the methods such as toString – if you don't want the default implementation as shown above.