11

在Java中可以使用什么语句来表示变量的缺失值。例如我想写一个代码:

if (a>=23)
 income = pay_rate;
else 
 income is missing;
4

11 回答 11

14

这个帖子里有很多不好的建议。首先让我谈谈为什么你应该采用一些建议的方法。

1.使用包装类型和null

Integer income = null;
if (a >= 23) {
  income = payRate; 
}

Java具有自动拆箱功能。如果您不小心income在 Java 必须自动拆箱的地方使用了它怎么办?编译器无法捕获此错误,您的代码将在运行时崩溃。

其次,收入的“可空性”不是income's 类型的一部分。因此,程序员null每次使用时都要小心检查它。如果他忘记执行这个检查,编译器不会抱怨,但你会NullPointerException在运行时得到 s。

2. 使用标记值表示异常情况

int income = Integer.MAX_VALUE;
if (a >= 23) {
  income = payRate;
}

这种方法具有方法的第二个缺点null。更糟糕的是,在这种情况下,即使在错误的条件下,计算也不会抛出异常,而是会继续Integer.MAX_VALUE进行,因为它是有效的int,可能会导致灾难性的结果。


那么你应该如何处理呢?

使用以下数据类型:

  • 具有在其类型中表示的“可空性”。
  • 不涉及上述两种方法中的条件检查。
  • 确保在编译时不会以非法状态访问数据。

Maybe(也称为Option)符合要求。(@Bahribayli 已经提出了这个建议。我正在对此进行扩展。)请参阅此处的数据定义。

这就是你在你的情况下使用它的方式:

Maybe<Integer> income = Nothing.value();
if (a >= 23) {
  income = Just.of(payRate);
}

有一个名为Functional Java的库提供了这种抽象。如果您对使用此数据类型有任何其他问题,我将很乐意为您解答。

于 2012-06-03T12:19:02.007 回答
6

您正在寻找一个,而不是一个声明,而那个值是null. 您不能将其分配给原始数据类型null的变量,例如and ,但您可以将它与它们的盒装对应物一起使用—— 、、等等。intdoubleIntegerDouble

当你这样做时,你应该null在访问它们之前仔细检查你的值。否则,看似无辜的人if (pay_rate > 100)可能会抛出空引用异常。

于 2012-05-30T04:54:24.563 回答
3

Option类型理论中的类型是一种指定变量类型的方法,该变量可能具有也可能没有有意义的值。一些语言支持Option像 Scala 的类型这样的scala.Option类型。对于不支持该类型的语言,您可以使用包装类或原语的盒装对应物。

public class Income {
  private int value;
  public Income(int value) {
    this.value = value;
  }
  public int getValue() {
     return value;
  }
  public void setValue(int value) {
    this.value = value;
  }
}

...
Income income = null;
if( a >= 23)
  income = new Income(pay_rate);

或者干脆

Integer income = null;
if( a >= 23)
  income = pay_rate;
于 2012-05-30T05:04:39.610 回答
2
Integer income = null;
if (a >= 23) {
  income = payRate; // underscores are generally considered bad convention in Java
}
于 2012-05-30T04:54:13.937 回答
2

您可以将收入设置为空。稍后,当您检查收入值时,如果它为空,则将其视为缺失

Integer income = a>=53?pay_rate:null;
于 2012-05-30T04:54:14.387 回答
2
Double income = null;
if (a>=23) {income = pay_rate; }

收入将null默认为所以如果未初始化

于 2012-05-30T04:54:40.603 回答
2

正如此处其他答案所述,您可以使用盒装类型。但我会建议为您的数据查找有效值并选择任何无效值作为缺失值。在您的特定收入情况下,它不能为负数,因此您可以选择-1。

避免盒装类型的原因是性能。我不反对使用它们,但如果你可以在没有它们的情况下工作,那么就没有必要使用它们。

对于大多数 +ve 和 -ve 值都是有效值的情况,请使用Integer.MAX_VALUEInteger.MIN_VALUE作为您的缺失值。您只会丢失所有可用值范围中的一个值。

注意:自动装箱(从原始类型隐式转换为装箱类型,反之亦然)是一个很好的功能,但会导致一些难以调试和发现的性能问题。

于 2012-05-30T05:14:03.490 回答
2

使用抛出

if (a>=23)
    income = pay_rate;
else 
    throw new IllegalArgumentException("income is missing");
于 2012-05-30T05:19:58.517 回答
0

你需要初始化变量null

Double income = null;
if (a>=23) 
{
   income = pay_rate; 
}
于 2012-05-30T12:00:47.020 回答
0

你也可以试试这个,也许只是我喜欢的方式,但取决于你:p

if(a >= 23){
    income = payRate;
} else{
    income = null;
}

与其将其设置为null默认值,不如null在它检查是什么之后将其设置a为。另外,确保收入是IntegerDouble

于 2012-05-30T05:06:18.687 回答
0

您可以通过以下方式进行操作:

public abstract class Nullable extends Number {

    protected final boolean isNA;


    protected Nullable(boolean isNA) {
        this.isNA = isNA;
    }

    public boolean isNA() {
        return isNA;
    }
}


public final class NullableInt extends Nullable {

    public static final NullableInt NA = new NullableInt(0, true);

    private final int value;

    public NullableInt(int value, boolean isNA) {
        super(isNA);
        this.value = value;
    }

    public static NullableInt of(int value) {
        return new NullableInt(value, false);
    }

    public int getValue() {
        if (!isNA) {
            return value;
        }
        throw new RuntimeException("Value is NA");
    }

    @Override
    public int intValue() {
        return getValue();
    }

    @Override
    public long longValue() {
        return getValue();
    }

    @Override
    public float floatValue() {
        return getValue();
    }

    @Override
    public double doubleValue() {
        return getValue();
    }
}

public class Test {

    public static void main(String[] args) {
        NullableInt[] nullableInts = new NullableInt[3];
        nullableInts[0] = NullableInt.of(1);
        nullableInts[1] = NullableInt.of(2);
        nullableInts[2] = NullableInt.NA;

        System.out.println(Arrays.toString(nullableInts));
    }
}
于 2017-02-21T09:56:45.667 回答