I'm working on review problems for an exam and one of the problems ask that I alphabetize book titles in order. I am asked to ignore the word "The", if it appears in the beginning of a title. My question is, is there a way to sort the title order of books while ignoring "The" using Arrays.sort()?
Originally I put the books in an Array list called books and then applied:
Arrays.sort(books);
It worked but only to some extent because it wouldn't ignore "The". Instead is it better to do:
public class booktest {
public static void main(String[] args) {
System.out.println("Enter the title of your book: "); // The Great Gatsby
String book = IO.readString();
if(book.substring(0, 3).equalsIgnoreCase("the")){
book = book.substring(4);
}
System.out.println(book); // Output: Great Gatsby
And then compare the first letters of each book to output the ascending order?
I was wondering if there was a simpler way to go about this. Any clues or suggestions would be appreciated. Thank you.
You have to be slightly careful.
book.substring(0, 3)
throws a StringIndexOutOfBoundsException
for strings of length less than 3. "the"
does not necessarily begin with the word "The". It could begin with "There" for example. If you are using Java 7 or an earlier version, I would make a separate method like this
private static String noThe(String b) {
return b.length() >= 4 && b.substring(0, 4).equalsIgnoreCase("the ") ? b.substring(4) : b;
}
Then you can use
Arrays.sort(books, new Comparator<String>() {
@Override
public int compare(String b1, String b2) {
return String.CASE_INSENSITIVE_ORDER.compare(noThe(b1), noThe(b2));
}
});
In Java 8, you do not need a helper method as you can just do
Arrays.sort(books,
Comparator.comparing(b -> b.length() >= 4 && b.substring(0, 4).equalsIgnoreCase("the ") ? b.substring(4) : b,
String.CASE_INSENSITIVE_ORDER));
Full example (Java 8 version):
String[] books = {
"The Great Gatsby",
"The Witches",
"Persuasion",
"It",
"Therapy"};
Arrays.sort(books,
Comparator.comparing(b -> b.length() >= 4 && b.substring(0, 4).equalsIgnoreCase("the ") ? b.substring(4) : b,
String.CASE_INSENSITIVE_ORDER));
System.out.println(Arrays.toString(books));
The output is
[The Great Gatsby, It, Persuasion, Therapy, The Witches]
You can pass a custom Comparator which does the trick. You can use any one based on the SDK.
Comparator using lambda expression
Comparator<String> c1
= (String o1, String o2)->ignoreThe(o1).compareTo(ignoreThe(o2));
Comaprator for Java SDK v < 8
Comparator<String> java7Comparator = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return ignoreThe(o1).compareTo(ignoreThe(o2));
}
};
Code Snippet
import java.util.ArrayList;
import java.util.Comparator;
public class BookComparison {
public static void main(String[] args) {
//Comparator using lambda expression
Comparator<String> javaLambdaCompare
= (String o1, String o2)->ignoreThe(o1).compareTo(ignoreThe(o2));
//Comaprator for Java v < 7
Comparator<String> java7Comparator = new Comparator<String>() {
@Override
public int compare(String o1, String o2) {
return ignoreThe(o1).compareTo(ignoreThe(o2));
}
};
ArrayList<String> books = new ArrayList<String>();
//Add from source
books.add("Robinson Crusoe by Daniel Defoe");
books.add("Gulliver’s Travels by Jonathan Swift");
books.add("David Copperfield by Charles Dickens");
books.add("The Scarlet Letter by Nathaniel Hawthorne");
books.add("The Moonstone by Wilkie Collins");
books.add("Three Men in a Boat by Jerome K Jerome");
//pass any of the Comparator as an argument to sort
books.sort(javaLambdaCompare);
}
public static String ignoreThe(String book){
if(book.length()>=3 && book.substring(0, 3).equalsIgnoreCase("the")){
book = book.substring(4);
}
return book;
}
}
The result sorted list:
Hope this helps!
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.