Вопрос по java – Недостающее значение в Java

10

Какое утверждение можно использовать в Java для представления отсутствующего значения переменной. например, я хочу написать код:

if (a>=23)
 income = pay_rate;
else 
 income is missing;
@ Андрей: с автоматической коробкой Java 5 это действительно не более удобно, чем использование объектов-оболочек. Jonathan W
@JonathanW Хороший вопрос об автобоксе. Andrew Thompson
Иногда -1 используется для обозначения пропавшегоint это не может быть логически отрицательным. Andrew Thompson
На первый взгляд, этот вопрос выглядит немного глупо: это действительно классическая проблема, которую большинство из нас решает так или иначе, большую часть времени с решениями, которые абсолютно не идеальны. Думая об этом с большим вниманием, мы видим, что ответ совсем не тривиален, и что существует элегантное решение. И у нас есть хорошее объяснение с ответом @missingfaktor. Не заслуживает никакого даунвота, так что ... Agemen
Могут ли избиратели выразить свои причины? IMWTK. Andrew Thompson

Ваш Ответ

11   ответов
0

null

Double income = null;
if (a>=23) 
{
   income = pay_rate; 
}
2
Double income = null;
if (a>=23) {income = pay_rate; }

null по умолчанию, так что если неинициализирован

Это плохой совет. Смотри мой ответ.
2

вы можете использовать коробочный тип. Но я рекомендую поискать допустимые значения для ваших данных и выбрать недопустимые значения для пропущенных. В вашем конкретном случае доход, который не может быть отрицательным, поэтому вы можете выбрать -1.

Причиной, по которой следует избегать упакованного типа, является производительность. Я не против их использования, но если вы можете работать без них, то нет необходимости их использовать.

Для случаев, когда большинство значений + ve и -ve являются допустимыми значениями, используйте либоInteger.MAX_VALUE или жеInteger.MIN_VALUE как ваше недостающее значение. Вы просто потеряете одно значение из всего доступного диапазона значений.

ПРИМЕЧАНИЕ. Автобокс (неявное преобразование из примитива в штучный тип и наоборот) является хорошей функцией, но может привести к некоторым проблемам с производительностью, которые трудно отладить и найти.

@ SOS Я не могу понять, что ты хочешь, с кодом, который ты вставил в комментарий. Если это имеет отношение к Вопросу, то отредактируйте свой вопрос.
@ SOS вы не можете сравнитьdouble тип данных сnull, Сравнивать сnull Вы должны использовать коробочный типDouble.
Если вы не выполняете чрезвычайно интенсивные вычисления, производительность автобокса почти наверняка будет незначительной. Если значение может необязательно присутствовать, вы должны использовать значение NULL, когда оно отсутствует. Это намного понятнее, чем использование -1 в качестве опции. Сохраняйте примитивы для математики, счетчиков и т. Д.
когда я скомпилировал: if ((number_hrs_per_day & gt; 0) || (pay_rate = null) & amp; (days_per_week & lt; 0 & lt; 0 || days_per_week = null)), я получил ошибку mesg == & gt; ошибка: несопоставимые типы: double и & lt; null & gt; SOS
@JonathanW ты прав. Как я уже сказал, некоторые из проблем находятся на виду, какInteger count = new Integer(10); for(int i=0; i<count; i++);, Но их трудно найти, так как они очень хорошо сочетаются ... :). Также использование типа ящика увеличит создание небольших объектов, что приведет к вызовам GC. Так много этих маленьких вещей имеет значение. Но если я использую какой-то ORM, который уже дает мне данные в штучной упаковке, я буду рад их использовать.
2

бросает:

if (a>=23)
    income = pay_rate;
else 
    throw new IllegalArgumentException("income is missing");
Я согласен с вами, просто хочу показать другой способ сделать это :)
Исключения должны использоваться в реальных исключительных условиях.
@Balaswamyvaddeman: я сделал этот пример на основе моей идеи, что еслиif-else внутри в методе и метод, скажем,getIncome() имеет возвращаемое значениеint и пользователь хочет показать сообщение об ошибке, если условие входит вelse, Если возвращаемое значение методаvoid чем вы можете отобразить сообщение об ошибке, используяSystem.out.println("income is missing"); но если возвращаемое значениеint чем вы должны вернуть значение, поэтому для этого я выбрасываю исключение. Просто хочу думать нестандартно, поправьте меня, если я делаю неправильно :-)
Исключение следует из того факта, что доход являетсяint, Если недостающий доход не является исключительным, то не смоделируйте его какint, но какInteger, Пользовательский тип илиOptional<Integer> в зависимости от контекста.
За исключением того, что это звучит как отсутствие, является допустимым условием. Вы не должны использовать исключения для нормальных или ожидаемых потоков управления.
0

