简体   繁体   中英

generic method to return object to Double or double

I would like to return 2 different types of class ( List<double[]> or List<Double[] ) from a single method , as in the below pseudo code. How to achieve this ?

EDITED code and comment : Eclipse does even not allow to compile as this is requested to change the return or data type. I understand YserieScaledCasted will have to be casted manually.

protected List<E[]> getYserieRescaledList(Class<E> c) {

    if (Double[].class == c)
        return this.YserieScaled;
    else if (double[].class == c)
        return this.YserieScaledCasted;

}

EDIT2: I found the correct to my problem is simply to overload the method as described here .

You realise you are returning a list of arrays, right? :-)

Short answer:

  • even though you are passing in Class<E> , you can't use the instanceof operator on a generic type so you can't carry out the if-statement sketched above

  • the following is ILLEGAL and doesn't compile at each of the two instanceof operators:

 class trash { protected <T> List<T[]> getYserieRescaledList(Class<T> cl) { List<T[]> result = null; if (cl instanceof Class<Double>) { result = ...; } else if (cl instanceof Class<double>) { result = ...; } return result; } } 
  • the reason for this is that generics are a compile-time only construct. All instantiated generic classes are converted to non-generic classes, with types inserted and type casting carried out etc. It makes no sense to ask whether a generic class is instantiated with a particular type at runtime - the generic classes have been swapped for non-generic classes

  • Instead, cut out the if-statements and simply use the instantiated type to declare variables & arrays, then use your algorithm to populate them and return the result:

 class treasure { protected <T> List<T[]> getYserieRescaledList(Class<T> cl) { List<T[]> result = null; // apply general algorithm here to populate the array // will work identically whether instantiated with Double or double return result; } } 

Longer Answer:

Generic classes should represent "template logic" of generalised processing that can be applied with various specific instantiated types.

Good examples are the java Collections, a persistence query framework (such as JPA Criteria API), a financial calculator for different types of investments, or even a SOA service template with standard service "container" infrastructure logic.

In your case, it might be simpler to use pseudo- method overloading (ie two methods with slightly different names):

protected List<Double[]> getYserieRescaledList() {
    return this.Y;
}

protected List<double[]> getYserieRescaledList2() {
    return this.YCasted;
}

Or even better, just stick to double[] as the only case. The compiler will transparently do autobox conversions from double to Double as needed when you extract values into other variables/method parameters.

Just use Double[].class and double[].class . Note that you can't cast a Double[] to a double[] and vice versa, you have to manually copy it. So by extension, you can't cast List<Double[]> to List<double[]> either. Edit: though upon a second glance, it appears this may be the limitation you're trying to correct.

There is some interesting stuff going on here. So your List<double[]> is an List<Array> object where the Array contains primitive double s.

I would venture to say generics is NOT the right solution here.

I think your best bet is to use the Google Lists library.

something like this:

protected List<Double[]> getYserieRescaledList() {
   return this.YseriesScaled;
}

Then, whatever calls your getYseriesRescaledList() can do something like this to get a List<double[]> :

Lists.transform(getYseriesRescaledList(), toPrimitiveDouble());

This will construct a List object in one line of code, using the Function below (from Google Guava):

private Function<Double[], double[]> toPrimitiveDouble(){
    return new Function<Double[], double[]>() {
        @Override
        public double[] apply( Double[] doubles) {
            double[] doubleArray = new double[doubles.length];

            int i = 0;
            for (Double doubleObject : doubles){
                doubleArray[i] = doubleObject.doubleValue();
                ++i;
            }

            return doubleArray;
        }
    };
}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM