2017-01-13 4 views
9

Можно ли преобразовать этот код в java 8 Необязательное однострочное выражение?Java Необязательно, если объект не равен null - возвращает результат метода, если null - возвращает значение по умолчанию

long lastPollTime; 
if (object != null) { 
    lastPollTime = object.getTime(); 
} else { 
    lastPollTime = 0; 
} 

т.е. если какой-то объект не является нулевым, нужно вызвать метод объекта и возвращает его результат, либо возвращать 0. Optional.ofNullable(). OrElse() не подходит, так как он возвращает объект одного типа, но мне нужен результат вызова метода или какого-либо значения по умолчанию.

+2

Вызов '.mapToLong' на ваш' Факультативный', а затем 'orElse' – Ferrybig

+3

Перефразировать Джейми Завински:« Некоторые люди, столкнувшись с проблемой, думают «Я знаю, я буду использовать <новую функцию языка>»; теперь у них есть две проблемы ». Использование чего-либо большего, чем условный оператор, чтобы сделать это в однострочном пространстве, просто делает ненужную работу. –

+1

Я бы согласился с Энди, если вам нужно сначала построить опцию, это действительно ничего не поможет. Если у вас есть/сохраните опцию по другим причинам, карта/orElse хороша. – eckes

ответ

16

Несколько форм:

long lastPollTime = Optional.ofNullable(object).map(o -> o.getTime()).orElse(0L); 

long lastPollTime = Optional.ofNullable(object).map(YouObjectClass::getTime).orElse(0L); 

long lastPollTime = Optional.ofNullable(object).isPresent() ? object.getTime() : 0; 

long lastPollTime = object != null ? object.getTime() : 0; 

Из них последний, который не использует Факультативно (! И поэтому строго не ответ на ваш вопрос) проще читать и имеет меньше времени выполнения накладных расходов, и поэтому должно быть предпочтительным.

Возможно, это даже проще, если вы полностью изменить параметры:

long lastPollTime = object == null ? 0 : object.getTime(); 

... хотя вы можете предпочесть иметь по умолчанию в прошлом - это вопрос личного вкуса.


Если вы действительно не можете использовать тройные операторы, и вы делаете это много, вы можете написать свой собственный метод полезности:

public <T,U> U mapWithFallback(T obj, Function<T,U> function, U fallback) { 
    if(obj == null) { 
     return fallback; 
    } else { 
     return function.apply(obj); 
    } 
} 

... вызываемым как:

long lastPollTime = mapWithFallback(object, o -> o.getTime(), 0); 

... или сделать полное издевательство ваших не-триад проверки с помощью:

public <T,U> U ifElse(Supplier<Boolean> a, Supplier<U> ifTrue, Supplier<U> ifFalse) { 
    if(a.get()) { 
      return ifTrue.get(); 
    } else { 
      return ifFalse.get(); 
    } 
} 

long lastPollTime = ifElse(() -> object == null,() -> object.getTime(),() -> 0); 

Это в еще лучшего вкуса, чтобы избежать пустых ссылок в целом, так что этот вид проверки не требуется - например, с помощью Null Object pattern.

+0

'имеет меньше накладных расходов во время работы, и поэтому должно быть предпочтительнее. Категорически не согласен. Вы не должны беспокоиться о том, чтобы сделать такое «сокращение накладных расходов», пока не определили его как проблему. Таким образом, так часто люди избегают этих структур по «причинам производительности», когда они буквально 0 измеряют влияние на производительность кода. Затем, когда приходит время, чтобы поддерживать код и добавлять новые функции, вместо удобных крючков для добавления новых функциональных возможностей вы остаетесь с дымящимися грудами тройной логики. – corsiKa

+0

@corsoKa, но вы опустили «проще читать» из своей цитаты. Преждевременная оптимизация плохая. Но слишком богатые конструкции просто ради этого тоже плохие. – slim

3

вы можете сделать, как показано ниже с Java 8

long lastPollTime=Optional.ofNullable(object).isPresent()?object.getTime():0; 

или без использования java8 как этот

long lastPollTime = object != null ?object.getTime():0; 
+0

'obj.isPresent()' означает? – Null

+1

java 8 имеет boolean isPresent() метод, который Возвращает true, если присутствует значение, в противном случае значение false. –

+1

@JekinKalariya в исходном вопросе 'object' не является' Optional' - это переменная некоторого типа, которая имеет метод getTime(). Следовательно, все остальные ответы используются с опцией 'Необязательный.NNullable (object)'. Ваш ответ не будет компилироваться. – slim

4
long lastPollTime = object != null ?object.getTime():0; 
+0

Да, это очевидное решение, но в этом случае нужен вариант «вариант java option». – mv200580

+0

@ mv200580, и мой ответ был не 'java optional way'?! – Null

+2

Я не вижу никаких опций в этом выражении :) Я понимаю, что это самый короткий и вероятный самый эффективный способ, но в моем случае это неприемлемо, к сожалению – mv200580

4
long lastPollTime = Optional.ofNullable(object).map(o -> o.getTime()).orElse(0L); 

Вместо o -> o.getTime() вы можете использовать методы ссылки как ClassOfObject::getTime

+0

Есть метод mapToLong в java.util.Optional? Ничего об этом здесь. Https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html –

+0

Да, ваше право. Скорректированный мой ответ –

6
long lastPollTime = Optional.ofNullable(object).map(YouObjectClass::getTime).orElse(0L); 
+0

Удивительный, спасибо! – mv200580

Смежные вопросы