Java constructor with instance methods - java

over here I have some code that is supposed to make a constructor and some getters for my Fraction class. I'm wondering, is it possible to get both parameters in one getter? Because I'm only supposed to use only one method into obtaining both of my results.
Such as "1/2 and 3/5" for example.
import java.lang.reflect.*; import java.lang.annotation.*; import java.util.*; import java.time.*; // Please do not change or remove this line.
class Fraction {
private Integer nominator;
private Integer denominator;
public Fraction(Integer nominator, Integer denominator){
this.nominator = nominator;
this.denominator = denominator;
}
public Integer getNominator() {
return nominator;
}
public Integer getDenominator() {
return denominator;
}
}
class Main {
public static Fraction createFraction(Integer nominator, Integer denominator) {
return new Fraction(nominator, denominator);
}
public static void main(String[] arguments) {
final Fraction HALF = createFraction(1, 2);
final Fraction THREE_FIFTH = createFraction(3, 5);
System.out.println((HALF));
System.out.println((THREE_FIFTH));
}
public static String toString(Fraction fraction) {
return fraction.getDenominator() + "/" + fraction.getNominator();
}
}

First of all, great that you don't have setters and your class is functionally immutable--good start!
I would somewhat resist getting the nominator and denominator at all. You will eventually have to I'm sure, but try to avoid it.
For instance, if you were multiplying two Fractions you would simply have a Fraction.multiply(Fraction) method that returns a new Fraction, no need for getters. Anything you might want to do to the nominator/denominator you should be able to do inside the Fraction class.
As for if you really NEED to get the values (with one method):
Return a float (do the division internally)
return a string (like your toString method, but in the fraction class)
A string could also look like "7r1" for a value of 15/2.
you COULD return an array but I don't recommend it, cryptic return values are not awesome.
I don't recommend a sub-object either, it would have to have two getters so you aren't really solving any problems here, just kicking it down the line.
I'd consider a getIntegerValue() and getRemainder() but those are two methods--still they are a decent approach.

create a small class and return it or use an array
for example something like this
class Fraction1{
private int nominator;
private int denominator;
}
public Fraction1 getDenominator() {
Fraction1 fr=new Fraction1();
fr.nominator=this.nominator;
fr.denominator=this.denominator;
return fr;
}
..............

Related

Java How to chain with Math class

I am at the very basics of learning Java, I have tried searching for this answer but maybe I do not know what I am searching for.
I want to perform multiple operations on a number, so far the only way I know how to do that is the have intermediate variables with operations performed one at a time. This can't be the best way. The following is code in my main method that I would love to have work:
double sqrtAbsInput = promptForDouble("I can get the square root of the absolute value.");
double sqrtAbsOutput = sqrtAbsInput.Math.abs().sqrt();
System.out.println(sqrAbsOutput);
promptForDouble() method returns a double, it is the second line that concerns me most. The error I get is
"error: double cannot be dereferenced."
I assume what's going on is the variable needs to be the argument of the Math class methods, but I understand it could also have to do with the variable being a primitive type.
abs and sqrt aren't methods of double (which is a primitive, so it doesn't have any methods anyway - as noted in the error message you're getting), but static method of Math that take a double as an argument and return a double result:
double sqrtAbsOutput = Math.sqrt(Math.abs(sqrtAbsInput));
Math class does not implement "builder pattern" (for efficiency reasons), but you can create your own Math class implementation which allows chaining.
Here is an example:
public class MathBuilder {
private double value;
public MathBuilder(double value) {
this.value = value;
}
public MathBuilder abs() {
value = Math.abs(value);
return this;
}
public MathBuilder sqrt() {
value = Math.sqrt(value);
return this;
}
// other builder-math methods...
public double build() {
return value;
}
}
Usage:
double result = new MathBuilder(-10).abs().sqrt().build();
Or with Java 8:
public class MathBuilder {
private double value;
public MathBuilder(double value) {
this.value = value;
}
public MathBuilder apply(DoubleUnaryOperator o) {
value = o.applyAsDouble(value);
return this;
}
public double build() {
return value;
}
}
Usage:
double result = new MathBuilder(-10)
.apply(Math::abs)
.apply(Math::sqrt)
.build();
You will have to do this:
System.out.println(Math.sqrt(Math.abs(sqrtAbsInput)));

java: Confusing instructions on programming exam

