I have an abstract class called Expression which represents the result of a math expression and the class AtomicExpression which represents an operand of a math expression which extends Expression. AtomicExpression class has the method toString(). Inexplicably, whenever I initialize an instance of AtomicExpression then toString() is called automatically even though I didn't call it explicitly. I don't understand how this can be.
Originally I noticed that String.format from toString() was returning an error before toString() would be called, so I decided to add System.out.println inside toString() to see from console each time a call would be made to toString().
This is the code:
public abstract class Expression {
private double expression;
public Expression(double expression) {
this.expression = expression;
}
public abstract double calculate();
public boolean equals(Object o) {
Expression e = (Expression) o;
return this.expression == e.expression;
}
}
public class AtomicExpression extends Expression {
private double operand;
private static final String BLANK = "";
public AtomicExpression(double operand) {
super(operand);
this.operand = operand;
}
public double calculate() {
return this.operand;
}
public String toString() {
String s;
if(this.operand == (int) this.operand) { //the operand is an integer
//s = String.format("%d", this.operand);
System.out.println("this.operand == (int) this.operand");
s = BLANK + this.operand;
return s;
} else { //the num is a double
s = BLANK + this.operand;
return s;
}
}
}
public class Main {
public static void main(String[] args) {
AtomicExpression a = new AtomicExpression(5);
//System.out.println(a);
}
}
Related
I don't know how to write my toString() method.
This is my Main.java
Dice d = new Dice();
System.out.println(d);
d= new Dice(3);
System.out.println(d);
How should I write my toString() method, do I need to write two toString()'s ?
My Dice():
public class Dice {
private double kz= Math.random() * (6 - 1) + 1;
private double mz;
public Dice() {
this.kz= Math.random() * (6 - 1) + 1;
}
public Dice(double n) {
this.mz= n;
}
public String toString() {
return String.format("%.0f", this.kz);
}
}
I tried it with this, but it's not working
public String toString(double i) {
return String.format("%.0f", this.mz);
}
Instead of having two separate members for the two constructors, you could use the same member. This way, your toString method doesn't need to try and figure out how the object was constructed:
public class Dice {
private double kz;
public Dice() {
this(Math.random() * (6 - 1) + 1);
}
public Dice(double n) {
this.kz = n;
}
public String toString() {
return String.format("%.0f", this.kz);
}
}
The toString() method is the default method that is called most of built-in java classes and it's a standard for returning object information as a string.
Your method:
public String toString(double i) {
return String.format("%.0f", this.mz);
}
isn't working because by convention methods like Stystem.out.println() will look for the standard signature, not a weird toString(doulbe foo).
If you want to see your object state at the method call you can do something like this:
public String toString(double i) {
return String.format("kz = %.0f, mz = %.0f, ", kz, mz);
}
There are some tweaks that you can make to your Dice class:
You can also omit the this keyword, you have to use when you want to reference the same object you are in or when there are conflicts like this:
public class Dice {
private double foo;
// If you try to remove this. you will get a runtime error
public Dice(double foo) {
this.foo = foo;
}
}
You can have only one variable and multiple constructors that calls themself (credit to Mureinik's answer):
public class Dice {
private double kz;
public Dice() {
this(Math.random() * (6 - 1) + 1);
}
public Dice(double n) {
this.kz = n;
}
}
In this code, I have an overridden toString() method. I call this toString() method in a subclass of the ArithBinaryExpression class called AddExpression.
It throws me an exception which goes back to the toString() method. I want to solve this stackoverflow error. Any help is appreciated!
Exception in thread "main" java.lang.StackOverflowError
at main$AddExpression.toString(main.java:20)
public class ArithValue implements ArithExpression {
private double doubValue;
ArithValue(double dVal) {
this.doubValue = dVal;
}
public double result() {
return doubValue;
}
#Override
public String toString() {
return String.valueOf(doubValue);
}
}
public static class AddExpression extends ArithBinaryExpression {
public AddExpression(ArithExpression leftExp, ArithExpression rightExp) {
super(leftExp, rightExp);
}
public double result() {
double rightExp = getRightExpression().result();
double leftExp = getLeftExpression().result();
return rightExp + leftExp;
}
public String toString() {
return "Expression: " + "(" + leftExpression.toString() + " + " + rightExpression.toString() + ")";
}
}
public abstract class ArithBinaryExpression implements ArithExpression {
protected static ArithExpression leftExpression;
protected static ArithExpression rightExpression;
// constructor
public ArithBinaryExpression(ArithExpression left, ArithExpression right) {
if (left == null) {
leftExpression = new ArithValue(0);
}
else
leftExpression = left;
if (right == null) {
rightExpression = new ArithValue(0);
}
else
rightExpression = right;
}
// end constructor
// accessors
public ArithExpression getLeftExpression() {
return leftExpression;
}
public ArithExpression getRightExpression() {
return rightExpression;
}
}
this is the ArithExpression interface:
public interface ArithExpression {
public abstract double result();
}
Conjecture: your bug is manifesting itself due to the fact you're using static variables for leftExpression and rightExpression.
Pasting the main method would allow us to determine if conjecture is true but it seems like something you wouldn't want anyway
Since leftExpression or rightExpression can be an instance of AddExpression you might have a cyclic dependency eg:
AddExpression e1 = new AddExpression(null, null);
AddExpression e2 = new AddExpression(e2, null);
e1.leftExpression = e2;
or
AddExpression e1 = new AddExpression(null, null);
e1.leftExpression = e1;
This examples will lead to infinite callbacks and result in the given overflow exception.
Try to add a instanceof check to the toString() method of AddExpression:
public String toString() {
if(this instanceof AddExpression){
//print stacktrace or something
return "possible cyclic dependency";
}
return "Expression: " + "(" + leftExpression.toString() + " + " + rightExpression.toString() + ")";
}
The check is itself isn't a real solution it is more like a check to ensure that a cyclic dependency is causing the problem. Normally it shouldn't be possible for a calculator (I guess that is what you are trying to code) to create cyclic dependenices. Instead this would cause a Syntax error.
However I can understand that it may be hard to prevent the user from defining any illegal expression, so you might want to count the recursion depth for example by a static variable to prevent at least a stackoverflow.
Java noob here, i have a program that i want to iterate the number of plugins that has been added in another file, then as long as it's a prefix and postfix calculator i want to check if the symbol in the stack for example is '+' so find Addition class that extended from Operator class and then call doAction(stack.pop(), stack.pop()) , it's because i want to add unlimited methods for calculating more symbols
i tried to use reflection but i couldn't understand how to loop over between names to let the program choose the right method
public class Operator {
public int doAction(int op1, int op2) {
return 0;
}
public String getOperator(String sign) {
return null;
}
public String setOperator() {
return null;
}
}
class Plus extends Operator {
public int doAction(int op1, int op2) {
return op1 + op2;
}
public String setOperator() {
return "+";
}
public String getOperator(String sign) {
if (sign.equals("+")) {
return "+";
} else {
return null;
}
}
}
class Minus extends Operator {
public int doAction(int op1, int op2) {
return op1 - op2;
}
public String setOperator() {
return "-";
}
public String getOperator(String sign) {
if (sign.equals("-")) {
return "-";
} else {
return null;
}
}
}
By reading your requirement I would suggest to use Factory or Abstract Factory design pattern. Basically you want to execute particular class's method based on your parameter. You can create factory class which return your desired class based on parameter you passed and it will do your work. for reference
Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 8 years ago.
Improve this question
What I'm trying to do is to get this line of code to work in my main method:
Expression exp = new Add(new Value(3.2), new Multiply(new Value(4.1),
new Value(7.1)));
Here's my code:
public interface Expression {
public int accept(EvaluationVisitor visitor);
}
My Operation Class
public class Operation implements Expression {
private Expression lhs;
private Expression rhs;
public Operation(Value lhs, Value rhs)
{
this.lhs = lhs;
this.rhs = rhs;
}
public Expression getLHS()
{
return lhs;
}
public Expression getRHS()
{
return rhs;
}
public int accept(EvaluationVisitor visitor) {
return 0;
}
}
Value Class(represents a float value):
public class Value implements Expression {
private float number;
public Value(float number)
{
this.number = number;
}
public String toString()
{
return String.valueOf(number);
}
public float getValue()
{
return number;
}
public int accept(EvaluationVisitor visitor) {
return 0;
}
}
My Add and Multiply methods:
public class Add extends Operation {
private Value lhs;
private Value rhs;
public Add(Value lhs, Value rhs)
{
super(lhs,rhs);
}
public String toString()
{
return String.valueOf(lhs.getValue() + rhs.getValue());
}
public Value add()
{
return new Value(lhs.getValue() + rhs.getValue());
}
}
public class Multiply extends Operation{
private Value lhs;
private Value rhs;
public Multiply(Value lhs, Value rhs)
{
super(lhs,rhs);
}
public String toString()
{
return String.valueOf(lhs.getValue() + rhs.getValue());
}
public Value mul()
{
return new Value(lhs.getValue() * rhs.getValue());
}
}
Here's the line of code again:
Expression exp = new Add(new Value(3.2), new Multiply(new Value(4.1),
new Value(7.1)));
In my line of code that I'm trying to get to work, I want to find a way that the Multiply object can be a value can be taken in as an argument. I know that I could just create the object and then place it there by calling my method that returns a Value object, but a constructor is supposed to set up an object so the state of the object is valid. Is there anyway I could get around this?
You need to make full use of your interface so you can treat the values and operator expressions indiscriminately. Right now you aren't doing that, for example, Operation which takes two Values as arguments but stores them as Expressions.
You also have a problem which is that your subclasses of Operation are declaring duplicate members named lhs and rhs. Perhaps you've already noticed that right now you'll get null pointer exceptions if you try to call methods on Add and Multiply.
Here is a slight redesign:
public interface Expression {
public Value evaluate();
}
public class Value implements Expression {
private final float floatValue;
public Value(float floatValue) {
this.floatValue = floatValue;
}
public float floatValue() {
return floatValue;
}
#Override
public Value evaluate() {
return this;
}
}
public abstract class BinaryOperator implements Expression {
protected final Expression lhs, rhs;
public BinaryOperator(Expression lhs, Expression rhs) {
this.lhs = lhs;
this.rhs = rhs;
}
}
public class Add extends BinaryOperator {
public Add(Expression lhs, Expression rhs) {
super(lhs, rhs);
}
#Override
public Value evaluate() {
return new Value(
lhs.evaluate().floatValue()
+
rhs.evaluate().floatValue()
);
}
}
public class Multiply extends BinaryOperator {
public Multiply(Expression lhs, Expression rhs) {
super(lhs, rhs);
}
#Override
public Value evaluate() {
return new Value(
lhs.evaluate().floatValue()
*
rhs.evaluate().floatValue()
);
}
}
Now you can do
Expression exp = (
new Add(new Value(3.2f), new Multiply(new Value(4.1f), new Value(7.1f)))
);
System.out.println(exp.evaluate().floatValue());
Which outputs 32.309998 (the correct answer).
The above redesign could be further simplified if evaluate simply returned a float.
The constructors take Value objects but Multiply does not extend Value
What you are doing is adding a value to an operation. What you really want to be doing is adding a value to a value (the latter being the result of an operation). So you should do the following:
Expression exp = new Add(new Value(3.2), new Multiply(new Value(4.1),
new Value(7.1)).mul());
Alternatively, you could make your Operation class extend Value and override the getValue() method inside the Multiply class to perform the multiplication and return the value (likewise in the Add class to perform the addition and return the value).
Is there a "typeof" like function in Java that returns the type of a primitive data type (PDT) variable or an expression of operands PDTs?
instanceof seems to work for class types only.
Try the following:
int i = 20;
float f = 20.2f;
System.out.println(((Object)i).getClass().getName());
System.out.println(((Object)f).getClass().getName());
It will print:
java.lang.Integer
java.lang.Float
As for instanceof, you could use its dynamic counterpart Class#isInstance:
Integer.class.isInstance(20); // true
Integer.class.isInstance(20f); // false
Integer.class.isInstance("s"); // false
There's an easy way that doesn't necessitate the implicit boxing, so you won't get confused between primitives and their wrappers. You can't use isInstance for primitive types -- e.g. calling Integer.TYPE.isInstance(5) (Integer.TYPE is equivalent to int.class) will return false as 5 is autoboxed into an Integer before hand.
The easiest way to get what you want (note - it's technically done at compile-time for primitives, but it still requires evaluation of the argument) is via overloading. See my ideone paste.
...
public static Class<Integer> typeof(final int expr) {
return Integer.TYPE;
}
public static Class<Long> typeof(final long expr) {
return Long.TYPE;
}
...
This can be used as follows, for example:
System.out.println(typeof(500 * 3 - 2)); /* int */
System.out.println(typeof(50 % 3L)); /* long */
This relies on the compiler's ability to determine the type of the expression and pick the right overload.
You can use the following class.
class TypeResolver
{
public static String Long = "long";
public static String Int = "int";
public static String Float = "float";
public static String Double = "double";
public static String Char = "char";
public static String Boolean = "boolean";
public static String Short = "short";
public static String Byte = "byte";
public static void main(String[] args)
{
//all true
TypeResolver resolver = new TypeResolver();
System.out.println(resolver.getType(1) == TypeResolver.Int);
System.out.println(resolver.getType(1f) == TypeResolver.Float);
System.out.println(resolver.getType(1.0) == TypeResolver.Double);
System.out.println(resolver.getType('a') == TypeResolver.Char);
System.out.println(resolver.getType((short) 1) == TypeResolver.Short);
System.out.println(resolver.getType((long) 1000) == TypeResolver.Long);
System.out.println(resolver.getType(false) == TypeResolver.Boolean);
System.out.println(resolver.getType((byte) 2) == TypeResolver.Byte);
}
public String getType(int x)
{
return TypeResolver.Int;
}
public String getType(byte x)
{
return TypeResolver.Byte;
}
public String getType(float x)
{
return TypeResolver.Float;
}
public String getType(double x)
{
return TypeResolver.Double;
}
public String getType(boolean x)
{
return TypeResolver.Boolean;
}
public String getType(short x)
{
return TypeResolver.Short;
}
public String getType(long x)
{
return TypeResolver.Long;
}
public String getType(char x)
{
return TypeResolver.Char;
}
}
There are two ways that you can use to determine the type of the Primitive type.
package com.company;
public class Testing {
public static void main(String[] args) {
int x;
x=0;
// the first method
System.out.println(((Object)x).getClass().getName());
if (((Object)x).getClass().getName()=="java.lang.Integer")
System.out.println("i am int");
// the second method it will either return true or false
System.out.println(Integer.class.isInstance(x));
}
}