Как исправить: Exception in thread "main" java.util.NoSuchElementException?
У меня сборник решения задач лабораторных с общим интерфейсом. Когда я запускаю прогу, то первый класс отрабатывает как надо, а на следующем сразу же ложится доходя до str.nextInt()
'''
package tasks;
import java.util.Arrays;
import java.util.List;
public class Main{
public static void main(String[] args) {
TaskInterface[] taskArray = {new Task1, new Task2(), new Task3(), new Task5(), new Task6(), new Task7(), new Task8(), new Task10(), new Task11()};
List<TaskInterface> taskList = Arrays.asList(taskArray);
for( TaskInterface t : taskList) {
t.execute();
}
}
}
'''
'''
package tasks;
import java.util.ArrayList;
import java.util.Scanner;
public class Task2 implements TaskInterface{
public void execute() {
System.out.print("Введите число массива: ");
Scanner str = new Scanner(System.in);
int n = str.nextInt();
ArrayList<Integer> numbers = new ArrayList<Integer>();
for(int i = 0; i < n; i++){
System.out.print("Введите числа массива: ");
numbers.add(str.nextInt());
}
str.close();
int i = (int) (Math.random() * n);
int j = (int) (Math.random() * n);
System.out.println("Счастливые числа: " + numbers.get(i) + "," + numbers.get(j) );
}
}
''' Сама ошибка:
Подскажите пожалуйста почему так. Заранее благодарен за помощь)
Ответы (2 шт):
Возможно, остаётся перенос строки "\n" в буфере после ввода с клавиатуры в Task1. Попробуйте после каждого str.nextInt() прописывать сразу str.nextLine();
Это позволит очистить остатки ввода и впоследствии получать только введённое число.
Закрыв сканер, открытый для стандартного потока ввода System.in, вы также закрываете сам этот поток, после чего чтение данных с консоли становится невозможным.
Следовательно, НЕЛЬЗЯ закрывать сканер, открытый для общего стандартного потока ввода.
Если у вас однопоточное приложение, и задачи выполняются одна за одной, имеет смысл создать ОДИН экземпляр сканера и передавать его в ваши таски:
Scanner scanner = new Scanner(System.in);
List<TaskInterface> taskList = Arrays.asList(
new Task1(scanner), new Task2(scanner),
// ...
new TaskN(scanner)
);
t.forEach(TaskInterface::execute);
Можно создать общий абстрактный класс для задач:
public abstract class AbstractTask implements TaskInterface {
protected Scanner scanner;
public AbstractTask(Scanner scanner) {
this.scanner = scanner;
}
}
Затем все конкретные задачи будут унаследованы от AbstractTask:
public class Task1 extends AbstractTask {
public Task1(Scanner scanner) {
super(scanner);
}
@Override
public void execute() {
int num = scanner.nextInt();
System.out.println("Чётное? " + (num % 2 == 0 ? "Да" : "Нет"));
}
}
и т.д.
Ссылки на аналогичные вопросы:
