Java 从列表推断类型的最佳方法是什么?
因此,我有一个包含双精度和整数的列表,我必须循环遍历该列表,并将每个数字随机+-25% 这是一个与我的代码类似的示例: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 =
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);
}
}
}