Я получаю неожиданное поведение при использовании потоков Java и сканеров - PullRequest
0 голосов
/ 07 февраля 2019

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

Я создал класс Book следующим образом:

class Book
{
    private String author, title;

    public Book setAuthor(String a)
    {
        author = a;
        return this;
    }

    public Book setTitle(String t)
    {
        title = t;
        return this;
    }

    public String getAuthor() 
    {
        return author;
    }

    public String getTitle()
    {
        return title;
    }
}

Концепция заключается в том, что пользователь может создавать несколько книг назапустите программу и затем найдите автора:

private final static int BOOK_NO = 3;
private final static SO instance = new SO(); // This is whatever you called the class

public static void main(String[] args)
{
    Book[] books = new Book[BOOK_NO];
    Scanner kybd = new Scanner(System.in);

    for(int i = 0; i < BOOK_NO; i++)
    {
        books[i] = instance.addBook(kybd, new Book());
    }

    Arrays.stream(instance.findBook(kybd, books)).forEach(o -> {
        System.out.println(o.getTitle() + " by " + o.getAuthor());
    });
}

public Book addBook(Scanner s, Book b)
{

    System.out.println("Enter the Author of this book:");
    b.setAuthor(s.next());

    System.out.println("Enter the Title of this book:");
    b.setTitle(s.next());

    return b;
}

public Book[] findBook(Scanner s, Book[] bs)
{
    System.out.println("Search a book by author:");

    List<Book> finding = Arrays .stream(bs)
            .filter(o -> o.getAuthor().equalsIgnoreCase(s.next()))
            .collect(Collectors.toList());

    System.out.println("Found " + finding.size() + " matches.");

    Book[] output = new Book[finding.size()];
    output = finding.toArray(output);
    return output;
}

Теперь вся программа работает нормально, однако у меня возникает неожиданное поведение со сканером, когда дело доходит до поиска книги.Вот прямое поведение ввода / вывода, с которым я сталкиваюсь:

Enter the Author of this book:
Foo
Enter the Title of this book:
Bar
Enter the Author of this book:
Foo
Enter the Title of this book:
FooBar
Enter the Author of this book:
Bar
Enter the Title of this book:
Foo
Search a book by author:
Foo
Foo
Foo
Found 2 matches.
Bar by Foo
FooBar by Foo

Как видите, мне приходится вводить автора книги в сканер 3 раза, прежде чем получить какой-либо результат.Как я могу смягчить это?Что является причиной этого?

1 Ответ

0 голосов
/ 07 февраля 2019

Это потому, что в вашем Stream вы вызываете next(), поэтому для каждого Book объекта в Stream к нему применяется Predicate в вызове фильтра, и next() будетназывается.Разрешите его переменной, чтобы он не вызывался более одного раза:

String book = s.next();
List<Book> finding = Arrays.stream(bs)
                           .filter(o -> o.getAuthor().equalsIgnoreCase(book))
                           .collect(Collectors.toList());

filter() принимает Predicate, который в этом случае будетбыть примерно таким:

Predicate<String> pred = str -> str.equalsIgnoreCase(s.next());

Так что каждый раз, когда он применяется, next() будет называться

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