Java 从列表推断类型的最佳方法是什么?

Java 从列表推断类型的最佳方法是什么?,java,list,arraylist,numbers,Java,List,Arraylist,Numbers,因此,我有一个包含双精度和整数的列表,我必须循环遍历该列表,并将每个数字随机+-25% 这是一个与我的代码类似的示例: public class ListTester { public static void main(String[] args){ ListTester lt = new ListTester(); } public ListTester(){ int a = 1; int b =

因此,我有一个包含双精度和整数的列表,我必须循环遍历该列表,并将每个数字随机+-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语句使一切变得复杂

如果您不介意将所有内容转换为双倍,您可以使用


好吧,作为一个设计练习,有一个解决方案可以避免使用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分钟,把一些事情做好,而不是只省下这些时间,做一些不好的事情。但是,我知道有时候简单是最好的…

你知道你没有改变列表的值,对吗?因为Integer和Double是不可变的。我希望您认识到,I/100*n2将使用Integer算术计算。是的,这就是我从脑海中编写代码而不是复制粘贴代码所得到的结果……当您在每个循环中使用的值不是对您迭代的集合的引用时。您的代码不会对列表进行任何更改。对于这种情况,最好使用BigDecimal而不是Integer和Double。此外,您需要为此创建一个新列表,或者改用数组。不幸的是,我需要按原样将它们放回列表中,因为它们被用作int和double,以在代码的其他部分中构建其他对象。在这种情况下,我仍然必须将双精度转换回整数。@AngeloAlvisi-您是否意识到,例如2+/-25%不能合理地表示为整数?很抱歉,但是您的应用程序的设计很复杂。糟糕。是的,我确实意识到代码中的缺陷,我写这篇文章就是为了这个问题。我只需要了解是否有一种方法可以让java而不是循环来推断n是整数还是双精度。这种方法的问题是我需要整数在列表中是整数,NewNumber不会剪切它。如果需要,请检查我答案中的版本。我添加了返回数字的方法tonNumber。然后,我举例说明如何将一个NewNumber列表转换为一个Number列表。希望通过根本不将字段传递给列表来解决此问题。我会让他们在施工时奇数倍增。
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);
        }
    }
}