#java #object #foreach #accumulate
#java #объект #foreach #накапливать
Вопрос:
Я пытаюсь извлечь определенные значения из нескольких объектов одного и того же класса. Я использовал цикл for each для перебора каждого объекта и хотел бы создать агрегированный итог, представляющий рейтинг и стоимость элемента из объектов.
Для каждого цикла в моем родительском классе:
for (Song songObj : Song.returnSongs()) {
totalSongCost = Double.parseDouble(songObj.getPrice());
totalSongRating = Integer.parseInt(songObj.getRating());
}
Дочерний класс ArrayList предназначен для хранения объектов:
private int rating;
private String title;
private double price;
private boolean favorite;
private static int counter = 0;
private static ArrayList songArray = new ArrayList();
/**
* Constructor for objects of class Song
*/
public Song()
{
// initialise instance variables
rating = 0;
title = "";
price = 0.0;
counter ;
songArray.add(this);
}
public static ArrayList returnSongs() {
return songArray;
}
Когда я компилирую код, я получаю сообщение об ошибке, в котором говорится, что объект не может быть преобразован в песню. Есть ли способ исправить это или более простой способ выполнить ту же задачу?
Комментарии:
1. Вероятно, у вас должен быть другой класс, например «Album», который содержит список композиций, потому что ваша текущая реализация не будет работать. Вы не можете добавить объект, содержащий список (например, песню), в список (который находится в песне).
2. @BenjaminLowry Объект не содержит списка, потому что он
static
и, следовательно, не принадлежит какому-либо объекту.3. @ajb Ах да, мой плохой, не видел, что он был статическим.
Ответ №1:
Если вы когда-либо читали документы, вы знаете, что ArrayList
это на самом деле универсальный класс. Это означает, что вы можете указать ArrayList
тип.
Тип материала, который может хранить список массивов, зависит от того, какой тип вы ему присвоили. Но если вы не задаете ему никакого типа, он сохраняет Object
s! Здесь,
for (Song songObj : Song.returnSongs()) {
вы хотите получить Song
объекты из списка Object
объектов массива, что не имеет смысла для компилятора. В результате появляется ошибка.
Решение этой проблемы, конечно, заключается в том, чтобы присвоить списку массивов тип, чтобы он знал, какой тип он должен хранить.
Измените это
private static ArrayList songArray = new ArrayList();
к этому:
private static ArrayList<Song> songArray = new ArrayList<>();
и измените это:
public static ArrayList returnSongs() {
к этому:
public static ArrayList<Song> returnSongs() {
Комментарии:
1. По какой-то причине, когда я делаю это, я могу получить доступ только к самому последнему объекту, а не ко всем объектам класса, почему это?
2. Пожалуйста, убедитесь, что
songArray
это объявленоstatic
. @user6828298
Ответ №2:
ArrayList
является универсальным классом. Это означает, что вы можете указать, с каким типом класса он предназначен для работы. если вы измените это:
private static ArrayList songArray = new ArrayList();
к этому:
private static ArrayList<Song> songArray = new ArrayList<Song>();
Тогда класс ArrayList поймет, что вы работаете с экземплярами Song .
Редактировать: как указал Джим Гаррисон, ваш returnSongs()
метод также следует изменить, чтобы указать тип класса таким же образом.
public static ArrayList<Song> returnSongs() { ...
Комментарии:
1. Не забудьте также изменить
public static ArrayList returnSongs()
наpublic static ArrayList<Song> returnSongs()
и общий тип в точке, гдеreturnSongs()
вызывается.
Ответ №3:
Немного необычно Song
, когда класс отвечает за отслеживание всех композиций в приложении. Это, по-видимому, выходит за рамки ответственности этого класса и, возможно, лучше подходит для обработки в другом классе, либо в вашем родительском классе, либо в новом типе, специально определенном.
Кроме того, будьте осторожны при использовании типов, таких как List
и ArrayList
. Как предупредит вас ваш компилятор, для этого требуются параметры типа в угловых скобках (т.Е. List<Type>
). Вы должны выработать привычку обращаться ко всем предупреждениям компилятора и всегда указывать параметры типа для универсальных типов, таких как List
. В тех случаях, когда вы неправильно определяете свои типы, по умолчанию все становится Object
равным , что приводит к проблеме, с которой вы столкнулись здесь.
Ниже приведен пример того, как это может выглядеть, реструктурированный, чтобы сохранить Song
класс исключительно для атрибутов самой песни:
import java.util.ArrayList;
import java.util.List;
public class Parent {
private static List<Song> songs = new ArrayList<Song>();
private static double totalSongCost = 0.0;
private static int totalSongRating = 0;
public static void main(String[] args) {
populateSongs();
for (Song song : songs) {
totalSongCost = songObj.getPrice();
totalSongRating = songObj.getRating();
}
}
private void populateSongs() {
songs.add(new Song(5, "Hey Jude", 12.5));
songs.add(new Song(4, "Angie", 11.5));
songs.add(new Song(0, "Other", 10.5));
}
}
Ваш класс song будет просто таким:
public class Song {
private int rating = 0;
private String title = "";
private double price = 0.0;
public Song(int rating, String title, double price) {
this.rating = rating;
this.title = title;
this.price = price;
}
// Compressed for brevity
public int getRating() { return rating; }
public String getTitle() { return title; }
public double getPrice() { return price; }
}