How to deep copy an object array of multiple classes - java

As the title suggest, how do I do that? I have searched everywhere in the internet, maybe I didn't search for the right word or something. But please help me.
Object[] FlyingObject = new FlyingObject[3];
FlyingObject[0] = new Helicopter();
FlyingObject[1] = new Airplane();
FlyingObject[2] = new Drone();
Public static Object[] CopyFlyingObject(Object[] C){
Object FlyingObjectCopy = new Object(C.length);
// ...I got no idea how to continue from here
}
Using clone() is not allowed and you aren't allowed to find the name of the class either. I have copy constructor in my other classes but I have no idea how to call it when we're using object, especially with an object array with unknown classes throughout the array.
Edit:
My Subclass code
'''java
int speed;
double price;
Helicopter(){
speed = 0;
price = 0.0;
}
Helicopter(Helicopter c){
speed = c.speed;
price = c.price;
}
public Airplane extends Helicopter{
String brand;
Airplane(){
super();
brand = "";
}
Airplane(Airplane c){
super(C);
brand = c.brand;
}
public String getBrand(){
return brand;
}
}
public Drone{
//practically the same for here
}
'''

Related

Class instance assistance

I am working on a program that is supposed to implement an electronic store. I had to create 3 classes (desktop, laptop and fridge) with specific defined functionality which I did. I am stuck on how to create the Electronic store class in which the constructor for this class
must create three instances of each of the previous three classes (9 items in total, using the
constructors defined in those classes) and store them within the ElectronicStore instance being created. I am unsure on how to do the above and would appreciate assistance. Below is what I have gotten so far.
// Desktop class
public class Desktop{
double speed = 0;
int ram, storage = 0;
boolean storageType;
public Desktop(double s, int r, int p, boolean t){
speed = s;
ram = r;
storage = p;
storageType = false;
}
// This is a String representation of the Desktop object
//#Override
public String toString(){
return "#"+speed+"#"+ram+"#"+storage;
}
}
// Laptop class
public class Laptop{
double CPU;
int RAM, storage, size;
boolean storeType;
public Laptop(double C, int R, int st, int si){
CPU = C;
RAM = R;
storage = st;
size = si;
storeType = false;
}
// This is a String representation of the Desktop object
public String toString(){
return "#"+CPU+"#"+RAM+"#"+storage+"#"+size;
}
}
// Fridge class
public class Fridge{
double fridge;
boolean freezer;
String color;
public String toString(){
return "#"+fridge+"#"+color;
}
}
// ElectronicStore class (which i am stuck with)
public class ElectronicStore{
public ElectronicStore()
{}
}
You create an instance of a class like so:
Desktop desktopOne = new Desktop(x, y, z);
To store them you can either have class variables (like you have for speed, ram) etc., or you could use a data structure like a list. Further clarification needed on that point.
I think it should be something like this
public class ElectronicStore{
private ArrayList<Fridge> fridges = new ArrayList<>();
public ElectronicStore()
{
Fridge fridge1 = new Fridge();
Fridge fridge2 = new Fridge();
Fridge frigde3 = new Fridge();
fridges.add(fridge1);
fridges.add(fridge2);
fridges.add(fridge3);
...
}
}
And you have to do the same thing to create the other objects.

How do i add together values from all objects of a class in java?

I am trying to retrieve certain values from multiple objects under the same class. I have used a for each loop to iterate through each object, and would like to create an aggregated total, representing the rating and the cost of the item from the objects.
The For Each loop in my parent class:
for (Song songObj : Song.returnSongs()) {
totalSongCost += Double.parseDouble(songObj.getPrice());
totalSongRating += Integer.parseInt(songObj.getRating());
}
The Child class ArrayList meant to store objects:
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;
}
When I compile the code I get an error message saying that an object cannot be converted to song. Is there a way to fix this, or an easier way to accomplish the same task?
If you've ever read the docs, you will know that ArrayList is actually a generic class. That means you can give ArrayList a type.
The type of stuff that an array list can store depends on what type you gave it. But if you don't give it any type, it stores Objects! Here,
for (Song songObj : Song.returnSongs()) {
you want to get Song objects from an array list of Object objects, which makes no sense to the compiler. As a result, the error appears.
The solution to this problem is of course, give the array list a type so that it knows what type it should store.
Change this
private static ArrayList songArray = new ArrayList();
to this:
private static ArrayList<Song> songArray = new ArrayList<>();
and change this:
public static ArrayList returnSongs() {
to this:
public static ArrayList<Song> returnSongs() {
ArrayList is a generic class. This means you can specify what class type it is meant to work with. if you change this:
private static ArrayList songArray = new ArrayList();
to this:
private static ArrayList<Song> songArray = new ArrayList<Song>();
Then the ArrayList class will understand that you're working with instances of Song.
Edit: as Jim Garrison pointed out, your returnSongs() method should also be changed to specify the class type in the same way.
public static ArrayList<Song> returnSongs() { ...
It's a little unusual to have the Song class be responsible for keeping track of all of the songs within the application. That seems outside of the responsibility of that class, and perhaps better suited to be handled within a different class, either within your parent class or a new type specially defined.
Additionally, be careful when using types like List and ArrayList. As your compiler will warn you, these require type parameters in angle brackets (i.e. List<Type>). You should make it a habit of addressing all compiler warnings, and of always specifying type parameters for generic types like List. In cases where you don't define your types correctly, things start to default to Object, which leads to the issue you faced here.
Below is an example of what this could look like, restructured to keep the Song class solely for attributes of the song itself:
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));
}
}
Your song class would simply be this:
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; }
}

