在java中使用多个条件搜索图书

时间:2018-03-24 06:56:18

标签: java

我有这个方法,它使用几个参数并使用几个参数在arrayList中搜索一本书。 。 我怎样才能让它变小? 如何按类别或作者对书籍进行排序? 提前谢谢你。

这是我的方法 //使用多个条件搜索图书

static void bookSearch(String... varg) { // take varg as parameter
    String title = ""; // place holders
    String author = "";

    if (varg.length > 1) { // check varg length
        title = varg[0]; // if it is greater than 1 initialize needed arguments
        author = varg[1];
    } else {
        title = varg[0]; // else initialize the first argument
    }
    for (Book book : bookList) {

        /*
         * if the title is the same and there is a second argument that
         * match author's name print found it
         */
        if (book.getTitle().equals(title)) {
            if (author.isEmpty() ^ (book.getAuthor().getfName() == author)) {
                System.out.println(" \"" + 
                                   title + 
                                   "\" founded at: " + 
                                   bookList.indexOf(book));
                break;
            }// end of if

        } else if (bookList.indexOf(book) == bookList.size() - 1) {// if not found
            System.out.println("cant find \"" + title);
        }// end of else

    } // end of for loop

} //end of search method

5 个答案:

答案 0 :(得分:1)

Java8中,您可以使用lambdas和函数来获得灵活的filter图书功能。

E.g。你有以下Book课程:

class Book {
    private String author;
    private String title;
}

book filter函数可能如下所示:

BiFunction<List<Book>, Predicate<Book>, List<Book>> BOOK_FILTER =
        (books, fields) -> books.stream().filter(fields).collect(Collectors.toList());

然后,您只需构建所需的Predicate并使用此功能。

public static List<Book> findBookByPredicate(List<Book> books, String author, String title) {
    Predicate<Book> byAuthor = book -> book.getAuthor().equals(author);
    Predicate<Book> byTitle = book -> book.getTitle().equals(title);
    return BOOK_FILTER.apply(books, byAuthor.and(byTitle));
}

如您所见,您不仅限于一定数量的Book字段。你可以随意组合它; BOOK_FILTER功能保持不变。

答案 1 :(得分:0)

您可以使用java 8 lamda表达式。 实施例

List<String> lines = Arrays.asList("spring", "node", "mkyong");
//Here pass your collection and filter as per your requirement
List<String> result = lines.stream()                 
       .filter(line -> !"mkyong".equals(line))     
       .collect(Collectors.toList());

答案 2 :(得分:0)

您可以将title默认为varg[0],如果author大于带有三元组的varg.length,则设为boolean。我更喜欢带索引计数器的标准循环(因为否则你必须再次搜索以确定索引)。接下来,您需要在声明未找到标题之前完成循环(我将使用author来维护该状态)。接下来,在检查书籍作者之前,您在逻辑上需要一个或(不是xor)来检查static void bookSearch(String... varg) { String title = varg[0], author = varg.length > 1 ? varg[1] : ""; boolean found = false; for (int i = 0; i < bookList.size(); i++) { Book book = bookList.get(i); if (book.getTitle().equals(title) && (author.isEmpty() || book.getAuthor().getName().equals(author))) { System.out.printf("\"%s\" found at: %d%n", title, i); found = true; break; } } if (!found) { System.out.printf("cant find \"%s\"%n", title); } } 参数是否存在而不是空。我更喜欢格式化的io。像,

CASE

答案 3 :(得分:0)

除了使用lambda表达式之外,使代码更短的其他方法是为equals类实现Book方法,您可以在其中比较两个Book对象的相等性他们的头衔和作者。然后代替:

if (book.getTitle().equals(title)) { 
     if (author.isEmpty() ^ (book.getAuthor().getfName() == author)) {

            System.out.println(" \"" + title + "\" founded at: "
                    + bookList.indexOf(book));
            break;
        }// end of if

你可以使用:

Book searchForBook = new Book();
    searchForBook.setAuthor(author); //ins
    searchForBook.setTitle(title);
    for (Book book : bookList) {
        if (book.equals(searchForBook)){
            System.out.println(" \"" + title + "\" found at: "
                    + bookList.indexOf(book));
            break;
        } 

如果在Book类中添加适当的构造函数,也可以仅创建对象searchForBook一行。

排序 ArrayList - 您可以Book实施Comparable并使用Collections.sort(bookList)或使用Comparator代替Comparator使用{{ 1}}并在使用集合之前再次使用Collections.sort,以便按照您想要的方式对其进行排序。

答案 4 :(得分:0)

您的代码可以缩短为:

static void bookSearch (String... varg) { 
    String author = "";
    String title = varg[0]; 
    if (varg.length > 1) {                            
        author = varg[1];
    } 
    for (Book book : bookList) { 
        if (book.getTitle().equals (title)) && (author.isEmpty() || (book.getAuthor().getfName() == author)) {
                System.out.println(" \"" + title + "\" founded at: " + bookList.indexOf(book));
                return;
        }
    } 
    System.out.println("cant find \"" + title);
} 
  • 标题不需要在if和else分支中。只需初始化声明。
  • 如果您愿意,可以从Elliot获取三元运算符
  • 你的外部如果只有内在的if(标题/作者)。这可以用&amp;&amp;来代替。
  • 回来而不是破碎。
  • 过早回归,你不再需要别人了。

可能首选布尔谓词'匹配',它在Book类中执行相同的操作。排序可能是一个好主意,如果您不必经常采用不同的标准,并且如果您搜索多本书 - 那么它可以获得回报。

布尔返回或找到书籍的索引的返回可能更灵活。但是为了报告索引,我会使用经典的for循环,你可以通过相同的迭代得到它。

返回索引将允许删除System.outs,以便调用者可以决定如何处理事件:通过net订购书籍,打印到stdout,使用Swing或JavaFX或其他任何方式输出。

纯粹的compareTo将允许高效的搜索算法在大型列表中快速,顺畅地集成新的Stream集合中的许多书籍。

使用varg对我来说似乎不是一个好主意,因为它为获取参数顺序错误打开了大门。

int bookSearch (String title, Optional[String] author) { 

更清楚地表达了您的需求 - 许多IDE支持参数名称。