5

Is it possible to have a function that returns either Integer or Float? I want to have the 2 functions become one if it's possible:

private static Integer parseStringFormatInt(String val){
    System.out.println(Integer.parseInt(val.substring(0, val.indexOf("."))));
    return Integer.parseInt(val.substring(0, val.indexOf(".")));
}
private static Float parseStringFormatFloat(String val){
    System.out.println(Float.parseFloat(val.substring(0, val.indexOf("."))));
    return Float.parseFloat(val.substring(0, val.indexOf(".")));
}
BenMorel
  • 34,448
  • 50
  • 182
  • 322
prog rice bowl
  • 788
  • 3
  • 19
  • 36

5 Answers5

8

Make the return type as Number since both Float and Integer are subtypes of Number like below

private static Number parseStringFormatNumber(String val){
    //Based on your conditions return either Float or Integer values
}

You can also make instanceof operator to do the test on the return value, to get the exact type of the returned value. i.e Float or Integer

if(returnedValue instanceof Float)
{
// type cast the returned Float value and make use of it
}
else if(returnedValue instanceof Integer)
{
// type cast the returned Integer value and make use of it
}
Keerthivasan
  • 12,760
  • 2
  • 32
  • 53
4

You can use Number as return type, or make the method generic

static <T extends Number> T parseString(String str, Class<T> cls) {
    if (cls == Float.class) {
        return (T) Float.valueOf(str);
    } else if (cls == Integer.class) {
        return (T) Integer.valueOf(str);
    }
    throw new IllegalArgumentException();
}
Evgeniy Dorofeev
  • 133,369
  • 30
  • 199
  • 275
1

You can return Number:

private static Number parseStringFormatNumber(String val){
    try {
        return Integer.valueOf(val.substring(0, val.indexOf(".")));
    } catch (NumberFormatException e) {
        try {
            return Float.valueOf(val.substring(0, val.indexOf(".")));
        } catch (NumberFormatException e2) {
            // handle invalid value (throw exception, return 0?)
        }
    }
}
Njol
  • 3,271
  • 17
  • 32
  • But this will give me an error: The constructor *ObjectName*(Project, String, String, String, Date, Date, String, String, String, String, boolean, boolean, String, Number, Number, Number) is undefined but I want *ObjectName*(Project, String, String, String, Date, Date, String, String, String, String, boolean, boolean, String, Float, Integer, Integer). – prog rice bowl Jan 28 '14 at 05:57
  • @progricebowl You'll have to modify that constructor to use a Number as well. – Njol Jan 28 '14 at 06:00
  • Hard to see how the NumberFormatException could ever arise. – user207421 Jan 28 '14 at 06:01
  • Nope, I don't intend to change to Number because it's a rule I have to follow - I have to use both Float and Integer respectively. – prog rice bowl Jan 28 '14 at 06:05
  • @EJP all number parsing methods throw NumberFormatExceptions if then cannot parse the string. – Njol Jan 28 '14 at 06:10
  • @progricebowl Then use this answer in conjunction with the other: Use instanceof to check what type was returned and cast the number to Float or Integer respectively. – Njol Jan 28 '14 at 06:11
  • I'm aware of what the exception is for. I don't see how a string stripped of everything from the decimal point onwards could fail Integer.parseInt() and pass Float.parseFloat(). – user207421 Jan 28 '14 at 06:16
  • @EJP The String could contain other characters than digits, it could be empty, or it could be too large for an int or float. – Njol Jan 28 '14 at 12:01
1

I wouldn't. I would have the method return 'float', with a small 'f', or more probably 'double'; I would have it parse the entire value without any substring operations; and I would cast the value to 'int' at the call sites that require it, and/or from there to Integer, Float, Double, ... whatever you need at the call site.

You will find this is orders of magnitude more efficient than the answer you've accepted, which is just a poor man's self-implemented runtime polymorphism where you previously had compile-time polymorphism.

But the problem itself is highly dubious. There are no ints and floats in an Excel file. There are only decimal numbers with zero or more decimal places.

user207421
  • 305,947
  • 44
  • 307
  • 483
  • returning float or int has a high risk of getting your Java returning a NullPointerException which is what I don't really want. The numbers will be saved into Objects with Integers/Floats. – prog rice bowl Jan 28 '14 at 06:51
  • 1
    Nonsense. Returning float, int, double etc. has a *zero* risk of a NullPointerException. It is returning Integer or Float that incurs that risk, at least in theory. I really wonder whether you understand what it is you're doing. – user207421 Jan 28 '14 at 07:07
  • Do you know Java? Returning Float/ Integer/ Double then has zero risk. That is why when people write a POJO, most coders will code private Integer x OR private Float x or private Double x rather than private int x/ private float x/ private double x. Ask around. – prog rice bowl Jan 28 '14 at 08:14
  • Clearly *you* don't know the difference between "'float' with a small 'f'", which is what I recommended here, and which *cannot be null,* and 'Float', which *can* be null. NB 'private' has nothing to do with it either way. Ask around yourself. You're not impressing anyone here. – user207421 Jan 28 '14 at 08:27
  • Yes I understand what you mean, but that is what I don't recommend myself to use it here because int/ float is throwing me nullpointerexception which I do not want on my program. This is what I am referring to: http://stackoverflow.com/questions/2254435/can-an-int-be-null-in-java?answertab=votes#tab-top – prog rice bowl Jan 28 '14 at 08:27
  • Your citation doesn't support what you've claimed here. – user207421 Jan 28 '14 at 08:28
  • 'int'/'float' cannot possibly throw NullPointerException. There are no pointers to be null. Primitive values cannot be null. Check your own citation. You're doing something else wrong. – user207421 Jan 28 '14 at 08:32
  • Nevertheless, I've decided to use Float/ Integer. – prog rice bowl Jan 28 '14 at 08:32
1

Alternatively, return a discriminated union such as Either<Integer, Float>. There is a stand-alone implementation of Either for Java 8 in a small library, "ambivalence": http://github.com/poetix/ambivalence

Either<Integer, Float> either1 = Either.ofLeft(23);
Either<Integer, Float> either2 = Either.ofRight(Float.valueOf("3.14"));
BigDecimal result1 = either1.join(BigDecimal::valueOf, BigDecimal::valueOf);
BigDecimal result2 = either2.join(BigDecimal::valueOf, BigDecimal::valueOf);

You can get it from Maven central:

<dependency>
    <groupId>com.codepoetics</groupId>
    <artifactId>ambivalence</artifactId>
    <version>0.2</version>
</dependency>
Dominic Fox
  • 1,039
  • 11
  • 8