Problems writing and reading ArrayList<Object> with filestream in Java

In my Android application, I have a list of custom objects
ArrayList<Poke> pcList = new ArrayList<>();
Later in my code, I have save and load methods, that use Java OOS, and OIS to function. I have used these exact methods in other projects and know they work properly.
I believe I am having an issue with saving and loading a list of custom objects.
Here are the lines I'm calling to save, as well as load my list.
// save
oos.writeObject(pcList);
...
// load
pcList = (ArrayList<Poke>)ois.readObject();
Any ideas why I can't properly load/save with my list of custom objects?
Here is the interface that links a few similar objects:
public interface Poke {
int getNum();
String getName();
String getType();
int getValue();
boolean getShiny();
String getImageName();
}
Here is one of the similar object classes
public class BasicPoke implements Poke {
boolean shiny = false;
Random randomInt = new Random();
int iRandom = randomInt.nextInt(34 - 1) + 1;
int iShiny = randomInt.nextInt(31 - 1) + 1;
public int getNum(){
return this.iRandom;
}
public String getName(){
return this.pokeNames[iRandom-1];
}
public String getType(){
return this.pokeTypes[iRandom-1];
}
public int getValue(){
return 1;
}
public boolean getShiny() {
return (iShiny == 15);
}
public String getImageName() {
String threeDigitInteger = String.format(Locale.getDefault(),"%03d", this.getNum());
return (this.getShiny()) ? "icon"+threeDigitInteger+"s" : "icon"+threeDigitInteger;
}
String pokeNames = {"..","..",".."};
String pokeTypes = {"..","..",".."};
Please implement Serializable for the BasicPoke class. And by the way, could you tell us what issue (exception) when you load/save a list of objects?
Thanks,
Nghia

Don't understand lines and how to assign genres to objects in this class

This is the class Painting:
public class Painting {
private String genre;
public Painting() {
}
public Painting (String aGenre) {
genre = aGenre;
}
public String getGenre(){
return genre;
}
}
From this class I was trying to create 4 objects and assign each a genre which I did below.
public class PaintingGenre {
public static void main(String[] args) {
Painting [] p = new Painting [4];
p[0].genre = "Brush";
p[1].genre = "Crayon";
p[2].genre = "Pencil";
p[3].genre = "Watercolour";
}
}
However, genre is private in the java class.. is there a way to assign these genres to the four objects/ paintings without changing the genre from private to public in the java class?
I think I can somehow do that by using these lines in the java class below but I don't know what it means... could you explain these lines for me and tell me if and how I can assign genres to the paintings using these lines?
public Painting (String aGenre) {
genre = aGenre;
}
public String getGenre() {
return genre;
}
Thanks very much!
Without changing the class, the only way to set the value is via the constructor. So you'd initialize any given instance with the value:
p[0] = new PaintingGenre("Brush");
The alternative would be to add a setter to the class:
public void setGenre(String genre) {
this.genre = genre;
}
and call that on an object (if the object has already been initialized):
p[0].setGenre("Brush");
Even if your genre field was public, when you try to assign it in your current code, you would end up with a NullPointerException anyway, because just creating an array of objects does not actually create objects inside it. This is where your constructor comes in.
This function:
public Painting (String aGenre) {
genre = aGenre;
}
is called a constructor. What it does is create a new object and, in this case, take the String called "aGenre" and assign it to the object's genre field. You can use this to fill out the array you created with Paintings with the correct genres.
Painting [] p = new Painting [4];
p[0] = new Painting("Brush");
p[1] = new Painting("Crayon");
p[2] = new Painting("Pencil");
p[3] = new Painting("Watercolour");
The other function you asked about:
public String getGenre(){
return genre;
}
simply returns the genre assigned to the object you call it on. For example:
String str = p[0].getGenre(); // str now has the value "Brush"
str = p[1].getGenre(); // str now has the value "Crayon"
Usually, you don't directly access a field.
The best thing you can do is to implement Getter and Setter, like this:
public Painting (String aGenre) {
genre = aGenre;
}
public String getGenre(){
return genre;
}
With this code, you set the genre at initialization of the object.
But you'd have to edit your assignment:
Painting [] p = new Painting [4];
p[0] = new Painting("Brush");
p[1] = new Painting("Crayon");
p[2] = new Painting("Pencil");
p[3] = new Painting("Watercolour");

Calling Set / Get Methods from another Class and .java file

Alright, I'm trying to call setters and getters from another function that's inside another class, in another file. Here's what I'm getting, and I really don't know what I'm doing wrong...
Bank.java
package Bank;
import java.io.*;
import java.util.*;
public class Bank
{
public static void main (String args[]) throws FileNotFoundException
{
final String fileName = "Bank/AcctInfo.txt";
File accounts = new File(fileName);
ArrayList <Object> acctInfo = new ArrayList <Object> ();
acctInfo = setObjects(accounts);
}
public static ArrayList setObjects(File document) throws FileNotFoundException
{
ArrayList <Object> objectArray = new ArrayList <Object> ();
Scanner fileInput = new Scanner(document);
String blankInfo;
String accountType;
String customerType;
String customerName;
int accountNumber;
float balance;
int counter = 0;
while (fileInput.hasNext())
{
accountNumber = fileInput.nextInt();
blankInfo = fileInput.nextLine();
accountType = fileInput.nextLine();
customerName = fileInput.nextLine();
customerType = fileInput.nextLine();
balance = fileInput.nextFloat();
blankInfo = fileInput.nextLine();
objectArray.add(new BankAccount());
objectArray.get(counter).setAccNumber(accountNumber);
counter++;
}
return objectArray;
}
}
BankAccount.java
package Bank;
public class BankAccount extends Bank
{
private int accNumber;
private String accType;
private String cusName;
private String cusType;
private float bal;
public void setAccNumber(int accountNumber)
{
int accNumber = accountNumber;
}
public int getAccNumber()
{
return accNumber;
}
public void setAccType(String accountType)
{
String accType = accountType;
}
public String getAccType()
{
return accType;
}
public void setCusName(String customerName)
{
String cusName = customerName;
}
public String getCusName()
{
return cusName;
}
public void setCusType(String customerType)
{
String cusType = customerType;
}
public String getCusType()
{
return cusType;
}
public void setBal(float balance)
{
float bal = balance;
}
public float getBal()
{
return bal;
}
}
Errors:
Bank.java:51: error: cannot find symbol
objectArray.get(counter).setAccNumber(accountNumber);
^
symbol: method setAccNumber(int)
location: class Object
Note: .\Bank\Bank.java uses unchecked or unsafe operations.
Note: Recompile with -Xlint:unchecked for details.
1 error
It's not completed yet, but if someone can help me through that bit, it'd be a huge help...
Instead of ArrayList<Object>, use ArrayList<BankAccount>.
Object is a class that doesn't have a method with the signature setAccNumber(int) whereas BankAccount does.
The ArrayList<Object> declaration says that you're declaring an ArrayList that will have Objects inside it; since all classes inherit from Object, putting instances of BankAccount in the list is valid, but as far as the compiler is concerned, when you refer to an element inside the list, it's an Object and only has the standard methods available to Object.
There are other peculiarities in your class too (e.g. in your setter methods, you declare a new variable and assign to it, inside of assigning it to a field). I would recommend revisiting your course lecture notes if available. There's an online free PDF called Java Precisely which is a very concise look at Java - the free version is up to Java 5 I think, but it's enough to cover the topics here.
Because you're doing this:
ArrayList <Object> objectArray = new ArrayList <Object> ();
the list there doesn't know what the things inside are, because you said they are Object.
if you make that
ArrayList <BankAccount> objectArray = new ArrayList <BankAccount> ();
it should work like you expect.
If you want to use the methods of BankAccount on the items of your ArrayList, you have to specify that it is a list of BankAccounts. Speficically, the line
ArrayList <Object> objectArray = new ArrayList <Object> ();
should really be
ArrayList <BankAccount> objectArray = new ArrayList <BankAccount>();
You can think of generics as specifying what you have a list of. So for the first example, you can read it as "An ArrayList of Objects." Since you don't know if they are BankAccounts or not, you don't know if you can call settAccNumber() on them.
For the second example, you can read it as "An ArrayList of BankAccounts." In this case you know that they are BankAccounts, so you know that you can call setAccNumber() on them.
Here's a lesson on generics, since you don't seem to quite have the hang of them.
Here's the oracle documentation on them as well.
Other answers correctly suggest using ArrayList<BankAccount>
If (for whatever strange reason) you cannot or do not want to do it, then you need to implicitly cast the retrieved list element to BankAccount type.
Your
objectArray.get(counter).setAccNumber(accountNumber);
will become
((BankAccount)objectArray.get(counter)).setAccNumber(accountNumber);

Categories