Okay so don't get turned off by the fact that I want homework help.
Anyways, I don't want to explain the entire project for this little bit of help, but I'll just list some rules, and what I did with them. They're in weird order and they don't make complete sense. And there are many ways to do this probably, and I simply don't know what is what.
So here's the rules I'm confused about:
Three fields, a String for name of the purchase, int for units purchased, and a double for cost per unit.
So I made this:
private String purchase = "";
private int unitsPurchased = 0;
private double costPerUnit = 0;
Then, next rule:
Standard accessors and modifier methods for each field, so I made this:
//Accessors
public String purchase(){
return purchase;
}
public int unitsPurchased(){
return unitsPurchased;
}
public double costPerUnit(){
return costPerUnit;
}
//Modifiers
public void setPurchase(String purchase){
this.purchase = purchase;
}
public void setunitsPurchased(int unitsPurchased){
this.unitsPurchased = unitsPurchased;
}
public void setCostPerUnit(double costPerUnit){
this.costPerUnit = costPerUnit;
}
Then this: Negative values are not allowed, so change those to zero in all cases.
Wasn't sure if that meant to do anything, so I continued on.
Then this: Constructor to initialize these three fields (String, int, double) in that order.
So I did this:
public Purchase(String initialPurchase, int initialUnitsPurchased, double initialCostPerUnit){
purchase = initialPurchase;
unitsPurchased = initialUnitsPurchased;
costPerUnit = initialCostPerUnit;
}
Then this rule: Constructor overload, (String, double) assumes the int quantity is zero.
I didn't know if that meant anything, so once again I skipped it
Then this rule: Default constructor that assumes name is “” and numbers are zero, must call the three argument constructor.'
Now I'm just confused. So first of all, I would like to know if my code seems right. I don't think I need to explain the backstory of the program to do that. Then, I would love to know what to do about that last rule, because it says "must call the three argument constructor" am I supposed to use "this"? I didn't know where to go and I've tried a couple ideas but I don't think it works. I can't test to see if it's right either, given there's not really anything to test. Thanks so much to anyone who helps.
Here's just everything I've written:
public class Purchase {
private String purchase = "";
private int unitsPurchased = 0;
private double costPerUnit = 0;
//Accessors
public String purchase(){
return purchase;
}
public int unitsPurchased(){
return unitsPurchased;
}
public double costPerUnit(){
return costPerUnit;
}
//Modifiers
public void setPurchase(String purchase){
this.purchase = purchase;
}
public void setunitsPurchased(int unitsPurchased){
this.unitsPurchased = unitsPurchased;
}
public void setCostPerUnit(double costPerUnit){
this.costPerUnit = costPerUnit;
}
//Default constructor
public Purchase(){
purchase = "";
unitsPurchased = 0;
costPerUnit = 0;
}
//first constructor
public Purchase(String initialPurchase, int initialUnitsPurchased, double initialCostPerUnit){
purchase = initialPurchase;
unitsPurchased = initialUnitsPurchased;
costPerUnit = initialCostPerUnit;
}
//constructor overload
//Default constructor
}
You don't really need that but just in case. That's all a mess, not sure what I'm writing. But thanks to anyone that helps.
Starting with the first rule you didn't understand:
Negative values are not allowed, so change those to zero in all cases.
This is referring to the setter methods you wrote, and it means that if someone calls setUnitsPurchased with a negative number as a parameter, you only set unitsPurchased = 0.
You'll probably want to add an if statement (or ternary, if you're familiar with those) to setUnitsPurchased and setCostPerUnit checking for values below zero.
Wasn't sure if that meant to do anything, so I continued on. Then this: Constructor to initialize these three fields (String, int, double) in that order.
Instead of directly setting the values (like you did):
purchase = initialPurchase;
unitsPurchased = initialUnitsPurchased;
costPerUnit = initialCostPerUnit;
You should probably call your setters, so you don't have to repeat your checks:
this.setUnitsPurchased(initialUnitsPurchased);
// etc.
Constructor overload, (String, double) assumes the int quantity is zero.
If a class has an overloaded constructor, it means that you can initialize it with different amounts and/or types of parameters. You've already overloaded the constructor with an empty constructor and one that takes three arguments.
Simply make another constructor, but with this signature:
public Purchase(String initialPurchase, double initialCostPerUnit)
Default constructor that assumes name is "" and numbers are zero, must call the three argument constructor.
Instead of the default constructor you implemented, you must call the three argument constructor. To call another constructor, use the this keyword, and invoke it like a method, passing in the correct parameters:
this("", 0, 0);
Happy Coding!
Couldn't be more self-explanatory. It writes itself if you can read:
public class Purchase {
private String purchase;
private int numUnits;
private double costPerUnit;
public Purchase() {
this("", 0, 0.0);
}
public Purchase(String purchase, double costPerUnit) {
this(purchase, 0, costPerUnit);
}
public Purchase(String purchase, int numUnits, double costPerUnit) {
this.purchase = purchase;
this.numUnits = (numUnits < 0) ? 0 : numUnits;
this.costPerUnit = (costPerUnit < 0.0) ? 0.0 : costPerUnit;
}
// Leave the rest for you.
}
Three fields, a String for name of the purchase, int for units purchased, and a double for cost per unit.
You got it correct, though there is no need for assigning any values to the data members.
private String purchase;
private int unitsPurchased;
private double costPerUnit;
Standard accessors and modifier methods for each field
You got this correct too.
Negative values are not allowed, so change those to zero in all cases.
You need to change your code to convert neg values to zero. e.g.
public void setunitsPurchased(int unitsPurchased){
if(unitsPurchased < 0)
unitsPurchased = 0;
this.unitsPurchased = unitsPurchased;
}
Constructor to initialize these three fields (String, int, double) in that order.
You got this correct. Though you might want to have this keyword for data members. It just makes it more readable.
public Purchase(String initialPurchase, int initialUnitsPurchased, double initialCostPerUnit){
this.purchase = initialPurchase;
this.unitsPurchased = initialUnitsPurchased;
this.costPerUnit = initialCostPerUnit;
}
Constructor overload, (String, double) assumes the int quantity is zero.
This is simple. you want a constructor with just 2 arguments. It also specifies to have unitsPurchased set to 0.
public Purchase(String initialPurchase, double initialCostPerUnit){
this.purchase = initialPurchase;
this.unitsPurchased = 0;
this.costPerUnit = initialCostPerUnit;
}
Default constructor that assumes name is “” and numbers are zero, must call the three argument constructor.'
Now you know a default constructor does not take any arguments. but the question asks to call the three argument constructor from within this constructor. that can be done using the this() as follows:
public Purchase(){
this("", 0, 0.0);
}

