[英]I am getting unexpected behaviour when using Java Streams and Scanners
我最近看到一个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;
}
现在整个程序运行正常,但是在搜索书籍时,我遇到了Scanner的意外行为。 这是我遇到的直接输入/输出行为:
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次。 我该如何缓解这种情况? 是什么导致这种情况发生?
这是因为在您的Stream
调用next()
,因此对于Stream
中的每个Book
对象,将对调用filter中的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()
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.