Modify an instance variable within the Main class or main method - java

I would like to be able to modify the value of a local variable defined in a constructor within the class via the main driver class at some point while running the program. How would I be able to achieve this?
Here is a sample of a constructor that I am using.
public Scale()
{
weight = 0;
unit = "kg";
}
I'd like to modify the value of weight at a point while running the program in the driver.

It sounds like you're wanting to give the class a method that would allow outside code to be able to change or "mutate" the state of the fields of the class. Such "mutator" methods are commonly used in Java, such as "setter" methods. Here, public void setWeight(int weight):
public void setWeight(int weight) {
this.weight = weight;
}

The best way to allow that would probably be through a method. It could be something as straightforward as setWeight(), or something more complicated like a method for adding items to the scale...
public class Scale {
private float weight = 0;
private String unit = "kg";
public void setWeight(float weight) {
this.weight = weight;
}
public void addItem(Item i) { // Assumes that Item is an interface defined somewhere else...
this.weight += i.getWeight();
}
public static void main(String[] args) {
Scale s = new Scale();
s.setWeight(4.0F); // sets the weight to 4kg
s.addItem(new Item() {
#Override
public float getWeight() {
return 2.0F;
}
}); // Adds 2kg to the previous 4kg -- total of 6kg
}
}

Related

Best way to unit test this method?

I have the following class
public class Multiplier {
private static Map<Integer, Float> map;
private static final float DEFAULT_MULTIPLIER = 4.4F;
static {
// This map is actually populated by reading from a file. This is an example on how the map looks like.
map = new HashMap<>();
map.put(1, "3.5F");
map.put(2, "5.8F");
map.put(3, "2.7F");
}
public static float getMultiplier(Integer id) {
return map.getOrDefault(id, DEFAULT_MULTIPLIER);
}
}
I have another class
public class MultiplierUser {
private integer id;
private float value;
private float result;
public MultiplierUser(int id, float value) {
this.id = id;
this.value = value;
}
public void setResult() {
result = value * Multiplier.getMultiplier(this.id);
}
public float getResult() {
return this.result;
}
}
What's the best way to test this method?
Should I get the expected value by calling the method and then asserting?
public testMethod() {
MultiplierUser multiplierUser = new MultiplierUser(1, 10F);
multiplierUser.setResult();
float expected = Multiplier.getMultiplier(1) * 10F;
Assert.assertEquals(expected, multiplierUser.getResult());
}
Or mock?
public testMethod() {
MultiplierUser multiplierUser = new MultiplierUser(1, 10F);
Mockito.mock(Multiplier.class);
when(mock.getMultiplier(1)).thenReturn(1.5F);
multiplierUser.setResult();
float expected = 1.5F * 10F;
Assert.assertEquals(expected, multiplierUser.getResult());
}
I can't understand which would be the better way to test this method? If I use the former, I'm basically calling the method myself and getting the result. But if there's an issue with the method in the future, the test will keep succeeding. If I'm using a mock, then I'm technically not testing the method and the value it returns. I'm confused. Please help.
To test the setResult method, mocking the Multiplier is sufficient.
The methods setResult and getMultiplier are pretty straight forward in this case.
But let's consider a scenario where complex operations are involved:
public class A {
public int foo1() {
//some complex operations
}
}
public class B {
public int foo2() {
A a = new A();
int val = a.foo1();
//some complex operations
}
}
Now to test foo2(), it makes more sense to mock the class A and use thenReturn to get some sample output rather than testing the entire foo1() method in the test for foo2(). This ensures that you are only testing the corresponding units of code pertaining to the method under test.
Unit tests should be designed such that they are simple, readable and deals with one logic at a time.

Create tasks[] an array of task

