I previously have the variable availability stored in a double which is present inside a class named wrapper as below -
public final class Wrapper {
private final double availability;
Wrapper(){
this.availability = 2;
}
public Wrapper(final double availability){
this.availability = availability;
}
public double availability (){ // Need a confirmation if this is a getter ?
return this.availability;
}
}
Now, I have to change the scenario a bit by making availability as an object.Reason being - Now we want availability per region unlike the above case.Also, we need to use that availability object inside the wrapper class now.
Here is what I'm trying to do -
public final class Availability {
public enum Region {
US,
UK,
EU;
private final double availability;
Region () {
this.availability = 2;
}
Region (double availability) {
this.availability = availability ;
}
}
I'm supposed to use the Availability object inside wrapper class as wrapper class object is being used in other places which previously used to take argument (Availability). Now I don't want to break that workflow. Also I'm a bit confused a bit regarding creation of object for Availability class as I'm using an enum. Can anyone please help me with this. Thanks in advance!
Per my understanding, you do not need class Availability.
Define Region.java file as having public enum Region, then you can have that constructor along with adding a missing getter.
public enum Region {
US(2),
UK(2),
EU(2);
private final double availability;
Region (double availability) {
this.availability = availability ;
}
public getAvailability() {
return this.availability;
}
}
Then Wrapper can accept Region instance instead, and access .getAvailability() method of it.
public final class Wrapper {
private final Region region;
public Wrapper(Region region){
this.region = region;
}
public double getAvailability() {
return this.region.getAvailability();
}
e.g. System.out.print(new Wrapper(Region.US).getAvailability());
Related
I have 4 motors let's say, and for each, I have some constants like the ID, the maximum speed, and the minimum power. Let's say that at some point there are going to be many constants added to this MotorConstants class, and this is what it currently looks like:
public abstract class MotorConstants{
abstract final int ID;
abstract final double MAX_SPEED, MIN_POWER;
}
// And an implementation:
public class LeftMotorConstants extends MotorConstants{
final int ID = 3;
final double MAX_SPEED = 500, MIN_POWER = 10;
}
I understand that abstract fields are not possible. What could be a good replacement for them?
I'm afraid of passing everything through the constructor/getters and setters because then after adding a field would take a lot of time and lots of lines of code, instead of the (not working) code sample.
Constants cannot be inherited and then overwritten; that defeats the purpose of calling them "constant. Methods can be overridden to return differing values (even if they return an external constant variable).
If I understand your data model, and ID belongs to a specific instance of some "part". The other fields are also specific properties to some instance, which should not belong to the overall class, so that would be done with methods.
This is where you'd use interfaces to define those common "templates" that a class needs to implement.
E.g.
interface LimitedPower {
double getMinPower();
}
interface LimitedSpeed {
double getMaxSpeed();
}
interface Identifiable {
int getId();
}
abstract class AbstractMotor implements Identifiable {
protected int id; // available to all subclasses
#Override
public int getId() {
return this.id;
}
}
class LimitedMotor extends AbstractMotor implements LimitedSpeed, LimitedPower {
private double minPower, maxSpeed;
public LimitedMotor(int id, double minPower, double maxSpeed) {
this.id = id;
this.minPower = minPower;
this.maxSpeed = maxSpeed;
}
// TODO: implement interface getter+setter functions
}
class MotorPowered {
final AbstractMotor[] motors = new AbstractMotor[4];
public MotorPowered(AbstractMotor left, AbstractMotor right, AbstractMotor top, AbstractMotor buttom) {
this.motors[0] = left;
//... etc
}
}
Then, when you actually create a specific motor, you can pass in the details for it.
final AbstractMotor left = new LimitedMotor(3, 10, 500);
MotorPowered engine = new MotorPowered(left, ...);
If you want to say "all 'limited motors' will have the same id", then you can add some final static int ID to that class, and remove the constructor parameter.
class LimitedMotor extends AbstractMotor implements LimitedSpeed, LimitedPower {
private double minPower, maxSpeed;
public static final int ID = 3;
public LimitedMotor(double minPower, double maxSpeed) {
this.id = LimitedMotor.ID;
this.minPower = minPower;
this.maxSpeed = maxSpeed;
}
I have a nested POJO structure defined something like this,
public class Employee {
private String id;
private Personal personal;
private Official official;
}
public class Personal {
private String fName;
private String lName;
private String address;
}
public class Official {
private boolean active;
private Salary salary;
}
public class Salary {
private double hourly;
private double monthly;
private double yearly;
}
I get updates from a service with dot annotaion on what value changed, for ex,
id change --> id=100
address change --> personal.address=123 Main Street
hourly salary change --> official.salary.hourly=100
This POJO structure could be 3-4 level deeps. I need to look for this incoming change value and update the corresponding value in POJO. What's the best way of doing it?
If you would like to create Java objects that allows you to edit fields. You can specify your object fields with the public/default/protected access modifiers. This will enable you to get and set fields such as personal.address or official.salary.hours
This approach is typically frowned upon as the object is no longer encapsulated and any calling methods are welcome to manipulate the object. If these fields are not encapsulated with getters and setters, your object is no longer a POJO.
public provides access from any anywhere.
default provides access from any package
protected provides access from package or subclass.
public class Employee {
public String id;
public Personal personal;
public Official official;
}
public class Personal {
public String fName;
public String lName;
public String address;
}
Here's a quick approach using reflection to set fields dynamically. It surely isn't and can't be clean. If I were you, I would use a scripting engine for that (assuming it's safe to do so).
private static void setValueAt(Object target, String path, String value)
throws Exception {
String[] fields = path.split("\\.");
if (fields.length > 1) {
setValueAt(readField(target, fields[0]),
path.substring(path.indexOf('.') + 1), value);
return;
}
Field f = target.getClass()
.getDeclaredField(path);
f.setAccessible(true);
f.set(target, parse(value, f.getType())); // cast or convert value first
}
//Example code for converting strings to primitives
private static Object parse(String value, Class<?> type) {
if (String.class.equals(type)) {
return value;
} else if (double.class.equals(type) || Double.class.equals(type)) {
return Long.parseLong(value);
} else if (boolean.class.equals(type) || Boolean.class.equals(type)) {
return Boolean.valueOf(value);
}
return value;// ?
}
private static Object readField(Object from, String field) throws Exception {
Field f = from.getClass()
.getDeclaredField(field);
f.setAccessible(true);
return f.get(from);
}
Just be aware that there's a lot to improve in this code (exception handling, null checks, etc.), although it seems to achieve what you're looking for (split your input on = to call setValueAt()):
Employee e = new Employee();
e.setOfficial(new Official());
e.setPersonal(new Personal());
e.getOfficial().setSalary(new Salary());
ObjectMapper mapper = new ObjectMapper();
setValueAt(e, "id", "123");
// {"id":"123","personal":{},"official":{"active":false,"salary":{"hourly":0.0,"monthly":0.0,"yearly":0.0}}}
setValueAt(e, "personal.address", "123 Main Street");
// {"id":"123","personal":{"address":"123 Main Street"},"official":{"active":false,"salary":{"hourly":0.0,"monthly":0.0,"yearly":0.0}}}
setValueAt(e, "official.salary.hourly", "100");
// {"id":"123","personal":{"address":"123 Main Street"},"official":{"active":false,"salary":{"hourly":100.0,"monthly":0.0,"yearly":0.0}}}
I need help with a specific problem in my class project. The goal of the project is to create a program in which you can register how much shares you own. Information that's required is the company name, how many shares you own and their respective value. I created a GUI class and a class where the information is transferred to. The input comes from a private void. I'm having trouble finding a way to transfer the input from the private void to a an arraylist in a class outside it.
Here is how I initialized the arraylist in the GUI class.
public class GUISharePortfolio_1 extends javax.swing.JFrame {
ArrayList<SharePackage.Share> Package = new ArrayList<SharePackage.Share>();
Next is how I get the company name, number of shares and their value from the GUI. Since it is a private void I have to transfer that information to the SharePackage class.
private void CreatePortfolioButtonActionPerformed(java.awt.event.ActionEvent evt) {
String name;
double number;
double value;
name = CompanyNameField.getText();
number = Double.parseDouble(NumberOfSharesField.getText());
value = Double.parseDouble(ValueOfShareField.getText());
Package.CompanyName(name);
Package.NumberOfShares(number);
Package.ValueOfShare(value);
}
I'm getting an error saying "cannot find symbol" under the CompanyName, NumberOfShares and ValueOfShare.
The public class to which the info should be transferred is this:
package shareportfolio;
import java.util.ArrayList;
public class SharePackage
{
private ArrayList<Share> Package = new ArrayList<Share>();
public class Share
{
private String companyname;
private double numberofshares;
private double valueofshare;
Share(String companyname, double numberofshares, double valueofshare)
{
this.companyname = companyname;
this.numberofshares = numberofshares;
this.valueofshare = valueofshare;
}
public void setCompanyName(String name)
{
companyname = name;
}
public String getCompanyName()
{
return(companyname);
}
public void setNumberOfShares(double number)
{
numberofshares = number;
}
public double getNumberOfShares()
{
return(numberofshares);
}
public void setValueOfShare(double value)
{
valueofshare = value;
}
public double getValueOfShare()
{
return(valueofshare);
}
}
}
I would appreciate any help very much.
You have a field named Package, who's type is ArrayList. ArrayList doesn't have a method called CompanyName. What you're probably trying to do is something like:
Package.add(new SharePackage.Share(companyname, numberofshares, valueofshares));
You have two such fields named 'Package', so not sure which one you're trying to add to. Maybe you're under the impression the fields are somehow the same one. They are not.
BTW: Definitely learn Java coding style before submitting this to anyone. You are naming fields with UpperCamelCase which makes it very difficult for a java programmer to read your code.
user1207705 that was the answer. I modified it to:
String name;
double number;
double value;
name = CompanyNameField.getText();
number = Double.parseDouble(NumberOfSharesField.getText());
value = Double.parseDouble(ValueOfShareField.getText());
Package.add(new SharePackage.Share(name, number, value));
Thank you for your help and I will work on Java coding style.
I am told I need to create an enumeration Team with 2 values of Varsity and JV. Is this what it should look like? Do I need the constructor?
public enum Team {
Varsity, JV;
private String Level;
private Team(String studentLevel) {
Level = studentLevel;
}
}
It's almost correct: you need to pass values to the constructors, e.g. like this:
public enum Team {
Varsity("level_v"), JV("level_jv");
private String Level;
private Team(String studentLevel) {
Level = studentLevel;
}
}
Whether you need the constructor or not depends on whether your enum needs parameters/fields. You'd then set those fields with the constructor and since they shouldn't be changed in most cases, I'd declare them to be final as well, i.e. private final String level.
public enum Team
{
Varsity("someLvl"), JV("someLvl");
private String studentLevel;
Team(String studentLevel)
{
this.setStudentLevel(studentLevel);
}
public String getStudentLevel() {
return studentLevel;
}
private void setStudentLevel(String studentLevel) {
this.studentLevel = studentLevel;
}
}
You need to set the student level right away.
I have a class that has a constructor as the following:
public Stock(String symbol, String name, int value) {
this.symbol = symbol;
this.name = name;
this.value = value;
}
Now, I have another class that is an abstract data type:
public class Holding {
private Stock stock;
private int amount;
public Holding() {
this.stock = null;
this.amount = 0;
}
public Holding(Stock stock, int amount) {
this.stock = stock;
this.amount = amount;
}
}
Now, I am writing a method in another class.
I have created an arraylist using the Holding class above.
in this class
private ArrayList<Holding> holdings;
Now, I know that my objects in the Holding class contains a stock object, and an int amount.
How can I access only the symbol in my stock object in the Holding ArrayList?
Not sure what you mean.
for (Holding h : holdings) {
out.println(h.getStock().getSymbol());
}
That's assuming you have appropriate getters.
You would want to use Java's foreach to loop through the ArrayList:
for (Holding currentHolding : holdings) {
System.out.println(currentHolding.stock.symbol); // prints out all the symbols
}
You need to change the attribute Stock from private to public, or create a getStock method to return it. Otherwise, since it is private, you can't access it.
How can I access only the symbol in my stock object in the Holding ArrayList?
With the code as given, you can't do this.
You need to add a public getter method for the stock field of the Holding class.
You (may) need to add a public getter method for the symbol field of the Stock class.
When you have done that you can do something like this:
public Holding getHoldingForSymbol(List<Holding> holdings, String symbol) {
for (Holding h : holdings) {
if (h.getStock().getSymbol().equals(symbol)) {
return h;
}
}
return null; // or throw an exception
}