创建通用Number子类的零值

时间:2010-08-23 02:24:26

标签: java generics

如何一般创建任意数字类型的零?

这是一个玩具示例:将空数转换为零的函数。

static <T extends Number> T zeroIfNull(T value) {
    return value == null ? 0 : value;
}

这不能编译,因为文字零是int类型,我需要将其转换为T类型。

是否可以这样做?

9 个答案:

答案 0 :(得分:3)

是否可以这样做?
并不是的。首先,当value为null时,方法如何知道返回哪个Number实现?

答案 1 :(得分:2)

Number类中甚至没有提到零。如果你必须这样做,我建议避免null s,或许是:

public static <T> T coalesce(T a, T b) {
    return a==null ? b : a;
}

您还可以创建一个通用接口来处理具有对您的代码有意义的功能的数字:

interface NumberOps<T extends Number> {
    T zeroIfNull(T value);
}

答案 2 :(得分:0)

尝试:

   return value == null ? (T)Integer.valueOf(0) : value;

答案 3 :(得分:0)

这是一个老问题,但在经过一段时间努力解决这个问题之后,我想出了一个可能引起别人兴趣的解决方案:

<form method="get" class="search-form" id="search-form" action="<?php echo esc_url( home_url( '/' ) ); ?>">
<input type="search" class="search-field" placeholder="<?php _e('Search form', 'fukasawa'); ?>" name="s" id="s" />
<a id="searchsubmit" class="search-button" onclick="document.getElementById('search-form').submit(); return false;"><div class="genericon genericon-search"></div></a>

只要涉及算术运算,您就可以将 Number 实例转换为某种已知类型,例如:

@SuppressWarnings("unchecked")
public static <T extends Number> T getZero() {
    return (T)((Integer)0);
}

在这种情况下,如果它是Number的一个实例,那么变量的类型无关紧要,总是可以获得一个变量。

答案 4 :(得分:0)

此方法需要一个类型类,因此您需要一个T对象实例来获取它,或者直接使用该类型类。

T castedValue = NumberCast.cast((Class<T>)someTObject.getClass(), 0d);

public class NumberCast
{
    public static <T extends Number> T cast(Class<T> typeClass, double value)
    {
        if (typeClass == Double.class)
            return typeClass.cast(value);
        else if (typeClass == Float.class)
            return typeClass.cast((float)value);
        else if (typeClass == Integer.class)
            return typeClass.cast((int)Math.round(value));
        else if (typeClass == Short.class)
            return typeClass.cast((short)Math.round(value));
        else if (typeClass == Long.class)
            return typeClass.cast(Math.round(value));

        return null;
    }
}

答案 5 :(得分:-1)

不是那么优雅,但我认为在大多数类似的情况下,这就是我们能做的:

static <T extends Number> T zeroIfNull(T value, Class<T> clazz) {...}

并在使用时:

BigDecimal v = zeroIfNull(orignalVal, BigDecimal.class);

答案 6 :(得分:-1)

您可以使用方法重载来实现这一点:

public static Double getValue(Double value) {
  return value != null ? value : 0;
}

public static Long getValue(Long value) {
  return value != null ? value : 0;
}

public static Integer getValue(Integer value) {
  return value != null ? value : 0;
}

答案 7 :(得分:-2)

import java . math . * ;

class Numbers
{
    public static < T extends Number > T zeroIfNull ( T number , Class<T> clazz ) throws IllegalArgumentException
    {
    if ( clazz == Integer . class )
        {
        return zeroIfNull ( number , clazz , 0 ) ;
        }
    else if ( clazz == Double . class )
        {
        return zeroIfNull ( number , clazz , 0 ) ;
        }
    else if ( clazz == BigInteger . class )
        {
        return zeroIfNull ( number , clazz , BigInteger . ZERO ) ;
        }
    // add a whole bunch more if statements
    throw new IllegalArgumentException ( "Unexpected Number Class " + clazz . getName ( ) + " with possibly undefined zero value." ) ;
    }

    private static < T extends Number > T zeroIfNull ( T number , Class<T> clazz , Object zero )
    {
    if ( number == null )
        {
        return ( clazz . cast ( zero ) ) ;
        }
    else
        {
        return ( number ) ;
        }
    }
}

答案 8 :(得分:-2)

以下是对我的第一个答案的改进。

import java . math . * ;
import java . util . * ;

class Numbers
{
    private static final Map<Class<? extends Number>,Object> zeroes = new HashMap<Class<? extends Number>,Object> ( ) ;

    static
    {
         zeroes . put ( Integer . class , new Integer ( 0 ) ) ;
         zeroes . put ( Double . class , new Double ( 0.0 ) ) ;
         zeroes . put ( BigInteger . class , BigInteger . ZERO ) ;
         // fill it up with all supported classes
    }

    public static < T extends Number > T zeroIfNull ( T number , Class<T> clazz ) throws IllegalArgumentException
    {
    if ( number == null ) // return zero (if we know what zero is)
        {
        if ( zeroes . containsKey ( clazz ) )
            {
            return ( clazz . cast ( zeroes . get ( clazz ) ) ) ;
            }
        throw new IllegalArgumentException ( "Unexpected Number Class " + clazz . getName ( ) + " with undefined zero value." ) ;
        }
    return number ;
    }
}