Java calling an object without using parameters [closed] - java

Closed. This question needs to be more focused. It is not currently accepting answers.
Want to improve this question? Update the question so it focuses on one problem only by editing this post.
Closed 2 years ago.
Improve this question
I am new to programming. I have made this constructor:
public Attraction(int baseprice, String name) {
this.baseprice = baseprice;
this.name = name;
}
I have initialized the constructor in a different class:
Attraction attraction = new Attraction(ridename, price)
I would like to use this data in a third class without having to pass in parameters, so it would look like this:
Attraction attraction = new Attraction()
This would then allow me to use getters and setters to change the existing data in the attraction object. However, this is not possible at the moment because I have to pass in the name and price even though I want to use the existing data.
Can anyone show me what to do? Any help would be appreciated.

You seem to misunderstand how java works.
The new name of the keyword to make new objects wasn't chosen at random: Every time you write new Attraction([doesn't matter what goes here]), a well, new object is made (this object is then 'an instance' of Attraction). Each individual object has its own set of the fields. There is also no 'one instance to rule them all' - there is no way to just go: "Give me the instance I created last" or "Give me the one instance; I never want more than one to exist".
You need to pass the reference around:
Attraction a = new Attraction(ridename, price);
... do stuff
someOtherMethod(a); // pass 'a' around via a parameter, or...
return a; // pass 'a' around by returning it, or...
this.someFieldOfTypeAttaction = a; // pass 'a' around by assigning it to a field.
many ways to do it.
You can also program 'give me the attraction I created last' or even 'there will only ever be a single attraction', but this doesn't sound right here: Surely you are planning to have many different attractions, and in general having global mutable state leads to spaghetti code that is hard to debug and which is prone to failure.

