Java: An Object Constructor Passing Same Object as Parameter - java

I have made an object called Transaction which I am passing in an ArrayQueue.
Here is the Transaction class constructors (I have the appropriate setter and getters too):
public class Transaction {
private int shares;
private int price;
public Transaction(int shares, int price) {
this.shares = shares;
this.price = price;
}
public Transaction(Object obj) {
shares = obj.getShares();
price = obj.getPrice();
}
}
In the second constructor there I am wanting a scenario where I can pass into it a different Transaction object that has been dequeue(ed) and get the info from that transaction and make it into a new transaction or possibly manipulate it before I put it back into the queue. But when I compile it does not like this.
Is this acceptable programming practice to pass a specific object into it's own object's constructor? Or is this even possible?

It's called copy-constructor and you should use public Transaction(Transaction obj) instead of Object and also provide getters:
public class Transaction {
private int shares;
private int price;
public Transaction(int shares, int price) {
this.shares = shares;
this.price = price;
}
public Transaction(Transaction obj) {
this(obj.getShares(), obj.getPrice()); // Call the constructor above with values from given Transaction
}
public int getShares(){
return shares;
}
public int getPrice(){
return price;
}
}

You need to specify the same type:
public Transaction(Transaction obj) {
shares = obj.getShares();
price = obj.getPrice();
}
Provided that you have defined getShares() and getPrice().

Yes this is entirely possible.
public Transaction(Transaction other){
shares = other.shares;
price = other.price;
}
You do not need to call their getters because privacy only applies to other classes.

Yes, you can do that but you will have to type cast the parameter
public Transaction(Object obj) {
Transaction myObj = (Transaction) obj;
shares = MyObj.getShares();
price = MyObj.getPrice();
}

for instance lets assume we have a class of Author with all the getters created
to pass another object as a parameter we use the following syntax
public Author(ClassName variable){
this(obj.getlength(), obj.getwidht())// height and width are the instance variable of the class.
}

Related

Working with enum types in java

