Перебор объектов хранящихся в ArayList, который храниться в HashMap - Java
Подскажите пожалуйста как исправить ошибку. Необходимо отобразить значения полей объектов item которые хранятся в ArrayList monthReport. monthReport в свою очередь храниться в HashMap monthReports. Перебор HashMap получилось сделать, а вот перебор внутри ArrayList поему-то не получается. Ошибка IDE: java: for-each not applicable to expression type required: array or java.lang.Iterable found: java.util.Map.Entry<java.lang.Integer,java.util.ArrayList>
public class ReadAndShow {
private String name;
private String isExpence;
private String price;
private String quantity;
Map<Integer, ArrayList> monthReports = new HashMap<>(); // Все месячные отчеты
ArrayList<Item> monthReport = new ArrayList<>(); // Очет за месяц
ReadAndShow(String name, String isExpense, String price, String quantity) {
this.name = name;
this.isExpence = isExpense;
this.price = price;
this.quantity = quantity;
}
public void readFileContentsOrNull() {
for (int i = 1; i <= 3; i++) {
String address = "resources/m.20210" + i + ".csv";
try {
BufferedReader bReader = new BufferedReader(new FileReader(address));
String line;
while ((line = bReader.readLine()) != null) {
String razdel = ",";
monthReport.add(new Item(line.split(razdel)[0], line.split(razdel)[1], line.split(razdel)[2], line.split(razdel)[2]));
monthReports.put(i, monthReport);
}
} catch (IOException e) {
System.out.println("Невозможно прочитать файл с месячным отчётом. Возможно, файл не находится в нужной директории.");
}
}
}
public void showReports() {
for (Map.Entry <Integer, ArrayList> monthReport : monthReports.entrySet()) {
for (Item item: monthReport){ // в этой строке ошибка
System.out.println(item.giveName());
}
}
}
}
Ответы (1 шт):
Вам нужно типизировать ArrayList в Map. Дженерик вполне может быть вложенный. monthReports.entrySet() - этот вызов возвращает entrySet, который по сути является пара (один ключ-значение из Map), а вы делаете так: for (Item item: monthReport), таким образом вы пытаетесь привести entrySet к Item , коим он не является. Пробуйте так:
public class ReadAndShow {
private String name;
private String isExpence;
private String price;
private String quantity;
private Map<Integer, List<Item>> monthReports = new HashMap<>(); // Все месячные отчеты
private List<Item> monthReport = new ArrayList<>(); // Очет за месяц
ReadAndShow(String name, String isExpense, String price, String quantity) {
this.name = name;
this.isExpence = isExpense;
this.price = price;
this.quantity = quantity;
}
public void readFileContentsOrNull() {
try {
for (int i = 1; i <= 3; i++) {
Scanner scanner = new Scanner(new File("resources/m.20210" + i + ".csv"));
while (scanner.hasNext()) {
String[] split = scanner.next().split(",");
monthReport.add(new Item(split[0], split[1], split[2], split[2]));
monthReports.put(i, monthReport);
}
}
} catch (FileNotFoundException e) {
System.out.println("Невозможно прочитать файл с месячным отчётом. Возможно, файл не находится в нужной директории.");
}
}
public void showReports() {
for (Map.Entry<Integer, List<Item>> monthReport : monthReports.entrySet()) {
System.out.println(monthReport.getKey());
for (Item item : monthReport.getValue()) {
System.out.println(item.giveName());
}
}
}
}
Кроме того,вызывать каждый раз вызывать метод split, создавая массив, - плохая идея. Использование ридеров - также не очень хорошая идея. Разумеется, это будет работать, однако читаемость кода оставляет желать лучшего. Их использование должно быть обусловленно задачей, потому как это в целом более гибкий и управляемый инструмент. В любых других "стандартных" случаях стоит использовать более высокоуровневые инструменты, к примеру, сканер.
И последнее... Ваш класс собрал в себе все, что только можно было придумать и затолкать. Так делать нельзя, настоятельно рекомендую реорганизовать код, пока еще не поздно))