4

I am given the task to use the constructor TreeSet(Comparator<E> comparator) with a lambda expression to make the set be sorted by book title.

The following information is given:

public class Book implements Comparable<Book> {
    private String isbn;
    private String title;
    private String author;

    public int compareTo(Book obj) {
      return isbn.compareTo(obj.isbn);
    }
    // all-args constructor and getters
}

What I have thought about so far is: I think that the constructor allows you to define the Comparator. Perhaps I should do:

Comparator<String> comp = 
    (String title, String obj.title) -> (title.compareTo(obj.title));

Then put this comp into the TreeSet<Book> bookSet = new TreeSet<Book>(comp);

However, that doesn't seem to work. I think what I need to do is use the lambda expression in the same row when creating the new TreeSet, however, I am unsure how to do so.

Naman
  • 27,789
  • 26
  • 218
  • 353
JavaMan
  • 77
  • 1
  • 2

3 Answers3

4

You need a Comparator<Book>, not a Comparator<String>. The easiest way to get one would be to use Comparator.comparing:

TreeSet<Book> bookSet = new TreeSet<>(Comparator.comparing(Book::getTitle));
Mureinik
  • 297,002
  • 52
  • 306
  • 350
2

You're looking for a book comparator. Even if you're going to compare by book title, you'll still have to use Comparator<Book>.

To reuse your code, the correction you need is:

Comparator<Book> comp = 
    (Book book1, Book book2) -> (book1.getTitle().compareTo(book2.getTitle()));

Which can be rewritten as

Comparator<Book> comp = 
    (book1, book2) -> (book1.getTitle().compareTo(book2.getTitle()));

Or

Comparator<Book> comp = Comparator.comparing(Book::getTitle);

You can then pass comp as argument to TreeSet's constructor

ernest_k
  • 44,416
  • 5
  • 53
  • 99
1

Book:

public class Book {
  private String isbn;
  private String title;
  private String author;

  public Book(String isbn, String title, String author) {
    this.isbn = isbn;
    this.title = title;
    this.author = author;
  }

  public String getIsbn() {
    return isbn;
  }

  public void setIsbn(String isbn) {
    this.isbn = isbn;
  }

  public String getTitle() {
    return title;
  }

  public void setTitle(String title) {
    this.title = title;
  }

  public String getAuthor() {
    return author;
  }

  public void setAuthor(String author) {
    this.author = author;
  }

  @Override
  public String toString() {
    return "Book{" + "isbn='" + isbn + '\'' + ", title='" + title + '\'' + ", author='" + author + '\'' + '}';
  }
}

Main class:

import java.util.Comparator;
import java.util.Set;
import java.util.TreeSet;

public class Main {
  public static void main(String[] args) {
    Book book1 = new Book("isbn1", "First Book", "Author 1");
    Book book2 = new Book("isbn2", "Second Book", "Author 2");
    Book book3 = new Book("isbn3", "Third Book", "Author 3");

    //Method first
    Set<Book> books1 = new TreeSet<>((book, thisBook) -> book.getTitle().compareTo(thisBook.getTitle()));

    books1.add(book3);
    books1.add(book2);
    books1.add(book1);

    //Method second
    Set<Book> books2 = new TreeSet<>(Comparator.comparing(Book::getTitle));

    books2.add(book2);
    books2.add(book1);
    books2.add(book3);

    System.out.println(books1);
    System.out.println(books2);

  }
}

As you are inserting values into a set so I recommend you to add hashcode and equals method in Book class as well to identify the unique book object.

Ravi Nain
  • 605
  • 8
  • 16