I need to create a "super" enum (here ESideItem) which will keep record of "sub" enums (SALAD, FRY, TACO) & I need to access "sub" enum's fields(price) from outside too.
I meant "super" as main type & "sub" as sub-type of that main type.
There can be many types of SideItems (FRY, SALAD, TACO) for a meal & each of these sideitems can be of many types (i.e SALAD can be CHICKEN or AFGHAN or MIMOSA etc).
Following Ray Tayek's answer to this question I've implemented this:
public abstract class SideItem {
public enum FRY {
FRENCHFRY(25.25f), SEASONEDCURLYFRY(30.10f);
private float price;
FRY(float price) {
this.price = price;
}
public float getPrice() {
return price;
}
}
public enum SALAD{
AFGHANSALAD(50.25f), CHICKENSALAD(40.10f), MIMOSASALAD(45.89f);
private float price;
SALAD(float price) {
this.price = price;
}
public float getPrice() {
return price;
}
}
public enum TACO{
MONSTERTACO(26.25f), NACHOMONSTERTACO(35.10f);
private float price;
TACO(float price) {
this.price = price;
}
public float getPrice() {
return price;
}
}
public enum ESideItem {
FRY(SideItem.FRY.FRENCHFRY), SALAD(SideItem.SALAD.AFGHANSALAD), TACO(SideItem.TACO.MONSTERTACO);
ESideItem(Enum e) {
this.e = e;
}
public Object[] subValues() {
return e.getDeclaringClass().getEnumConstants();
}
final Enum e;
}
}
I implementd Main.java as follows:
public class Main {
public static void main(String[] args) {
for(SideItem.ESideItem aSideItem : SideItem.ESideItem.values()){
System.out.println(aSideItem);
for(Object o : aSideItem.subValues()){
System.out.format("%-15s",o);
System.out.println();
}
System.out.println();
}
}
}
The output is:
FRY
FRENCHFRY
SEASONEDCURLYFRY
SALAD
AFGHANSALAD
CHICKENSALAD
MIMOSASALAD
TACO
MONSTERTACO
NACHOMONSTERTACO
Main.java is like client side & SideItem.java is like server side. I can change or add any instance in the ESubItem enum from SideItem.java. Main.java should give output according to that change
But I do need to get price of these individual TACO's, SALAD's, FRY's . Is there any way to access these fields from Main.java using enum?
If not then what kind of data structure should I use to solve this problem ?
You should be using an interface:
interface Food
{
float getPrice();
}
public enum Fry implements Food
{
FRENCH_FRY(25.25f), SEASONED_CURLY_FRY(30.10f);
private final float price;
FRY(float price) {
this.price = price;
}
#Override
public float getPrice() {
return price;
}
}
And the same for the other two...
Then you can compose them like so:
public enum Meal implements Food {
HAPPY_MEAL(Fry.FRENCH_FRY, Fry.SEASONED_CURLY_FRY),
SAD_MEAL(Salad.AFGHAN_SALAD);
private final List<Food> items;
Meal (Food... items) {
this.items = Arrays.asList(food);
}
#Override
public float getPrice()
{
return (float) items.stream().mapToDouble(Food::getPrice).sum();
}
}
If you want to access the price for calculations etc. the easiest way is to make all those enums implement an interface with public float getPrice().
For display purposes you would only need to modify the toString() of each enum.
The enum ESideItem and SideItem classes seem unnecessary though. Especially the ESideItem doesn't seem like it should be an enum at all, and the way you're using getDeclaringClass().getEnumConstants() is just a really bad idea.
You will need to something like:
for(Object o : aSideItem.subValues()){
if(o instanceof SideItem.FRY)
((SideItem.FRY)o).getPrice()
You can define an interface, say
public interface Priced {
double getPrice();
}
The enums can implement that
public enum FRY implements Priced { // no further change needed, method already there
and you can return an array of Priced with your subValues().
public Priced[] subValues() {
return Stream.of(FRY.values(), SALAD.values(), TACO.values()).
toArray(Priced[]::new);
}
I'm not entirely sure if the latter works this way, but being able to implement an interface in your enum is the main point.

Chaining multiple constructors

I understand that when chaining constructors this must be done on the first line of the main constructor, can someone explain how you would go about the below code.
I want to chain to all constructors so that they can all be private other than the main constructor.
public class Flight {
int passengers = 0;
int seats = 150;
double maxKgPerPassenger;
private Flight(int passengers) {
this.passengers = passengers;
}
private Flight(int seats) {
this.seats = seats;
}
private Flight(double maxKgPerPassenger) {
this.maxKgPerPassenger = maxKgPerPassenger;
}
public Flight(int passengers, int seats, double maxKgPerPassenger) {
this(passengers);
this(seats);
this(maxKgPerPassenger);
}
}
A constructor is up to set as many fields as possible or construct an instance completely.
You pick a constructor which has a greater number of arguments and use it within constructors with a smaller amount. For example,
public Flight(double maxKgPerPassenger) {
this(0, 0, maxKgPerPassenger); // default, default, maxKgPerPassenger
}
private Flight(int passengers, int seats, double maxKgPerPassenger) {
this.passengers = passengers;
this.seats = seats;
this.maxKgPerPassenger = maxKgPerPassenger;
}
I want to chain to all constructors so that they can all be private other than the main constructor.
I suggest the opposite way. Make all constructors you are going to use public, but an all-arguments constructor private if you won't be using that.
The approach you tried to adopt is similar to the builder pattern where each method sets a single field. You definitely need to have a look at it if a number of arguments are going to grow up.
Why do you want to chain constructors ?
As you chain constructors, you have to specify some default values from the constructor with less argument to the invoked constructor with more arguments.
You do the reverse here :
public Flight(int passengers, int seats, double maxKgPerPassenger){
this(passengers);
this(seats);
this(maxKgPerPassenger);
}
You indeed want to invoke from the constructor with the most argument all other constructors.
It makes no sense and it is not valid either as a constructor can invoke a single other constructor of the same class.
I want to chain to all constructors so that they can all be private
other than the main constructor.
Things work in the reverse order.
The actual code doesn't seem to need constructor chaining.
This one is enough :
public Flight(int passengers, int seats, double maxKgPerPassenger){
this.passengers = passengers;
this.seats = seats;
this.maxKgPerPassenger = maxKgPerPassenger;
}
Suppose that class clients could create Flight instances with two flavors :
by passing all parameters
by passing only the seats parameter (remains being valued with default values)
You could so write :
public Flight(int passengers, int seats, double maxKgPerPassenger){
this.passengers = passengers;
this.seats = seats;
this.maxKgPerPassenger = maxKgPerPassenger;
}
public Flight(int seats){
super(50, seats, 10); // you pass some default values for passengers and maxKgPerPassenger
}
make the default constructor private to prevent constructor instantiation and instantiate objects using a public static method. This way you can work around the constructor restriction. To add a little confusion I converted your constructors to normal methods using the class name by adding void return type. Also consider if want you really want isn't the Builder pattern.
public class Flight {
private int passengers = 0;
private int seats = 150;
private double maxKgPerPassenger;
private Flight() {}
private void Flight(int passengers)
{
this.passengers = passengers;
}
private void Flight(int seats)
{
this.seats = seats;
}
private void Flight(double maxKgPerPassenger)
{
this.maxKgPerPassenger = maxKgPerPassenger;
}
public static Flight create(int passengers, int seats, double maxKgPerPassenger)
{
Flight flight = new Flight();
flight.Flight(passengers);
flight.Flight(seats);
flight.Flight(maxKgPerPassenger);
return flight;
}
}

Java association problems

Finding Java an overly complicated language. I can't figure out this association thing if my life depended on it. I'm specifically stuck on the Cab object +pickup(rider:Passenger): String. I know it will return a String and here's the code I have so far.
UML Diagram
package cabsimulation;
public class Cab {
private double companyTotalFare;
private double rate;
private double taxiTotalFare;
private int tripCounter;
private int cabID;
public Cab(int cabID){}
public double dropOff(int minutes){
return minutes*rate;
}
public double endOfShift(){
double sumOfFares = taxiTotalFare + companyTotalFare;
return sumOfFares;
}
//public String report();
public double getRate(){
return rate;
}
public void setRate(double cabRate){
this.rate = cabRate;
}
}
and
public class Passenger {
private final double weight;
private final boolean inFrontSeat;
public Passenger (double weight, boolean front){
this.weight = weight;
this.inFrontSeat = front;
}
public double getWeight(){
return weight;
}
public boolean isInFrontSeat(){
return inFrontSeat;
}
}
How do I write (program) an association between these two objects?
As written in your instructions: define a typed attribute
private Passenger passenger;
or the like (I'm no Java guy).
When you want to have an association between two classes, you will normally use an instance variable. In this case, a Cab can contain a Passenger. So you want to have an instance variable in the Cab class which is able to hold a Passenger. This can be done like that:
public class Cab {
Passenger passenger;
//...
}
In the pickUp method shown in the UML, you want to fill this variable, e. g. like that (unfortunately, there is no specification what String the method should return):
public class Cab {
Passenger passenger;
//...
public String pickUp(Passenger rider) {
this.passenger = rider;
return "something";
}
}
After you called the method pickUp, you can access the passenger in the cab via its instance variable.
I hope I could help you!
usually, if you have an attribute, you have the getter/setter which are dedicated to set and to get the attribute.
If you have a method (other than a setter) with a parameter of the type of an attribute, it does not mean that the parameter will set the attribute.
So for me, it could be easier to remove the method pickup and to define a getter and setter on passenger.

Alternate for hash map

I have a set of objects of type "Part" and each Part is associated with quantity(a field that specifies number of units required of that particular Part ). Is there in way in java to store this data, other than hash map?
You can write a wrapper object that has two fields, Part and quantity:
public class PartWithQuantity
{
private Part part;
private int quantity;
public int getQuantity() { return quantity; }
public void setQuantity(int q) { quantity = q; }
public Part getPart() { return part; }
public void setPart(Part p) { part = p; }
}
You can also use a TreeMap if the concern is that the HashMap might use too much memory.
This can be done very easily by just storing the metadata into the arraylist.
You can take a class that contains one reference of part type and other(quantity) is int type. Then you can even store the instances of this new class into an arraylist. Do Remember ,you can access your information anytime from this arraylist by calling the object.
The simplest way to achieve this would be to modify the Part class and add the quantity field, along with its setter and getter.
Another option would be to use a wrapper object and store it in the Set.
I have created a convenience method called check() to easily identify the Part of interest:
public class PartExtended {
private Part part;
private int quantity;
public PartExtended(Part part, int quantity) {
this.part = part;
this.quantity = quantity;
}
public boolean check(Part part) {
return part.equals(this.part);
}
public Part getPart() {
return part;
}
public int getQuantity() {
return quantity;
}
}
To retrieve a Part's quantity, use a for loop:
Set<PartExtended> data = new HashSet<>();
data.add(new PartExtended(new Part(), 0));
for (PartExtended item : data) {
if (item.check(new Part())) {
int quantity = item.getQuantity();
}
}

Getting data from another class in Java

public class Item {
/**
* Instance variables for this class
*/
private String itemName;
private int itemQuantity;
/**
* Contructor for this class
*/
public Item (String itemName, int itemQuantity) {
this.itemName = itemName;
this.itemQuantity = itemQuantity;
}
//setter and getter methods
public String getItemName () {
return itemName;
}
public void setItemName(String itemName) {
this.itemName = itemName;
}
public int getItemQuantity () {
return itemQuantity;
}
public void setItemQuantity(int itemQuantity) {
this.itemQuantity = itemQuantity;
}
}
Ok..I already have the class for item. Now I have to write the CartItem class. The description that was given are as follows:
class CartItem{
/*
Objects of this class are used to hold items that the shopper purchases in the super market.
There are two attributes in this class, an item (an object created from the Item class) and a quantity (the number of that item that the shopper purchases). You have to write these two attributes. Note that one of the two will have a user defined data type.
*/
}
public class CartItem {
private Item item; //item from the item class
private int itemQuantity; //quantity how much shopper buys
public CartItem(Item itemName, int itemQuantity) {
this.getItem();
this.getQuantity();
}
public Item getItem() {
return item;
}
public void setItem(Item item) {
this.item = item;
}
public int getQuantity() {
return itemQuantity;
}
public void setQuantity(int quantity) {
this.itemQuantity = itemQuantity;
}
}
Just wondering if it's correct though.
No, it's not correct. Look at your constructor:
public CartItem(Item itemName, int itemQuantity) {
this.getItem();
this.getQuantity();
}
Here you're calling the getters and completely ignoring the values the caller has passed in. I don't think you want to do that... think about what the constructor needs to do in order to populate the newly constructed object...
(You should also consider making these classes immutable, but that's a slightly different matter.)
Few things.
1 Person may shop more than one Item so have List of Item
2 Constructor isn't correct, which should be
public CartItem(Item itemName, int itemQuantity) {
this.item = itemName;
this.itemQuantity = itemQuantity;
}
No it's not.
The constructor for CartItem just calls this.getItem() and this.getQuantity(). This will just call the methods, which will obviously return null, since the attributes are never initialized. It should be:
public CartItem(Item itemName, int itemQuantity) {
this.item = itemName;
this.itemQuantity = itemQUantity;
}
Another problem is that you add getters and setters for all the fields, without even knowing if those methods are necessary. Try to favor immutability, and only provide setters if they are absolutely necessary. I won't explain all the advantages of immutability, because it would be too early given what you already know. But a good rule of thumb is : don't add a method to a class if it's not used.

Categories