从List <number>列表推断类型的最佳方法?</number>

时间:2014-08-06 16:49:44

标签: java list arraylist numbers

所以我有一个包含双打和整数的List<Number>,我必须遍历List并将每个数字随机化+ - 25%

这是一个类似于我的代码的例子:

public class ListTester {
    public static void main(String[] args){
        ListTester lt = new ListTester();        
    }   

    public ListTester(){
        int a = 1;
        int b = 2;
        double d = 3.5;
        randomizableStats = new ArrayList(Arrays.asList(a, b, d));        
        randomizeStats();
    }

    protected List <Number> randomizableStats;    

    protected void randomizeStats(){
        List<Number> randomizedStats = new ArrayList<>();

        Random r = new Random();
        for (Number n : randomizableStats){             
            int l = r.nextInt(1);
            int i = r.nextInt(25);
            if (l == 1){
                if (n instanceof Integer) {
                    Integer n2 = (Integer) n;
                    n2 = n2 + (i / 100 * n2) + 1;
                    randomizedStats.add(n2);
                } else if (n instanceof Double) {                    
                    Double n2 = (Double) n;
                    double d = (double) i;
                    n2 = n2 + (d / 100 * n2);
                    randomizedStats.add(n2);
                }
            } else {
                if (n instanceof Integer) {
                    Integer n2 = (Integer) n;
                    n2 = n2 - (i / 100 * n2) - 1;
                    randomizedStats.add(n2);
                } else if (n instanceof Double) {
                    Double n2 = (Double) n;
                    double d = (double) i;
                    n2 = n2 - (d / 100 * n2);
                    randomizedStats.add(n2);
                }
            }             
        }      
        for (Number n : randomizableStats){
            System.out.print(n);
        }
        for (Number n : randomizedStats){
            System.out.print(n);
        }
    }
}

问题是,有没有更好的方法来编写它,而不必强制转换为Integer \ Double使用其他if语句复杂化所有内容?

2 个答案:

答案 0 :(得分:1)

如果您不介意将所有内容转换为加倍,则可以使用Number.doubleValue()

for (Number n : randomizables) {
    int i = r.nextInt(1);
    int l = r.nextInt(24) + 1;

    if (i == 1) {
        double d = n.doubleValue();
        d = d + (d * l/100);

        // do something with d
    }
}

答案 1 :(得分:1)

好吧,作为一个设计练习,一个解决方案是避免使用 instaceof ,这通常是不鼓励的(我会评论后者),一种解决方案是使用多态。例如,您可以创建以下类:

public abstract class NewNumber {
    protected Number number;
    public abstract NewNumber multiply(int m);
    public Number toNumber() {
        return this.number;
    }
}

public class NewNumberInt extends NewNumber{
    public NewNumberInt(Integer number) {
        this.number = number;
    }
    @Override
    public NewNumber multiply(int m) {
        int out = this.number.intValue()*m;
        return new NewNumberInt(out);
    }
}

public class NewNumberDou extends NewNumber{
    public NewNumberDou(Double number) {
        this.number = number;
    }
    @Override
    public NewNumber multiply(int m) {
        double out = this.number.doubleValue()*m;
        return new NewNumberDou(out);
    }
}

这样,你的程序可以用以下方式重写

int a = 1;
int b = 2;
double d = 3.5;
List<NewNumber> randomizables = new ArrayList<NewNumber>();
randomizables.add(new NewNumberInt(a));
randomizables.add(new NewNumberInt(b));
randomizables.add(new NewNumberDou(d));

// Example on how to convert from NewNumber to Number 
List<Number> randomizablesNumber = new ArrayList<Number>();
for (NewNumber numNew:randomizables) randomizablesNumber.add(numNew.toNumber());

public void randomize(){
    Random r = new Random();
    for (NewNumber n : randomizables){
        int i = r.nextInt(1);
        int l = r.nextInt(24)+1;
        if (i == 1){
            NewNumber n2 = n.multiply(l/100);
        }
    }
}

问题在于,为了避免使用 instanceof 来编写所有这些内容是否值得。从设计的角度来看当然是这样,我个人更喜欢花2分钟但做得好,而不仅仅是节省这些时间并且有一些不好的东西。但是,据我所知,有时简单是最好的......