Сегодня сидел разбирался с нововведениями Java 8. Когда попробовал на практике, сразу столкнулся с ошибкой. Наверное, я чего-то не знаю. Объясните, пожалуйста, что не так.
Вот такой код:
private boolean test( String line )
{
String[] words = line.split(" ");
Stream
Если массив controlWords имеет размер > 1, то всё время получаю ошибку
java.lang.IllegalStateException: stream has already been operated upon
or closed
Если же метод чуть-чуть видоизменить, то проблема исчезнет:
private boolean test( String line )
{
String[] words = line.split(" ");
//Stream
Ответ
Как верно отметил @kofemann, Stream — одноразовая штука. В этом плане он похож на Iterator. Чтобы использовать его несколько раз, нужно создавать новый Stream. Если вы по какой-то причине хотите создание Stream вынести наружу (например, чтобы вам Stream передавали параметром), но при этом вам он нужен несколько раз, рекомендуется использовать Supplier
private boolean test(String line) {
String[] words = line.split(" ");
Supplier
Ещё обратите внимание, что есть метод Arrays.stream(), поэтому вам необязательно заворачивать сперва слова в список:
Supplier
Наконец, заметьте, что ваша задача решается гораздо легче старыми способами без Stream API:
private boolean test(String line) {
List
Однако можно повернуть в другую сторону и уже сам цикл for свернуть в Stream из controlWords
private boolean test(String line) {
List
Тут можно заменить лямбду на ссылку:
private boolean test(String line) {
List
И даже заинлайнить words (после инлайнинга он всё равно один раз вычисляется!)
private boolean test(String line) {
return Arrays.stream(controlWords).allMatch(Arrays.asList(line.split(" "))::contains);
}
Комментариев нет:
Отправить комментарий