My current problem is that I am assigned to created a program that should within the private fields assign tasks[] an array of task. Then within the constructor, that creates the task[] array, giving it the capacity of INITIAL_CAPAITY, and setting numTasks to zero.
I am new and confused on I can tackle this problem
I have tried declaring it within the constructor but there has been no luck.
Task.java
public class Task {
private String name;
private int priority;
private int estMinsToComplete;
public Task(String name, int priority, int estMinsToComplete) {
this.name=name;
this.priority=priority;
this.estMinsToComplete = estMinsToComplete;
}
public String getName() {
return name;
}
public int getPriority() {
return priority;
}
public int getEstMinsToComplete() {
return estMinsToComplete;
}
public void setName(String name) {
this.name = name;
}
public void setEstMinsToComplete(int newestMinsToComplete) {
this.estMinsToComplete = newestMinsToComplete;
}
public String toString() {
return name+","+priority+","+estMinsToComplete;
}
public void increasePriority(int amount) {
if(amount>0) {
this.priority+=amount;
}
}
public void decreasePriority(int amount) {
if (amount>priority) {
this.priority=0;
}
else {
this.priority-=amount;
}
}
}
HoneyDoList.java
public class HoneyDoList extends Task{
private String[] tasks;
//this issue to my knowledge is the line of code above this
private int numTasks;
private int INITIAL_CAPACITY = 5;
public HoneyDoList(String tasks, int numTasks, int INITIAL_CAPACITY,int estMinsToComplete, String name,int priority) {
super(name,priority,estMinsToComplete);
numTasks = 0;
tasks = new String[]{name,priority,estMinsToComplete};
//as well as here^^^^^^^^
}
My expected result is to be able to print out the list through honeydo class. I need to manipulate the code a bit more after adding a few other methods.
Your problem is that your constructor parameter tasks has the same name as that field of your class.
So you assign to the method parameter in your constructor, not to the field. And luckily those two different "tasks" entities have different types, otherwise you would not even notice that something is wrong.
Solution: use
this.tasks = new String...
within the body of the constructor!
And the real answer: you have to pay a lot attention to such subtle details. And by using different names for different things you avoid a whole class of issues!
Also note: it sounds a bit strange that a class named Task contains a list of tasks, which are then strings. The overall design is a bit weird...

I have created two classes, when I entered negative quantity and negative price it does not set to be "0" and "0.0"

I have created two classes, when I entered negative quantity and negative price it does not set to be "0" and "0.0" respectively as I assigned condition in setitmprch(int itmprch) and setitmprch(int itmprch) methods. Kindly tell where I did a mistake.
public class INVOICE {
private String pn;
private String pdscp;
private int itmprch;
private double prpitm;
private double amount;
public INVOICE(String pn, String pdscp, int itmprch, double prpitm ){
this.pn=pn;
this.pdscp=pdscp;
this.itmprch=itmprch;
this.prpitm=prpitm;
}
public void setpn(String pn){
this.pn=pn;
}
public void setpdscp(String pdscp){
this.pdscp=pdscp;
}
public void setitmprch(int itmprch){
if (itmprch < 0)
itmprch=0;
}
public void setprpitm(double prpitm){
if(prpitm > 0.0)
this.prpitm=prpitm;
else if(prpitm < 0.0)
this.prpitm=0.0;
}
public String getpn(){
return pn;
}
public String getpdscp(){
return pdscp;
}
public int getitmprch(){
return itmprch;
}
public double getprpitm(){
return prpitm;
}
public double getInvoiceAmount(){
amount= getitmprch()*getprpitm();
return amount;
}
}
public class INVOICETEST {
public static void main(String[] args) {
// TODO code application logic here
INVOICE in= new INVOICE("Mercedez","Arw 777",-3,-2.0);
System.out.printf("Part number is: %s\n",in.getpn());
System.out.printf("Part decription is: %s\n", in.getpdscp());
System.out.printf("Item purchased: %s\n",in.getitmprch());
System.out.printf("Price per item is: %s\n",in.getprpitm());
System.out.printf("Total amount is: %s\n",in.getInvoiceAmount());
}
}
You are assigning values to the method parameters, which will be lost as soon as you exit your method. Add this.itmprch = itmprch to your setitmprch method. Also have a look at some Java programming guidelines to improve code readability.
public void setitmprch(int itmprch){
if (itmprch < 0)
itmprch=0;
this.itmprch = itmprch;
}
Also your constructor should call the setter methods instead of assign values directly. It would look something like this:
public INVOICE(String pn, String pdscp, int itmprch, double prpitm ){
setpn(pn);
setpdscp(pdscp);
setitmprch(itmprch);
setprpitm(prpitm);
}
Don't use all caps for class names.
Use more descriptive variable names - my eyes are bleeding looking at this and it takes 10x longer to understand than it should.
Use automatic properties rather than having private backing fields and void methods to set/get.
Use property for simple calculations such as working out invoice amount.
Don't asssign to private variable then return said variable.
Use unit tests to test your logic rather than a main method. What happens when your code grows, how are you going to test it all using one entry point?
Don't use protected keywords like in for variable names (in your main function).
The following code is in C#, but it should be easily transcribable to Java. Do some research on unit testing frameworks for Java and try and incorporate that into your workflow.
public class Invoice
{
public string ModelName { get; set; }
public double Price { get; set; }
public double Amount { get; set; }
public double InvoiceAmount => Price * Amount;
}
[TestClass]
public class InvoiceTest
{
[TestMethod]
public void TestInvoiceAmount()
{
// Arrange
var testInvoice = new Invoice()
{
ModelName = "Audi R8",
Price = 5000.0,
Amount = 1
};
// Act
double invoiceAmount = testInvoice.InvoiceAmount;
// Assert
Assert.IsTrue(invoiceAmount == 5000.0);
}
}

Changing parent object to child object

I need a bit of help here. so i have this. I was basically wondering when you create an array of object of a parent class, then change that object to a child class, can I access the methods of that child class and if not why. thanks for any help.
public class Racer {
private String name;
private int position;
// Constructor
public Racer()
{}
public Racer(String name)
{
this.name = name;
position = 0;
}
public String getName()
{
return name;
}
public int getPosition()
{
return position;
}
public void setPosition(int n)
{
position = n;
}
public void setName(String n){
this.name=n;
}
}
the child class
public class Spartiates extends Racer{
private int energy;
public Spartiates(){
super();
}
public Spartiates(String name){
setName(name);
setPosition(20);
energy=100;
}
public void setEnergy(int energy){
this.energy=energy;
}
public int getEnergy(){
return energy;
}
}
main class
public class demo{
public static void main(String[] args){
Racer [] player = new player[3];
for(int i=0; i<player.length; i++){
player[i] = new Spartiates();
}
System.out.println(player[1].getEnergy());
}
so here the problem the getEnergy method doesn't work so I was wondering why. If anybody can help it would be very much appreciated. thanks
This is discussed here:
Is it possible to call subclasses' methods on a superclass object?
Along with all the reasons why doing something like this is probably never a good idea :).
You'll have to cast it to an instance of the subclass. If you plan on having a mixed array of object instances you'd need to first check the type:
System.out.println(((Racer)player[1]).getEnergy());
You need either define the function in the superclass or cast the object to the subclass.
If you intend the array to hold ONLY elements of the subclass Spartiates, then declare it as such.
Otherwise, if it needs to hold objects of both type, there only way to do this is to check with instanceof.
if (player[1] instanceof Spartiates)
System.out.println(((Spartiates)player[1]).getEnergy());
else
// handle other types
The reason energy is 0 is because you are calling your empty (no arg) constructor:
player[i] = new Spartiates();
which does not initialize the energy variable (so it will be 0 by default). You only set the variable to 100 in the constructor which takes in a String, namely here:
public Spartiates(String name){
setName(name);
setPosition(20);
energy=100;
}
So either call that constructor in the for loop with some string as an argument, or call your setEnergy() setter with some value after creating the object with the empty constructor.
Also, this is wrong:
Racer [] player = new player[3];
It should read:
Racer [] player = new Racer[3];
or:
Racer [] player = new Spartiates[3];

creating graphs in Java with ArrayLists

I'm new to Java and I wanted to practice by creating a graph. I am having trouble creating the graph because I'm not sure how to do so correctly. I am lacking the logic and being new in Java makes things quite difficult. I was wondering if anyone could help me or guide me in the right path! Thanks!
Basically I am trying to create something like this as a graph. A node will contain an ArrayList for it's neighbors.
A,B,C,D
A = 0,1,3,0
B = 1,0,0,2
C = 1,0,0,3 //shorter path to A (cycle)
D = 0,0,3,0
The nodes are connected to each other with or without weights (if I change numbers to 1)
Here is what I have so far (it is incomplete):
public class GraphNode {
boolean visited;
public GraphNode() {
List<GraphNode> node = new ArrayList<GraphNode>(); // store neighbors
this.visited = false;
}
public void addNeighbor(GraphNode root, GraphNode target, int distance) {
root.add(target); // cannot use "add" to ArrayList
}
}
To be able to access the ArrayList from accross methods within the same class, you would need to promote that local variable to a global variable (field), like below:
public class GraphNode {
/*Global Variables*/
boolean visited;
List<GraphNode> nodeNeighbours;
/*Global Variables*/
public GraphNode() {
this.nodeNeighbours = new ArrayList<GraphNode>(); // store neighbors
this.visited = false;
}
public void addNeighbor(GraphNode target) {
this.nodeNeighbours.add(target); //This will add target to the neighbours of this given node.
}
}
EDIT:
Shortest path algorithms (as far as memory serves) have a fixed starting point, meaning that the root will always be the same. The same can be said to their weight, which usually does not change.
However, as different paths are explored, the distance to the root node is most likely to change. With that in mind, you could re write your class as follows:
public class GraphNode {
/*Global Variables*/
protected double weight;
protected double distanceFromRoot;
protected List<GraphNode> neighbours;
protected boolean visited;
/*Global Variables*/
public GraphNode(double weight, double distanceFromRoot) {
this.weight = weight;
this.distanceFromRoot = distanceFromRoot;
this.neighbours = new ArrayList<GraphNode>();
this.visited = false;
}
public void setDistanceFromRoot(double distanceFromRoot) {
this.distanceFromRoot = distanceFromRoot;
}
public void setVisited(boolean visited) {
this.visited = visited;
}
public double getWeight() {
return this.weight;
}
public double getDistanceFromRoot() {
return this.distanceFromRoot;
}
public List<GraphNode> getNeighbours() {
return this.neighbours;
}
public void addNeighbour(GraphNode neighbour) {
this.neighbours.add(neighbour)
}
}
This might be a little bit more extensive than what you started with. The main change in your code is that this code promoted encapsulation. Encapsulation is one of the core fundamentals of OOP in which you essentially deny direct access to your global variables. The access is offered through appropriate set and get method which you can use to define how and when does someone external to your program modifies the internal state of your program.

Categories

Resources