I assume you have a class like below
public static class Attraction {
private String ride;
private int price;
public Attraction(String ride, int price) {
this.ride = ride;
this.price = price;
}
public String getRide() {
return ride;
}
public void setRide(String ride) {
this.ride = ride;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
So to create the class Attraction you need to pass two arguments. if you want to create an object without data and later you want to update it, you can make use of default constructor and later you can update the values of the object. like below
public static class Attraction {
private String ride;
private int price;
public Attraction(String ride, int price) {
this.ride = ride;
this.price = price;
}
// this is a default construtor
public Attraction(){
this("", 0); // pass a default values for the object.
}
public String getRide() {
return ride;
}
public void setRide(String ride) {
this.ride = ride;
}
public int getPrice() {
return price;
}
public void setPrice(int price) {
this.price = price;
}
}
later you can create object of Attraction with or without passing argument parameters.
Attraction attraction = new Attraction() //will create the object with emptyString and 0
attraction.setRide("Your ride"); //sets ride
attraction.setPrice(1233); // sets price
attraction.getRide(); //gives the value of ride
attraction.getPrice(); // gives the price of the ride
Or You can create with argument data.
Attraction attraction = new Attraction("myRide", 20) //will create the object with value passed.
attraction.setRide("Your ride"); //sets ride
attraction.setPrice(1233); // sets price
attraction.getRide(); //gives the value of ride
attraction.getPrice(); // gives the price of the ride

Related

Is there a way to efficiently audit statistics attributes of objects in Java?

Say I have a class Person, and I created 10 instances of Person, and each person has several different attributes, such as enum Gender{MALE, FEMALE}, enum Profession{CEO, POLICE, TEACHER}, etc.
And I somehow have to randomly create many persons with random attributes and use a dedicated class to audit the statistics of created persons' attributes.
So, eventually, I need to generate a list of attributes with some statistics accordingly, such as, "FEMALE: [number], POLICE: [number],...".
Currently, I'm planning to add all kinds of the persons' attributes count, as a bunch of new attributes to the audit class, such as, "femaleCount int, policeCount int, ..." then manipulate the counts based on generated persons.
But, I got 10-ish attributes for each person, so I wonder if there is a better way to do this.
Thanks for your reading.
One possible approach is below, but do not say that it's the only one neither the best.
It's only depends of the purpose and your design.Other option maybe it's to store all Persons in a data-structure List and just compute the statistic based on data at a certain time (have also update/delete here)
Version where only add is counting ...
public class Statistic
{
private static Statistic s=null;
public int countPerson;
public int countMale;
public int countFemale;
public static Statistic getInstance()
{
if(s==null)
s = new Statistic(0, 0, 0);
return s;
}
public static Statistic getInstace(int cP,int cM, int cF)
{
if(s==null)
s = new Statistic(cP, cM, cF);
return s;
}
//do whatever init wanted
private Statistic(int cP,int cM, int cF)
{
countPerson = cP;
countMale = cM;
countFemale = cF;
}
public String toString()
{
return "Total="+countPerson+", Male="+countMale+", Female=" + countFemale;
}
}
...
public class Person
{
public int id;
public String name;
public Gender g;
public Profession p;
public enum Gender{MALE, FEMALE};
public enum Profession{CEO, POLICE, TEACHER}
Person(int id,String name, Gender g, Profession p)
{
this.id = id;
this.name = name;
this.g = g;
this.p = p;
Statistic.getInstance().countPerson++;
if(g.equals(Gender.MALE))
{
Statistic.getInstance().countMale++;
}
else
{
Statistic.getInstance().countFemale++;
}
}
}
...
public class TestStat {
public static void main(String[] args)
{
//cPersons,cMale,cFemale - init
Statistic.getInstace(10, 5, 5);
System.out.println(Statistic.getInstance());
new Person(1,"Male",Person.Gender.MALE, Person.Profession.TEACHER);
System.out.println(Statistic.getInstance());
new Person(2,"Female",Person.Gender.FEMALE, Person.Profession.CEO);
System.out.println(Statistic.getInstance());
}
}
Output
//custom start from (10,5,5) based on Singleton Custom Constructor
Total=10, Male=5, Female=5
//start update counters
Total=11, Male=6, Female=5
Total=12, Male=6, Female=6
Thinking twice maybe it's better to keep a List with Persons on Singleton
and make each time a new Computation - from Singleton instead on Person.
About Delete a person which can be translated in "moving from a Company to other" and then it's not to be reflected on Statistic.
Even so, on current you could add a delete method on person which could be reflected with adjust Statistic with minus and Person-Instance with null.
Further, it's up to you to update design as wanted.

Calling methods with objects trouble

So, I need to do this for part of my homework :
Create a method in the Customer class called hasMoreMoneyThan(Customer c)
which returns true if the customer calling the method has more money than the
customer c, otherwise it should return false.
I am looking to be pointed in the right direction for the line that says "the customer calling the method"
This is very confusing to me and doesn't make sense, this my Customer is a class.
Here is the necessary code :
public class Customer
{
private String name;
private int age;
private float money;
public String getName()
{
return name;
}
public int getAge()
{
return age;
}
public Customer(String n, int a, float m)
{
name = n;
age = a;
money = m;
}
I started writing the method:
public boolean hasMoreMoneyThan(Customer c)
{
}
But am not sure how to call that with my Customer object (which I think the question is asking.
Other relevant code :
public class StoreTestProgram {
public static void main(String args[]) {
Customer[] result;
Store walmart;
walmart = new Store("Walmart off Innes");
walmart.addCustomer(new Customer("Amie", 14, 100));
}
}
When a method is called on an object, the objects variables are in the current scope. In this case, the 'customer calling the method' is the object that the method is being called on (object being an instance of the class).
So, if boolean hasMoreMoneyThan(Customer c) is being called on Customer a, then you should think of it as asking Customer a has more money than Customer c?.
You can use the this keyword to refer to the current object (to help the reader differentiate from Customer c).
So, in your hasMoreMoneyThan method, you can compare this.money with c.money.
And to call this method, you need a reference to the current customer and the customer you want to compare with. You could do something like:
Customer currentCustomer = new Customer(...
Customer customerToCompareWith = new Customer(...
if (currentCustomer.hasMoreMoneyThan(customerToCompareWith)) {
// do something
}
Edit Let's try a different example. Let's say you want a method to know whether a customer is older than another customer. That code might look like:
public boolean isOlderThan(Customer c) {
return this.age > c.age;
}
And to call the method:
if (currentCustomer.isOlderThan(customerToCompareWith)) {
// the current customer is older
} else {
// the current customer is not older
}
this is how you reference an object from methods that are members of an object. this.money ><=? c.money
if in your constructor you you used public Customer(String name, int age, float money) you would use this.name= name instead of name= n to clear up ambiguity.

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; }
}

create variable of either data type

I need to create a variable of either data type on runtime (via scanner class)
This is what my assignment asked
"A selling arrangement could be an offered price OR an auction date"
This is what i have created but not sure if it is correct..
public class SellingArrangement {
private Object dateOrPrice;
public SellingArrangement()
{
}
public void setDateOrPrice(String price)
{
dateOrPrice = new Object();
dateOrPrice = price;
}
public void setDateOrPrice(Double price)
{
dateOrPrice = new Object();
dateOrPrice = price;
}
I have done something similar before (when an API may return JSON or XML)
However, you have two sets of two choices here - the input can either be a String or a Double, and that input can either represent a Date or a Price.
Instead of using an Object, I would just create two separate fields and populate the correct one using two separate constructors like this.
public class SellingArrangement {
private Date date;
private Price price;
public SellingArrangement(String input)
{
if ( // String is a price ) {
this.price = new Price(input);
}
if ( // String is a date ) {
this.date = new Date(input)
}
}
public SellingArrangement(Double input)
{
if ( // Double is a price ) {
this.price = new Price(input);
}
if ( // Double is a date ) {
this.date = new Date(input)
}
}
}
Of course, I am assuming you can figure out some way to validate whether the String or Double you are getting as input is a date or a price, and that you have constructors which will take a String / Double for each type. Treat this as pseudocode...
However as others have mentioned in comments if you dont have to do this with a single class, it would be better to use another method entirely...

Printing address instead of array elements? [duplicate]

This question already has answers here:
How do I print my Java object without getting "SomeType#2f92e0f4"?
(13 answers)
Closed 6 years ago.
So in my code, I made a class named Pet, that would have both a default constructor and a non-default constructor that passes in String name, and int age of the pet.
public class Pet
{
// instance variables
private int age;
private String name;
/**
* Constructor for objects of class Pet
*/
public Pet()
{
// initialise instance variables
age = 0;
name = "somePet";
}
public Pet(int age, String name)
{
this.age = age;
this.name = name;
}
}
Then I created a class named petArray that would add to the array and print out the array...
public class PetArray
{
// instance variables
private Pet [] petArray;
/**
* Constructor for objects of class PetArray
*/
public PetArray()
{
// initialise instance variables
petArray = new Pet[5];
}
public void addPets()
{
// put your code here
Pet myPet = new Pet(4, "Spots");
petArray[0] = (myPet);
petArray[1] = new Pet(2, "Lucky");
petArray[2] = new Pet(7, "Joe");
}
public void printPets()
{
for (int i = 0; i < petArray.length; i++)
{
System.out.println(petArray[i]);
}
}
}
But then, I get this in the terminal window when trying to print it out...
Pet#13255e3c
Pet#171ac880
Pet#52185407
null
null
You forgot to override toString() method inherited from Object.
In this case you can use something like this:
#Override
public String toString() {
return (name + age);
}
Java compiler just does not know how to print it, you have to inform it :)
In your addPets() method you are only adding 3 objects to your petArray while there are 2 more spaces you need to fill as you declared that array to be a length of 5.
You could change the length of your array down to 3 or you could add 2 more objects, that should fix your problem.
And as stated above, adding the toString method will get rid of the addressing issues.
class Pet {
...
#Override
public String toString(){
// the string passed from here will be shown in console
}
}
Your output is fine according to your code. You have to override toString() method to print as per your requirement. Add this may be it will help.
#override
public string toString(){
return "your required string"; // i.e : name or name+age
}

Categories