I have a class that stores a number in the millions. What I would like to do is override the method to get that number and apply a string formatter for readable UIX output.
This is what I have to "overload" the to gets:
class dudViewModel {
public int gettotal () {
return this.total;
}
public String gettotal(String formated) {
return String.format("%.1f", (float)total / 1000000);
}
}
So it's the difference between the two following calls:
gettotal(); // returns 23,400,000
and
gettotal("formatted"); // returns 23.4
Is there a better way or pattern in java to overload an individual method() that returns a number and override i with a tostring() call somehow to overide default number return and instead return a formatted string?
I think the best way is to separate the presentation from the business logic. In this approach, you'd just have a single getTotal() method returning int. A completely separate method of a separate class would take that int and format it for the UI.
or patter in java to overload an individual method() that returns a number and override i with a tostring()
You can apply Decorator pattern which allows behavior to be added to an individual object, either statically or dynamically, without affecting the behavior of other objects from the same class
What a method does, must be indicated in its name. In this case, the two methods should be named different rather than trying to overload, overloading should alter the processing, not the total effect or output.
class dud {
public int getTotal () {return this.total;}
public String getFormattedTotal() {return String.format("%.1f", (float)total / 1000000);}
public String getFormattedTotal(String customFormat) {return String.format(customFormat, (float)total / 1000000);}
}
Separate the data from its representation and you can also test it in isolation.
class Dud {
public int getTotal () {return this.total;}
}
class DudPresentation {
private Dud dud;
public DudPresentation(Dud dud){
this.dud = dud;
}
public String getTotal() {
return getTotal("%.1f");
}
public String getTotal(String format) {
int total = dud.getTotal();
return String.format(format, (float)total / 1000000);
}
}
Related
I have the following type of Strings
"Move 1 place forwards";
"Move 1 place backwards;
Can I create a type called 2dMotion, where a method can only take in these two strings as arguments in Java.
public 2dMotion message(){ return "Move 1 place forwards"; }
For example if a method was classed that had 2dMotion as an input then it wouldn't be able to input anything but those 2 sentences
You can declare them as constants in a class, and provide direct access to them by making them public:
public MyClass {
public static final MOTION_FORWARD = "Move 1 place forward";
public static final MOTION_BACKWARDS = "Move 1 place backwards";
// Rest of the class omitted
}
Or, a better solution is to use an Enum.
public enum MOTION {
FORWARD("Move 1 place forward"),BACKWARDS("Move 1 place backwards");
private final String val;
private MOTION(String val) {
this.val = val;
}
public String getVal() {
return val;
}
}
To use the constant, simply use MyClass.MOTION_FORWARD. To use the enum, you could do MOTION.FORWARD.getVal();
Lastly, as good practice, you should override toString() method:
#Override
public String toString() {
return val;
}
Even though this method does the same as getVal(), it is consider good practice to do so. If you would like to remove one of those methods, it should be the getVal() method. Also, even though the enum solution involves more code, it is also considered to be a better solution. Also, when you override toString(), it allows to return the value of the enum without invoking toString() or getVal() directly. For example, System.out.println(MOTION.BACKWARDS); prints out "Move 1 place backwards".
Let me give you an example for what i'm trying to achieve. Look only to the numbers because it's a card game.
I have:
harten5 klaveren4 klaveren7 schoppen5 ruiten5 schoppen2 klaverenheer schoppenheer schoppendame schoppen6 klaverenboer schoppen8 ruitenheer klaveren6...
I want to sort this on the value to:
schoppen2 harten2 ruiten2 klaveren2 ruiten3 harten3 schoppen3 klaveren3 klaveren4 harten4 schoppen4 ruiten4 harten5 schoppen5 ruiten5...
But i get the 10 before the 2 like this:
schoppen10 ruiten10 harten10 klaveren10 schoppen2 harten2 ruiten2 klaveren2 ruiten3 harten3 schoppen3 klaveren3...
This is my basic compareTo Method:
#Override
public int compareTo(Card p) {
return this.value.compareTo(p.value);
}
Because String's (I guess this.value is String) compareTo compares lexicographically, whilst you want numerically. So you have to reimplement it, take substring (or find the last part which is a digit, convert it to Integer and then user compareTo on that Integer.
In general, I think your class Card could be improved a bit. In particular, I would rewrite it:
class Card {
private String value;
private Integer rank;
...
public int compareTo(Card c) {
// Additional logic if you need to consider
// also value (suite) in comparison
return this.rank.compareTo(c.rank);
}
}
But you can also use an enum for this purpose.
String java API compareTo
I'm guessing you want the reverse order? If so, then just change your implementation to this:
#Override
public int compareTo(Card p) {
return p.value.compareTo(this.value);
}
It really depends on what the type of "value" is and how the "compareTo" is implemented. Alternatively, you could just do this if "value" is an integer:
#Override
public int compareTo(Card p) {
return this.value - p.value;
}
I believe your value is stored as an String. If you do not want to change the data type of value, you can implement the compareTo method in the following way:
public int compareTo(Card p) {
return Integer.parseInt(this.value).compareTo(Integer.parseInt(p.value));
}
Hi I was just wondering if it is possible to have multiple toString() methods in the same class. The two different toString() methods print different things. ex:
public String toString(){
return String.format("(%.1f%+.1fi)%n", real, imaginary);
}
public String toString(){
return String.format("z=%.3f(cos(%.3f)+isin(%.3f))%n",real,imaginary,imaginary);
}
No, you can't have two methods with the same name and signature.
A "signature" in this case means the number of arguments and their types. Changing this won't allow you to override toString() twice, it'll just make one a normal method.
public String toString(){
return String.format("(%.1f%+.1fi)%n", real, imaginary);
}
public String toString( boolean fubar ){
return String.format("z=%.3f(cos(%.3f)+isin(%.3f))%n",real,imaginary,imaginary);
}
The second method has a different signature, so it's legal, but doesn't override toString().
You can have a toString() method that takes an argument to indicate the expected format of the output.
Say you have 3 formats. You can have an enum and based on the value you get, you print/return the value in that format.
EDIT 1
Let's say you have an enum
public enum PrintFormat{
F1, F2, F3
}
and the toString() method that you're going to overload
public toString(PrintFormat format){
switch(format){
case F1:
//return in a diff format
case F2:
//return in a diff format
//so on so forth
}
}
No, it is not possible to overrides multiple toString() in the same Class
In my worker class, I have several methods that return double values. In my driver class I'm tasked with putting each return value into a corresponding JTextField. For example, I have agetTotalTax methods that returns the total taxes paid, and that number has to be put in a JTextField in currency format. I don't know how I'm supposed to use my toString method.
As it stands I call this in my driver class:
totalTaxField.setText(Report.toString());
And my toString class:
public String toString(){
return fmt1.format(getTotalTax());
}
EDIT:
Here's more code to help express my problem:
public double getTotalTax(){
double totalTax = getTotalSales()*TAX_RATE;
return totalTax;
}
public double getTotalSales(){
double totalSales =
getSalesLarge()+getSalesMedium()+getSalesSmall()+getSalesStick();
return totalSales;
}
Those are two methods in my worker class, I need to take the result of both of them and place them in two different JTextFields like so.
totalSalesField.setText(?);
totalTaxField.setText(?);
I need to use the getString function to somehow set the text to the text field.
toString method is not a static method, so you should call it from a Report object like:
Report report = new Report();//suppose this a valid declaration form a Report class.
totalTaxField.setText(report.toString());
Your question is somewhat unclear but it sounds like you need to convert a double into a string with currency formatting.
Who can do that with the following:
public String toString(){
return NumberFormat.getCurrencyInstance().format(getTotalTax());
}
For example, I have a method that looks through a string for data separated by a specified deliminator, but some items might be a names, and other items might be numbers.
If a user calls my method to return item number X from the deliminated list, i want it to return a string if item X is a name, or a double if item X is a number.
For example, objectName.get(5); would get the 5th item in the deliminated list.
Would I have to use some type of overloading for this?
Or would I have to instead do something like objectName.getDouble(5); and objectName.getString(5); based on the fact that the user knows what item 5 is?
But what if the user doesn't know what item 5 is? He just needs a String or a Double depending on what it happens to be.
Here's one way to do this:
public Object get() {
if (blueMoon) {
return new Double(42.0);
} else {
return "fred";
}
}
Note that this will return a Double wrapper rather than a double.
I don't think this is a good idea though, since the caller now has to test the type of the returned value and do a typecast to do something with it.
For the record, Java does not allow a method to return a String or double because these types do not have a common supertype in the Java type system.
For this sort of thing, I prefer to use something akin to the Maybe/Option pattern from the functional programming camp. You end up with an interface like:
public abstract class DoubleOrString
{
// Constraint isDouble() xor isString()
public boolean isDouble();
public boolean isString();
//Must throw iff !isString()
public String getString();
//Must throw iff !ifDouble()
public Double getDouble();
public static DoubleOrString wrap(final double wrapMe)
{
return new DoubleOrString()
{
public boolean isDouble() {return true;}
public boolean isString() {return false;}
public Double getDouble() {return wrapMe;}
public String getString() {throw new RuntimeException();}
};
}
//same for wrap(String)
}
This forces the issue for clients, in that there is always a sanity check that there was indeed a double or String at the appropriate time. In your case, I'd make just one get() method, so when the client (thinks they) knows what the type is, the call is
objectName.get(5).getString();
and in your get(int) method, rather than returning a String or a double, the return statement looks like
DoubleOrString.wrap(theThingToReturn)
It's a little extra work up front, but it has paid of for me several times in the past.
Here's how you'd use it to build one (warning - this hasn't been near a compiler)
public static DoubleOrString parseADoubleOrString(String input) {
try {
return DoubleOrString.wrap(Integer.parseInt(input))
} catch (NumberFormatException nfe) {
return DoubleOrString.wrap(input);
}
}
and here's what the client looks like
String input = //get the input from the user somehow
DoubleOrString parsed = parseADoubleOrString(input);
if (parsed.isDouble())
aFunctionThatTakesADouble(parsed.getDouble());
else
aFunctionThatTakesAString(parsed.getString());
If you need to do this then there is problem with your design. Since the original datasource is String you have to accept that all returned values will be string and leave it to the client to check whether the result can be converted to a number.
If you want to save the client from doing the check, you can provide him with a minimal API which may look something like:
public class ValueExtractor {
public ValueExtractor(String delimitedText) {
// ...
}
/**
* Determines whether there is a next element
* to be returned
*/
public boolean next() {
// ...
}
public String get() {
// ...
}
/**
* Returns the value as a Double if possible
* null otherwise.
*/
public Double getPossibleDouble() {
// ...
}
}
The Java language does not expose an overload on the return type of a method. (As Thilo pointed out, this is a restriction of the Java language and not the JVM/bytecode.)
Generally this type of thing does not fit well into the Java type system. One could imagine returning an Either<String,Double> type (a more restricted return type than Object as suggested by Stephen C and a more general type than DoubleOrString as pointed out by B. Bear), but the general effort required to use such a construct in Java generally results in simply having multiple methods, e.g. getString(...) and getDouble(...).