может быть, просто так, как мне нравится, но на ваше усмотрение: p

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

вместо того, чтобы установить егоnull по умолчанию вы устанавливаетеnull после того, как он проверяет, чтоa является. Кроме того, убедитесь, что доход являетсяInteger или жеDouble

2
Integer income = null;
if (a >= 23) {
  income = payRate; // underscores are generally considered bad convention in Java
}
Правильно. Вот для чего нужен нуль.
Но что вы подразумеваете под "отсутствующим"? Как & quot; отсутствует & quot; повлиять на последующие расчеты? Должен ли он вести себя как 0 или некоторые вычисления вообще не должны выполняться?
если он отсутствует, то будут выполнены другие вычисления. например, если number_hrs_per_day & gt; 0 и days_per_week & lt; 0 или пропущено, тоcome_hr = (// todo) SOS
Я хочу найти минимальный доходHr для всех наблюдений. Если минимальный доходHr & gt; = число, то должен быть пропущенcome_hr_min. SOS
3

Option Тип в теории типов - это способ указать тип переменной, которая может иметь или не иметь значащее значение. Поддержка некоторых языковOption типа как в Scalascala.Option тип. Для языков, которые не поддерживают тип, вы можете использовать классы-обертки или штучные аналоги для примитивов.

  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;
добавьте, как это сделать на Java, и ваш ответ выделяется + 1
+1. Я добавляю еще один ответ, который более подробно описывает эту технику.
2

когда вы проверяете значение дохода, если оно равно нулю, тогда относитесь к нему как к отсутствующему

Integer income = a>=53?pay_rate:null;
& Quot;? & Quot; является вопрос, заданный для условия, то есть "является & gt; = b?" если да, верните & quot; pay_rate & quot; иначе верните & quot; null & quot ;. Код после & quot;: & quot; выполняется, если условие ложно. код перед & quot;: & quot; выполняется, если указание истинно. Смотрите эту ссылку для более подробной информации -cafeaulait.org/course/week2/43.html
что такое "?" и & quot; & quot; значит? SOS
6

valueне дляstatementи это значениеnull, Вы не можете назначитьnull переменнымprimitive data types, такие какint а такжеdouble, но вы можете использовать его со своимиboxed аналоги -Integer, Doubleи так далее.

Когда вы делаете это, вы должны быть осторожны, чтобы проверить свои значения дляnull прежде чем получить к ним доступ. Иначе невинно выглядящийif (pay_rate > 100) может выдать исключение нулевой ссылки.

В java термин для «встроенных модулей» являетсяprimitives
@ Bohemian Спасибо за исправление! Было слишком поздно для моей головы, чтобы выдать правильное слово :)
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));
    }
}
14

почему вы должныnot идти за некоторые из предложенных подходов.

1. Using wrapper types and null

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

У Java есть автоматическая распаковка. Что делать, если вы где-то случайно используетеincome в месте, где Java должна была автоматически распаковать его? Компилятор не может поймать эту ошибку, и ваш код взорвется во время выполнения.

Во-вторых, «обнуляемость» доход не является частьюincomeтип. В результате, программист должен быть осторожен при проверкеnull каждый раз, когда он используется. Если он забудет выполнить эту проверку, компилятор не будет жаловаться, но вы получитеNullPointerExceptionS во время выполнения.

2. Using sentinel values to denote exceptional conditions

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

Этот подход имеет второй недостатокnull подход. Еще хуже, в этом случае, вместо выдачи исключения, вычисление будетcontinue даже в ошибочных условиях, так какInteger.MAX_VALUE является действительнымint, что приводит к возможным катастрофическим последствиям.

So how should you deal with this?

Используйте тип данных, который:

has "nullability" expressed in its type. does not involve conditional checks such as in above two approaches. ensures at compile time that the data is not being accessed in illegal state.

Maybe (также известен какOption) отвечает всем требованиям. (@Bahribayli уже предложил это. Я расширяю это.) См. Определение данныхВот.

И вот как вы бы использовали его в вашем случае:

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

Есть библиотека с именемФункциональная Java тотобеспечивает эту абстракцию, Если у вас есть какие-либо дополнительные вопросы относительно использования этого типа данных, я буду рад ответить на них.

@ Raze2dust, если вы не работаете в области с высокой производительностью, вам не о чем беспокоиться. Я в первую очередь разработчик Scala (также язык JVM), и тамMaybe случается, способ обработки & quot; опциональности & quot ;.
Получил новые знания от этого .. спасибо! Какое снижение производительности при использовании конструкции Maybe?
+1 Четкий анализ.
Рад узнать об этом
+1. Объяснение действительно ясное, и это заставляет разработчиков (таких как я) быть более строгими со своими кодами.

Похожие вопросы