Incorrect Casting

For some reason I am getting a precision error when I try to compile my code. The precision error comes in the return of my second method where I am trying to calculate the circumference. What am I doing incorrectly?
public class Methods2
{
public static final double PI = 3.14;
public static double calcCirc(double x)
{
return PI*x;
}
public static int calcCirc(int x)
{
return (2*(double) x)*PI;
}
public static void main(String[]args)
{
System.out.println(calcCirc(10.2));
System.out.println(calcCirc(4));
}
}
You are attempting to return a double value in a method declared to return an int. Java won't let you implicitly narrow your value like that.
If you're okay with the loss of precision, then explicitly cast the value to int -- Java will let you do that.
return (int) ((2*(double) x)*PI);
However, I would change the method to return double instead, not to lose precision:
public static double calcCirc(int x)
... as you already did with your other calcCirc method.
Both versions of calcCirc() ought to return doubles.
Also, side note--consider using different method names since they accept inputs that differ not only in type but also in semantics.
E.g. calcCircFromRadius(double radius), calcCircFromDiameter(double diameter). There's not really a reason to take an int as an input type here since Java will automatically cast ints to doubles for you.
try
public static int calcCirc(int x){
return (int)((2*x)*PI);
}

does this code about arrays make any sense?

I am watching a lecture from the University of California at Berkeley about creating arrays in Java. The professor presents the following code, and claims the code will create fractions such as 1/6, 2/6, etc. (I added main() so it can be tested.)
public class Test {
public static void main(String[] args) {
Fraction[] f = new Fraction[5];
for (int i=0; i<5; i++){
f[i] = new Fraction(i, 6);
}
}
}
I am testing this in Eclipse, obviously the code does not compile since there is no class Fraction, and even if I change Fraction to double the code still will not produce any fractions.
I am guessing the professor intended to write this:
public class Test {
public static void main(String[] args) {
double[] f = new double[5];
for (int i=0; i<5; i++){
f[i] = (i/6);
}
}
}
Is my reasoning correct?
Source: https://www.youtube.com/watch?v=wGibp2L5uCc #12:25
First of all, note that this will start at 0/6, not 1/6. Second of all, the professor is most probably referring to a hypothetical Fraction class that stores exact fractions (i.e. a numerator and a denominator as two ints); a double cannot do this.
Now, if you want to use doubles (which will not store exact fractions per se but rather the approximate numbers they represent), you have to use double division (and not integer division, as you are currently performing):
f[i] = i/6.0;
As #StephenTG points out, the Fraction class seems to be implemented here.
Yes and no. This:
f[i] = new Fraction(i, 6);
Means
Store on position i of the f array, this fraction object
f is a Fraction[], meaning that each index contains a Fraction typed object. You need to create a new one (i.e. new Ftaction(1,6)) in order to store 1/6. You were right about what to store, you just were not getting the whole picture about how do you represent it.
Just for the sake of your class, I assume that Fraction is a type created by your teacher and that you have to include in your project (As others have correctly suggested, you might be searching for this class)
There is fraction class here:
http://www.cs.berkeley.edu/~jrs/61bf98/labs/lab2/Fraction.java
I assume this is part of your class as well.
You have to download this file and add it to your project.
Well, if the Fraction class has a method to return a double or a float, it can be very well constructed with int actually.
Then the internal logics will take care of processing and returning the correct type.
Consider this example:
public static void main(String[] args) {
System.out.println(new Fraction(1, 6).getFraction());
}
static class Fraction {
private float fraction;
public Fraction(int num, int den) {
// TODO check that den != 0, otherwise we're in a world of trouble :D
fraction = (float) num/den;
}
public float getFraction() {
return fraction;
}
}
Output:
0.16666667
You need to create the Fraction class in order to create an array of Fraction objects.
From StephenTG's comment, it looks like you need to import Fraction.java into eclipse.
(This Fraction.java has a main method for testing purposes. You can place your code in that method, or you need to remove that method if you want to use your own main method.)
You should define a Fraction class first:
public class Fraction
{
int numerator;
int denominator;
public Fraction(){}
/* watch out for a division by zero Exception!
* maybe throw a custom exception here
*/
public Fraction(int n, int d){
numerator = n;
denominator = d;
}
public float getValue(){
return numerator * 1.0f/denominator;
}
}
your first snippet will only make sense if your Fraction class has a constructor that takes two integer values (e.g.):
class Fraction
{
private int val1, val2;
public Fraction(int val1, int val2)
{
this.val1 = val1;
this.val2 = val2;
}
}
For your second part of the question, your loop will first return an integer and then type-cast it to double. So, the result in your case will always be zero, even though you know it shouldn't. To fix this, any of the following two lines of code will do.
f[i] = ((i + 0.0)/6);
or
f[i] = (i/6.0);

