При вызове ArrayList через объект класса: size = 0
Всем привет! Не могу получить доступ к элементам ArrayList в другом классе, через объект класса, в котором он инициализируется.
Я только учусь программировать, и не понимаю в чем дело.
В коде пометил комментариями все операции с ArrayList.
В классе Object через экземпляр класса m = new Main() в консоли m.Object_List.size() выводит 0
public class Main extends Application {
Pane canvas = new Pane();
Scene scene = new Scene(canvas);
public ArrayList<Object> Object_List = new ArrayList<>(); // Инициализация ArrayList с public
@Override
public void start(Stage stage) throws Exception {
canvas.setStyle("-fx-background-color: black;");
stage.setScene(scene);
stage.show();
stage.setFullScreenExitHint("FXGravity");
stage.setFullScreen(true);
create_object(5); // Метод для заполнения Object_List
for(Object object : Object_List) {
canvas.getChildren().add(object);
}
AnimationTimer atimer = new AnimationTimer() {
@Override
public void handle(long arg0) {
System.out.println("size: " + Object_List.size()); // size: 5
Object_List.get(0).gravity(); // Вызываем метод класса Object через экземпляр класса
}
};
atimer.start();
}
public void create_object(int size) { // Заполняем Object_List
for (int i = 0; i < size; i++) {
double x =(int)(Math.random()*1600+1);
double y = (int)(Math.random()*900+5);
int radius = 5;
int mass =(int)(Math.random()*100+100);
Object_List.add(new Object(x,y,radius,mass));
}
}
public static void main(String[] args) {
launch();
}
}
public class Object extends Pane {
final double G = 0.00006674;
float slow = 0.1f;
double VelX;
double VelY;
int mass;
Circle circle = new Circle();
Point2D position = new Point2D(150,150);
Main m = new Main(); // Создаем экзмпляр класса, в котором инициализирован Object_List
public Object (double x, double y, int radius, int mass) {
circle.setRadius(radius);
circle.setCenterX(x - radius/2);
circle.setCenterY(y - radius/2);
circle.setFill(Color.rgb(255,255,255));
this.mass=mass;
position = new Point2D(circle.getCenterX() - radius/2, circle.getCenterY() - radius/2);
getChildren().add(circle);
}
// ---------------------------------------------------------------
public void setVelX(double VelX) {
this.VelX = VelX;
}
public void setVelY(double VelY) {
this.VelY = VelY;
}
public double getVelX() {
return VelX;
}
public double getVelY() {
return VelY;
}
// ----------------------------------------------------------------
public void move() {
circle.setCenterX(circle.getCenterX() + getVelY());
circle.setCenterY(circle.getCenterY() + getVelY());
}
public void gravity() {
System.out.println("gravity() obj_lst size: " + m.Object_List.size()); // size: 0 ???
for(int i = 0; i < m.Object_List.size(); i++) {
for(int j = 0; j < m.Object_List.size(); j++) {
if (j == i) {
continue;
}
m.Object_List.get(i).setVelX(
slow*G*(m.Object_List.get(i).mass * m.Object_List.get(j).mass) /
m.Object_List.get(i).position.getX()*m.Object_List.get(j).position.getX() );
m.Object_List.get(i).setVelY(
slow*G*(m.Object_List.get(i).mass * m.Object_List.get(j).mass) /
m.Object_List.get(i).position.getY()*m.Object_List.get(j).position.getY() );
// object_1 ->> G*(m1*m2/r*r) <<- object_2
}
}
move();
}
}
Ответы (1 шт):
Вы как-то поосторожнее относитесь к инкапсуляции, правилам именования переменных и прочим базовым вещам.
Разбивайте код на классы и методы осмысленно, а не случайным образом.
Игнорирование фундаментальных простейших правил ведут к наиболее тяжелым последствиям. Именно это случилось у вас. Имея тривиальнейшую задачу, вы написали столь запутанный код, что не смогли отладить. Я немного изменил его и превратил в рабочий, но это за гранью добра и зла, простите.
По этому коду советов никаких давать не буду, просто предоставлю рабочий вариант, но в целом совет один — зайдите ко мне в профиль и почитайте мои ответы. Я стараюсь давать расширенные ответы, комментируя свои действия. Привожу наиболее простые для понимания примеры насколько это возможно в ООП. Зачастую ссылаюсь на паттерны и т.д. Попробуйте разобраться с примерами, которые я привожу. Зачастую это решение учебных задач, которые будут намного более полезны, чем этот код.
Если будут вопросы — пишите.
import java.util.ArrayList;
import java.util.List;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.Pane;
import javafx.stage.Stage;
public class Main extends Application {
private final static double G = 0.00006674;
private final static double SLOW = 0.1;
private final List<Object> objectList;
public Main() {
this.objectList = createObject(5);
}
@Override
public void start(Stage stage) throws Exception {
Pane canvas = new Pane();
Scene scene = new Scene(canvas);
canvas.setStyle("-fx-background-color: black;");
stage.setScene(scene);
stage.show();
stage.setFullScreenExitHint("FXGravity");
stage.setFullScreen(true);
for (Object object : objectList) canvas.getChildren().add(object);
AnimationTimer atimer = new AnimationTimer() {
@Override
public void handle(long arg0) {
gravity();
}
};
atimer.start();
}
private List<Object> createObject(int size) {
int radius = 5;
final List<Object> list = new ArrayList<>();
for (int i = 0; i < size; i++) {
double x =(int)(Math.random()*1600+1);
double y = (int)(Math.random()*900+5);
int mass =(int)(Math.random()*100+100);
list.add(new Object(x,y,radius,mass));
}
return list;
}
private void gravity() {
for (int i = 0; i < objectList.size(); i++) {
for (int j = 0; j < objectList.size(); j++) {
if (j == i) continue;
objectList.get(i).setVelX(SLOW * G * objectList.get(i).getMass() * objectList.get(j).getMass()
/ objectList.get(i).getPosition().getX() * objectList.get(j).getPosition().getX());
objectList.get(i).setVelY(SLOW * G * objectList.get(i).getMass() * objectList.get(j).getMass()
/ objectList.get(i).getPosition().getY() * objectList.get(j).getPosition().getY());
}
}
for (Object obj : objectList) obj.move();
}
public static void main(String[] args) {
launch();
}
}
import javafx.geometry.Point2D;
import javafx.scene.layout.Pane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
public class Object extends Pane {
private final int mass;
private double VelX, VelY;
private final Circle circle;
private Point2D position;
public Object(double x, double y, int radius, int mass) {
this.circle = new Circle();
this.position = new Point2D(150, 150);
this.mass = mass;
this.circle.setRadius(radius);
this.circle.setCenterX(x - radius / 2);
this.circle.setCenterY(y - radius / 2);
this.circle.setFill(Color.rgb(255, 255, 255));
this.position = new Point2D(circle.getCenterX() - radius / 2, circle.getCenterY() - radius / 2);
getChildren().add(circle);
}
public Point2D getPosition() {
return position;
}
public int getMass() {
return mass;
}
public void setVelX(double VelX) {
this.VelX = VelX;
}
public void setVelY(double VelY) {
this.VelY = VelY;
}
public double getVelX() {
return VelX;
}
public double getVelY() {
return VelY;
}
public void move() {
circle.setCenterX(circle.getCenterX() + getVelY());
circle.setCenterY(circle.getCenterY() + getVelY());
}
}
От меня вам большое спасибо! Это самое изящное решение моей проблемы, вопросов по коду нет - всё работает так как и должно работать!
Если вы измените формулу в методе gravity() на
double DX = objectList.get(j).circle.getCenterX() - objectList.get(i).circle.getCenterX();
double DY = objectList.get(j).circle.getCenterY() - objectList.get(i).circle.getCenterY();;
double R = Math.sqrt(DX*DX) + (DY*DY);
double FORCE = G * objectList.get(i).getMass() * objectList.get(j).getMass() / R;
double ACCELI = FORCE / objectList.get(i).getMass();
double ACCELJ = FORCE / objectList.get(j).getMass();
DX /= R;
DY /= R;
objectList.get(i).setVelX(objectList.get(i).getVelX() + ACCELI * DX);
objectList.get(i).setVelY(objectList.get(i).getVelY() + ACCELJ * DY);
objectList.get(j).setVelX(objectList.get(j).getVelX() - ACCELI * DX);
objectList.get(j).setVelY(objectList.get(j).getVelY() - ACCELJ * DY);
то сможете посмотреть на моделирование Ньютоновской гравитации :) Добавьте 50+ объектов, вместо 5.
И в методе move() измените одну букву, там в первой строчке к X прибавляется Y, а должен X к X.