Print List in Java - java

I'm newbie in Java. I'm not sure why line my2.print_list(); is printing only object my2. I want to print every time whole list of objects. I'm adding every object to list in constructor. I'm 90% sure that for loop in function print_list is good. The compiler shows no problems. I'll appreciate all help.
public class Main {
public static void main(String[] args) {
// write your code here
rectangle my = new rectangle(5);
rectangle my1 = new rectangle(3,6);
rectangle my2 = new rectangle(10,7);
System.out.println( my2.getCounter());
my2.print_list(); ////////////////////<- described line
}
}
/// my class rectangle
import java.util.ArrayList;
import java.util.List;
public class rectangle {
public static int counter =0;
public int x;
public int y;
public List<rectangle> List = new ArrayList<rectangle>();
public rectangle(int x, int y) {
this.x = x;
this.y = y;
System.out.println("Rec");
List.add(this);
counter++;
}
public rectangle(int x) {
this.x = x;
this.y = x;
System.out.println("Sqr");
List.add(this);
counter++;
}
#Override
public String toString() {
return "x->"+x+" y->"+y+" Field: "+(x*y);
}
public void print_list()
{
for(rectangle x : List)
{
System.out.println(x);
}
}

Every instance of your class has its' own instance of List. Make it static if it should be shared (which is the only way your List will be populated). Also, please rename the variable List (it looks exactly like the interface java.util.List). Also, there's no reason to make it public.
private static List<rectangle> myList = new ArrayList<rectangle>();
And then change print_list like
public void printList()
{
for(rectangle x : myList)
{
System.out.println(x);
}
}
Also, the class name should be Rectangle (to follow Java naming conventions).

Change
public List<rectangle> List = new ArrayList<rectangle>();
to
public static List<rectangle> List = new ArrayList<rectangle>();
So there's only one instance of List.

Related

How to clone an object from an array of objects with different types

I've got this code:
int width = 1280;
int height = 720;
List<ElectronicDevice> devices = new ArrayList<ElectronicDevice>();
class ElectronicDevice {
int x;
int y;
// ...
}
class EClock extends ElectronicDevice {
int hz;
EClock(int x, int y, int clock) {
this.x = x;
this.y = y;
this.hz = hz;
}
// ...
}
class EBulb extends ElectronicDevice {
EClock(int x, int y) {
this.x = x;
this.y = y;
}
// ...
}
class ToolbarElement {
ElectronicDevice dev;
ToolbarElement(ElectronicDevice dev) {
this.dev = dev;
}
public void addDevice() {
// somehow add a copy of `dev` to the `devices` list
}
}
List<ToolbarElement> elements = new ArrayList<ToolbarElement>();
elements.add(new EClock(width/2, height/2, 5));
elements.add(new EBulb(width/2, height/2));
elements.get(0).addDevice();
I need to add a copy of ToolbarElement dev to devices, but I don't know how. It needs to be a deep copy. In the program I don't know the constructors of all devices, I'd like to just deep clone dev into devices.
I tried adding implements Cloneable to the ElectronicDevice class, but then I would need to add that and a clone() method to every class that extents ElectronicDevice.
After adding the implements Cloneable to ElectronicDevice it mostly worked, but all the clocks had desynchronized after adding more than 1 of them (this is a graphical application in Processing, every class that extends ElectronicDevice can have a behavior() method which specifies how it behaves and the clock oscillates between 0 and 1 with the frequency of hz Hz.)
This was my addDevice() implementation:
// In ElectronicDevice
class ElectronicDevice implements Cloneable {
// ...
protected Object clone() throws CloneNotSupportedException {
return super.clone();
}
// end of class code
}
// In ToolbarElement
class ToolbarElement {
// ...
public void addDevice() {
try { devices.add((ElectronicDevice)object.clone()); }
catch (CloneNotSupportedException e) { e.printStackTrace(); }
}
// end of class code
}
Is there any solution that wouldn't require modifying every single class that extends ElectronicDevice?

if I create a child class from within a parent class, the parent class gets created again the Java

public class Map
{
public Map()
{
}
int[][] Map = {{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}};
}
public class Unit extends Map
{
int x, y, num;
public Unit(int x, int y, int num)
{
this.x = x;
this.y = y;
this.num = num;
}
public void Set()
{
super.Map[x][y] = num;
}
}
public class Main
{
public static void main(String[] args)
{
Unit a = new Unit(1,1,5);
a.Set();
Unit b = new Unit(2,2,10);
b.Set();
}
}
If you run this code, a.Map and b.Map are made separately. I wish a parent and a b would like to participate together. Is there any way?
By default, when you make new classes from different classes of class, are the parent classes made as many as that number?
Unit doesn't seem like a natural sub-class of Map. Before you write class Unit extends Map you should be asking yourself whether a Unit is a kind of a Map. I don't think it is.
If you want to have multiple Units on a single Map, create a single Map instance, and add each Unit instance you create to that Map.
Here's a partial example:
public class Map {
int[][] map = {{0,0,0,0,0},
{0,0,0,0,0},
{0,0,0,0,0}};
public setUnit (Unit unit) {
map[unit.getX()][unit.getY()] = unit.getNum();
}
}
public class Unit
{
int x, y, num;
public Unit(int x, int y, int num)
{
this.x = x;
this.y = y;
this.num = num;
}
}
public class Main
{
public static void main(String[] args)
{
Map m = new Map ();
Unit a = new Unit(1,1,5);
map.setUnit(a);
Unit b = new Unit(2,2,10);
map.setUnit(b);
}
}
If the Unit objects need access to the Map that contains them, you can consider adding a Map map instance variable to the Unit class.

Having multiple animals in the same field in foxes and rabbits simulation

I'm making a new version of this foxes and rabbits Simulation - https://www.youtube.com/watch?v=F7KtfGELZsM
What I would like to do is be able to store multiple animals within the same square of the grid, not just one at a time. At the moment, Animals are stored in a 2d multidimensional array Animal[x][y] which if an animal is already in this location then it will replaced with the new animal. Perhaps this needs to be changed to a HashMap or something similar? For example -
http://comscigate.com/HW/cs302/BlueJ/projects/chapter10/foxes-and-rabbits-v2/Field.java
Potentially something like this:
// Storage for the animals.
private List<Field> field;
private List<List<Animal>> animalsList;
public void place(Animal animal)
{
Location location = animal.getLocation();
animalsList = new ArrayList<List<Animal>>();
field = new ArrayList<Animal>;
field.add(Field(location.getRow(), location.getCol()));
animalsList.add(field, animal);
}
Id use a simple storage system. Lets assume you have a 10*10 field :
You need a List<List<Animal>> list=new ArrayList<List<Animal>>();
You need 100 spaces that are all empty(well, you could also use an array) :
for (int i=0; i < 100; i++) {
list.add(new ArrayList<Animal>());
}
Your method :
public void addAt(int x, int y, Animal a) {
int w=10; //WIDTH
int h=10; //HEIGHT
List<Animal> animals_here=list.get(y*h+x);
animals_here.add(a);
list.put(y*h+x,animals_here);
}
if youd like to extract the position from an index :
- x=index%h;
- y=index/h; //Integer divison, no doubles/floats !
Another, probably easier accessable attempt would be a Map :
class Point {
public int x;
public int y;
public Point(int x, int y) {
this.x=x;
this.y=y;
}
}
Map<Point,List<Animal>> map=new HashMap();
public void addAt(int x, int y,Animal a) {
if (map.get(new Point(x,y))==null) {
List<Animal> animals_here=new ArrayList<Animal>();
animals_here.add(a);
map.put(new Point(x,y),animals_here);
}
else {
List<Animal> animals_here=map.get(new Point(x,y));
animals_here.add(a);
map.put(new Point(x,y),animals_here);
}
}
EDIT :
Efficiency :
CPU :
- Solution 1 : Indices are calculated each time, not so easy acess
- Solution 2 : Map is very fast.
RAM :
- Solution 1 : Less animals than cells : -, because you have unused cells
More animals than cells : +, because almost every cell will be used and the keys havent to be stored
- Solution 2 : Less animals than cells : +, because they are saved with keys
More animals than cells : -, because keys are always stored too
About the code you provided on GitHub :
Make another class for the field.
class Field {
public Map<Point, List<Animal>> map;
public int w,h;
public Field(int w, int h) {
this.w=w;
this.h=h;
map=new HashMap<Point, List<Animal>>();
}
public void addAnimal(int x, int y) {
if (map.get(new Point(x, y)) == null) {
List<Animal> animals_here = new ArrayList<Animal>();
animals_here.add(animal);
map.put(new Point(x, y), animals_here); //Set
}
else {
List<Animal> animals_here = map.get(new Point(x, y));
animals_here.add(animal);
map.put(new Point(x, y), animals_here); //Overwrite
}
}
public List<Animal> animalsAt(int x, int y) { //If it returns null, there isnt an animal
return map.get(new Point(x,y));
}
public void doStuff() {
for (int x=0; x < w; x++) {
for (int y=0; y < h; y++) {
List<Animal> animals_there=animalsAt(x,y);
if (animals_there != null) {
for (Animal a:animals_there) {
//Do your stuff
}
}
}
}
}
}
The point class is only to store two values : x and y. You dont need anything more.
class Point {
public int x;
public int y;
public Point(int x, int y) {
this.x=x;
this.y=y;
}
}
Dont make all vars private. Then you wont have to use getters and setters, you can access them easier.
BUT I THINK ITS MAYBE EASIEST TO STORE THE POSITION IN EVERY ANIMAL((-)very memory inefficent, but since you're not going to have 1000000 animals, it will be enough)
class Animal {
public String type;
public Location location;
public Animal(String type, Location location) {
this.type=type;
this.location=location;
}
}
//When you want to have specific methods(and vars) for different animals, create subclasses :
class Lion extends Animal {
public Lion(String type, Location location) {
super(type,location);
}
public void live(List<Object> other_animals) {
List<Integer> toRemove=new ArrayList<Integer>();
int index=0;
for (Object o:other_animals) {
if (o instanceof Mouse) {
Mouse m=(Mouse)o;
if (m.location.equals(this.location)) {
toRemove.add(index);
}
}
index++;
}
}
}
class Mouse extends Animal {
public Mouse(String type, Location location) {
super(type,location);
}
}
//Your field :
class Field {
public List<Object> animals;
public Field() {
animals=new ArrayList<Object>();
}
public void add(Object o) {
animals.add(o);
}
public List<Object> getAt(Location l) {
List<Object> animals_there=new ArrayList<Object>();
for (Object o:animals) {
if (((Animal)(o)).location.equals(l)) {
animals_there.add(o);
}
}
return animals_there;
}
}

Display elements in the arrayList using method from the superclass java

I'm trying to print out elements from the List in the main method. However I have a problem, because Eclipse says that the method I've implemented in a superclass is not defined for my type.
There is the superclass, there are three other which extend this one and I've imported java.util.List and java.util.ArrayList;
The reason I need to implement method is because my mentor asked that, however I know just using for-loop will be enough in the main method.
Superclass:
import java.util.ArrayList;
import java.util.List;
public class Figura {
private int x;
private int y;
private String name;
private int index;
public Figura (String name, int x, int y) {
this.name = name;
this.x = x;
this.y = y;
}
public int getX() {
return x;
}
public void setX(int x) {
this.x = x;
}
public int getY() {
return y;
}
public void setY(int y) {
this.y = y;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public void show(Figura p) {
System.out.println(p.toString());
}
public void showElements (List <Figura> m) {
Figura p = m.get(index);
for (int i = 0; i < m.size(); i++){
System.out.println(m.get(i));
}
}
}
I will not show here all other classes I've created (there classes are simple figures, which extend all the superclass). But the main problem is here:
import java.util.ArrayList;
import java.util.List;
public class zadanie2 {
public static void main(String[] args) {
// TODO Auto-generated method stub
List <Figura> kolekcje = new ArrayList<Figura>(10);
Punkt pr1 = new Punkt("Prostokat", 10,148,"Ciemne");
kolekcje.add(0,new Prostokat(pr1,42));
Punkt kolo1 = new Punkt("Kolo", 41,23,"Malinowe");
kolekcje.add(1,new Kolo(kolo1, 126));
Punkt pu31 = new Punkt("Punkt 3D", 45, 23,"Pomaranczowe");
kolekcje.add(2, new punkt3D(pu31, 451));
Punkt kw1 = new Punkt("Kwadrat", 215, 521,"Szary");
kolekcje.add(3, new Kwadrat(kw1, 620));
Punkt wk1 = new Punkt("Wektor", 52, 13,"Brazowy");
kolekcje.add(4, new Wektor(wk1, 41,52));
Punkt ec1 = new Punkt("Eklipsa", 52, 301, "Kremowy");
kolekcje.add(5, new Eclipsa(ec1, 22));
Punkt pr2 = new Punkt("Prostokat", 63,40,"Bialy");
kolekcje.add(6, new Prostokat(pr2,310));
Punkt kolo2 = new Punkt("Kolko",52,314,"Rozowe");
kolekcje.add(7, new Kolo(kolo2, 52));
Punkt pu32 = new Punkt("Punkcik 3D", 52,63,"Ciemno-brazowe");
kolekcje.add(8, new punkt3D(pu32, 412));
Punkt kw2 = new Punkt("Kwadracik", 52, 631,"Oliwkowy");
kolekcje.add(9, new Kwadrat(kw2,541));
Punkt wk2 = new Punkt("Wektor", 12, 71, "Czarne");
kolekcje.add(10, new Wektor(wk2, 41, 23));
int size = kolekcje.size();
//for (int i = 0; i< kolekcje.size(); i++) {
// System.out.println(kolekcje.get(i));
//}
kolekcje.showElements(kolekcje);
}
What is commented (for loop), works just fine, however showElements(List <Figura> m) method doesn't work and Eclipse shows that this method is not defined to the type List<Figura>.
Also, it suggest to cast the method like this
((Figura) kolekcje).showElements(kolekcje);
But it doesnt work either and shows the error Exception in thread "main" java.lang.ClassCastException: java.util.ArrayList cannot be cast to zadaniedomoweZadanie1.Figura
Please help!
kolekcje is a reference to ArrayList. Method showElements is a method on Figura object.
You are trying to access showElements on ArrayList, which is not available.
You will be able to access it on Figura instances, like:
kolekcje[0].showElements(kolekcje);
Also, based on what showElements is doing, you may want to consider making it static and access it like:
Figura.showElements(kolekcje);
In order to be able to call the showElements method, you need to invoke it on a Figura object. So
kolekcje.showElements(kolekcje);
will not work because kolekcje is a List, not a Figura.
Since you want to display a list of Figuras, & not just one; you would better make the showElements method static. You can call it this way:
Figura.showElements(arrayOfFiguras);
Figura.showElements()
// Display all the items of a Figura List
public static void showElements (List <Figura> m) {
for (int i = 0; i < m.size(); i++){
System.out.println(m.get(i));
}
}
You are calling the showElements() method on the ArrayList, not on the Figura object. There are two solutions to this problem, the better one in my opinion being to make the method static. As follows:
public static void showElements (List <Figura> m) {
Figura p = m.get(index);
for (int i = 0; i < m.size(); i++){
System.out.println(m.get(i));
}
Finally, change the method call from:
kolekcje.showElements(kolekcje);
to:
Figura.showElements(kolekcje);
Making the method static is important because the showElements() method is completely unrelated to the instance of the Figura object you are calling it on. But rather, it is fully dependent on the List you are passing in.
You could read more about why to use static methods here.

Objects override each other

I have the class GameObject:
public class GameObject{
private Coordinate coordinates;
public GameObject(){
coordinates = new Coordinate();
}
public void setCoordinates(int x, int y){
coordinates.x = x;
coordinates.y = y;
}
//More methods here
}
public class Coordinate{
public int x, y;
public Coordinate(){
}
public Coordinate(int x, int y){
this.x = x;
this.y = y;
}
public void setCoordinate(int x, int y){
this.x = x;
this.y = y;
}
And two classes Champion and Spell:
public class Spell extends GameObject{
//Some methods
}
public class Champion extends GameObject{
//Some methods
public Spell fireBall = new Spell();
}
And in my main class:
Champion character = new Champion();
If I call character.setCoordinates(200, 300); (just random numbers), the character goes to these exact coordinates. But the Spell fireBall also goes to (200, 300). So the coordinates in Spell are overriden by the setCoordinates(int x, int y) call to character. How is this possible?
TL;DR - Two classes from GameObject, Spell extends GameObject and Champion extends GameObject, override eachother coordinates. Why?
For full source code:
GameObject.java
Spell.java
Champion.java
Coordinate.java
Looking at your code in gitHub you have 2 methods:
//Set the coordinates for this GameObject
public void setCoordinates(int x, int y){
this.coordinates.x = x;
this.coordinates.y = y;
}
public void setCoordinates(Coordinate coordinates){
this.coordinates = coordinates;
}
If you ever use the 2nd one, then you are sharing the same instance of Coordinates so changing one will change the other
The solution is to copy the values instead
public void setCoordinates(Coordinate coordinates){
this.coordinates.x = coordinates.x;
this.coordinates.y = coordinates.y;
}
In the class Spell you set the coordinates:
this.startCoordinates = startCoordinates;
setCoordinates(this.startCoordinates);
Subsequently this code
if (getCoordinates().x - startCoordinates.x < range) {
is equivalent to
if (getCoordinates().x - getCoordinates().x < range) {
because getCoordinates() references the same object as startCoordinates does.
Your setter method just sets the reference, but it does not copy the object.

Categories

Resources