inheritance class fraction/integer

So, I created a simple class named Test, as follows:
import prog.utili.IntegerB;
//It's a custom class
class Test
{
public static void main(String[] args)
{
IntegerB a = new IntegerB(1);
IntegerB b = new IntegerB(2);
IntegerB sum = a.plus(b);
System.out.println(sum);
}
}
I wanted to practise with inheritance so I created two custom classes. Fraction...
package prog.utili;
public class Fraction
{
private int num;
private int den;
public Fraction(int x, int y)
{
[...]
}
public Fraction(int x)
{
this(x, 1);
}
public Fraction plus(Fraction f)
{
int n = this.num * f.den + this.den * f.num;
int d = this.den * f.den;
return new Fraction(n, d);
}
[...]
}
...and IntegerB:
package prog.utili;
public class IntegerB extends Fraction
{
public IntegerB(int num)
{
super(num);
}
public IntegerB plus(IntegerB other)
{
return (IntegerB)this.plus(other);
}
}
The problem is I keep getting the same error:
at prog.utili.IntegerB.plus(IntegerB.java:11)
I know I could simply solve the problem by just deleting the last method on IntegerB and replacing the 9th line of Test.java with
IntegerB sum = (IntegerB)a.plus(b)
but I absolutely want to do it using the inheritance rules over the "plus" method!
To implement the method plus(IntegerB), you call plus(IntegerB), which calls plus(IntegerB), etc. etc. until you get a StackOverflowError.
Provide an actual implementation for your method:
return new IntegerB(this.getNum() + other.getNum());
or
return new IntegerB(super.plus(other).getNum());
Also note that replacing the last line of Test.java by
IntegerB sum = (IntegerB)a.plus(b);
wouldn't work, since the plus() method in Fraction doesn't return an IntegerB, but a Fraction. You would thus get a ClassCastException.
The problem here is that IntegerB.plus does not override Fraction.plus, it overloads it. This is because the argument types are different. Thus when IntegerB.plus calls this.plus(other), it ends up calling itself, which then calls itself, which then calls itself until you get a StackOverflow (thus sending you to stackoverflow : )).
It seems like you want to call plus(Fraction) instead of plus(IntegerB). To do that, you can explicitly upcast other:
return plus((Fraction) other);
This cast has no effect other than to tell the compiler that you want to call the version of plus that handles Fractions, even though you know you have an IntegerB.
However, this method would not return an IntegerB, but just a Fraction whose denominator is 1. You could conceivably override plus to return an IntegerB if the denominator of the result is 1, but that might lead to unexpected situations where a.plus(b) is not equal to b.plus(a) because one is a Fraction while the other is an IntegerB. Alternatively, you could return IntegerB objects from Fraction.plus when possible.

Categories