Imagine I have, say, XML-generated entity in Java that holds some data I need.
For example:
<Car>
<Engine>
<Power>
175
</Power>
</Engine>
</Car>
So if I need an engine power, I, followed by the best practices of business software development, will do the next thing:
Car car = dao.getCar()
Power power = car != null && car.engine != null ? power : null
return power
I hate this. Sometimes it seems that half of the code is just null checks.
Any ideas?
Take a look at Java 8 Optional class.
It does exactly that: it avoids the ugly checks on null.
In your case, you could use this snippet of code to avoid them:
Car car = dao.getCar();
Optional<Car> optionalCar = Optional.ofNullable(car);
Optional<Power> optionalPower = getPowerIfPresent(optionalCar);
Power power = Optional.empty();
if(optionalPower.isPresent()) {
power = optionalPower.get();
}
after writing a function that returns the power of a given car:
public static Optional<Power> getPowerIfPresent(Optional<Car> car) {
return car
.flatMap(c -> c.getEngine())
.map(e -> e.getPower());
}
This is the same as using of Optional, but might be more readable:
public class NullSafe<T> {
private final T value;
public NullSafe(#Nullable T value) { this.value = value; }
public static <T> NullSafe<T> of(#Nullable T value) { return new NullSafe<>(value); }
public <R> NullSafe<R> get(Function<T,R> mapper) {
R newValue = (value != null) ? mapper.apply(value) : null;
return new NullSafe<>(newValue);
}
public T nullable() { return value; }
public T orDefault(T defaultValue) { return (value != null) ? value : defaultValue; }
}
And usage:
Power power = NullSafe.of(dao.getCar())
.get(Car::getEngine)
.get(Engine::getPower)
.nullable(); // .orDefault(Power.defaultPower());
An alternative can be static methods:
public static <R> R get(Supplier<R> supplier, R defaultValue) {
try { return supplier.get(); }
catch (NullPointerException ex) { return defaultValue; }
}
public static <R> R getNullable(Supplier<R> supplier) { return get(supplier, null); }
And usage:
Power power = NullSafe.get(() -> dao.getCar().getEngine().getPower(), Power.defaultPower());
Power powerOrNull = NullSafe.getNullable(() -> dao.getCar().getEngine().getPower());
My own approach kind of this now:
public class CarDataExtractor {
private final Car car;
private CarDataExtractor(Car car) {
this.car = car;
}
public static CarDataExtractor on(Car car) {
return new CarDataExtractor(car);
}
public EngineDataExtractor engine() {
return car != null && car.getEngine() != null
? EngineDataExtractor.on(car.getEngine())
: EngineDataExtractor.on(null);
}
public Car self() {
return car;
}
}
public class EngineDataExtractor {
private final Engine engine;
private EngineDataExtractor(Engine engine) {
this.engine = engine;
}
public static EngineDataExtractor on(Engine engine) {
return new EngineDataExtractor(engine);
}
public PowerDataExtractor engine() {
return engine != null && engine.getPower() != null
? PowerDataExtractor.on(engine.getPower())
: PowerDataExtractor.on(null);
}
public Engine self() {
return engine;
}
}
...
Power power = CarDataExtractor.on(dao.getCar()).engine().power().self()
It is because I am restricted to Java 6...
Or maybe create some util method:
static <T> Optional<T> tryGet(Supplier<T> getter) {
try {
return Optional.ofNullable(getter.get());
} catch(NullPointerException ignored) {
return Optional.empty();
}
}
Then you could use it like this:
System.out.println(tryGet(() -> car.engine.power).orElse(new Power()));
There is a library no-exception that does that, but you cannot specify it to only "silence" NPEs.
Exceptions.silence().get(() -> car.engine.power).orElse(new Power())
There is also another option, you could use, which might be helpful for you if you're using Spring.
If you're not using Spring you would need to add additional dependency to your project.
Using Spel you could do:
ExpressionParser parser = new SpelExpressionParser();
StandardEvaluationContext context = new StandardEvaluationContext(dao.getCar());
Power power = parser.parseExpression("engine?.power").getValue(context, Power.class);
In expression engine?.power safe navigation operator is being used. In case engine is null, then the whole expression will evaluate to null.
This solution will work on Java 6.
Related
//How can we handle the below code in functional way like collect all invalid sort params, prepare message with all them listed and finally throw InvalidSortParam exception.
DO you think the below query does it?
public Sort resolveArgument() {
Sort sort = sortHandlerMethodArgumentResolver.resolveArgument();
List<Sort.Order> orders = sort.stream().collect(Collectors.toList());
List<String> invalidSortList = orders.stream().map(Sort.Order::getProperty)
.filter(property -> !allowedSortParams.contains(property))
.collect(Collectors.toList());
if (orders.isEmpty()) {
sort = Sort.by(Sort.Direction.DESC, defaultSortParam);
} else {
if (orders.size() > sortMaxCount) {
throw new InvalidSortException(INVALID_SIZE_PARAMS);
} else {
if (!invalidSortList.isEmpty()) {
throw new InvalidSortException(invalidSortList.stream()
.collect(Collectors.joining(",")) + INVALID_SORT_PARAMS);
}
}
}
return sort;
}
First of all - you do not take advantage of the streaming functionality, you divided it into two separate steps - loading data, and when it is completed - transforming it. You could merge it into a single pipeline. Secondly - throwing exceptions is not a functional way. You should use some type to return a state e.g with some Try implementation.
final class Try<T> {
private final Exception e;
private final T t;
public Try(Exception e) {
this.e = e;
t = null;
}
public Try(T t) {
this.t = t;
e = null;
}
public Exception getE() {
return e;
}
public T getT() {
return t;
}
}
and the code itself could look something like
public Try<Sort> resolveArgument() {
int cnt = getCount();
return cnt == 0 ? Sort.by(Sort.Direction.DESC, defaultSortParam) : someErrorHandlingLogic(cnt);
}
private static void getCount() {
sort.stream().map(Sort.Order::getProperty)
.filter(property -> !allowedSortParams.contains(property))
.count();
}
If you're interested in the Functional Programming paradigm in java - I recommend great presentation https://dev.tube/video/YnzisJh-ZNI
I'm looking for nice syntax for providing a default value in the case of null. I've been used to using Optional's instead of null in Java where API's are concerned, and was wondering if C#'s nicer nullable types have an equivalent?
Optionals
Optional<String> x = Optional<String>.absent();
String y = x.orElse("NeedToCheckforNull"); //y = NeedToCheckforNull
#nullable
String x = null;
String y = x == null ? "NeedToCheckforNull" : x ; //y = NeedToCheckforNull
How would I make the above more readable in C#?
JavaScript would allow y = x | "NeedToCheckforNull"
You can use the ?? operator.
Your code will be updated to:
string x = null;
string y = x ?? "NeedToCheckforNull";
See: ?? Operator (C# Reference)
C# has the special Nullable<T> type which can be declared with int?, decimal?, etc. These can provide a default value by using .GetValueOrDefault(), T GetValueOrDefault(T defaultValue), and the ?? operator.
string x = null;
Console.WriteLine(x ?? "NeedToCheckforNull");
.Net developers always try to compare C# feature to java. This is their big mistake. Microsoft always teach them like that. But they don't know how java capable of. Optional is not only nullable type. Nullable type is one of the its feature. But main purpose of Optional is single stream. You can use map(), flatMap() and filter() Lambda expression functions. There is no such alternative in .Net world unfortunately.
However there is lambda expression on List if you want to use as Optional.
But for single item, there is not such feature in .Net
I've created my own.
public class Optional<T> {
private T value;
public bool IsPresent { get; private set; } = false;
private Optional() { }
public static Optional<T> Empty() {
return new Optional<T>();
}
public static Optional<T> Of(T value) {
Optional<T> obj = new Optional<T>();
obj.Set(value);
return obj;
}
public void Set(T value) {
this.value = value;
IsPresent = true;
}
public T Get() {
return value;
}
}
consider using language extensions option type
int x = optional.IfNone("NeedToCheckforNull");
Thanks for the inspiration #sm-adnan
using System;
using System.Diagnostics.CodeAnalysis;
namespace Common;
public readonly struct Optional<T>
{
private readonly T _value;
private Optional(T value)
{
_value = value;
}
public static Optional<T> Empty() => new Optional<T>(default);
public static Optional<T> Of([AllowNull] T value)
{
return value is null ? Empty() : new Optional<T>(value);
}
public T GetValue()
{
if (HasValue()) return _value;
throw new InvalidOperationException("No value present");
}
public bool HasValue()
{
return _value is not null;
}
public void HasValue(Action<T> method)
{
if (HasValue()) method.Invoke(_value);
}
public void HasValue(Func<object> method)
{
if (HasValue()) method.Invoke();
}
public T OrElse(T other)
{
return HasValue() ? _value : other;
}
public T OrElseGet(Func<T> method)
{
return HasValue() ? _value : method.Invoke();
}
public T OrElseThrow(Func<Exception> method)
{
return HasValue() ? _value : throw method.Invoke();
}
public Optional<TU> Map<TU>(Func<T, TU> method)
{
return HasValue() ? new Optional<TU>(method.Invoke(_value)) : default;
}
}
Sometimes methods have the only difference somwhere in the middles of their bodies and it's difficult to generalize them or extract common part of code to a single method.
Question itself: How would you refactor the following implementations of interface methods to avoid duplicate code around for loop body?
interface MyInterface {
Integer myInterfaceMethod(String inputStr);
Integer myInterfaceOtherMethod(String inputStr)
}
class MyClass implements MyInterface {
public Integer myInterfaceMethod(String inputStr) {
#Override
try {
List<String> listDependingOnString = getListByString(inputStr);
Integer result = -1;
if (inputStr != null) {
result = 0;
for (String str : listDependingOnString) {
// Some different code, given just for example
result += str.length();
}
}
return result;
} catch (Exception e) {
exceptionProcessing(e);
return null;
}
}
#Override
public Integer myInterfaceOtherMethod(String inputStr) {
try {
List<String> listDependingOnString = getListByString(inputStr);
Integer result = -1;
if (inputStr != null) {
result = 0;
for (String str : listDependingOnString) {
// Some different code, given just for example
System.out.println(str);
++result;
}
}
return result;
} catch (Exception e) {
exceptionProcessing(e);
return null;
}
}
}
For this particular example, a lambda would work nicely:
private Integer computeStringFunction(String inputStr, BiFunction<Integer,String,Integer> accumulator) {
try {
List<String> listDependingOnString = getListByString(inputStr);
Integer result = -1;
if (inputStr != null) {
result = 0;
for (String str : listDependingOnString) {
result = accumulator.apply(result, str);
}
}
return result;
} catch (Exception e) {
exceptionProcessing(e);
return null;
}
public Integer myInterfaceMethod(String inputStr) {
return computeStringFunction(inputStr,
(Integer oldValue, String str) -> oldValue + str.length());
}
public Integer myInterfaceOtherMethod(String inputStr) {
return computeStringFunction(inputStr,
(Integer oldValue, String str) -> {
System.out.println(str);
return oldValue + 1;
});
}
"accumulator" here is a function that takes an integer and a string and returns another integer, and whose intent is to keep a "running total" of some sort.
BiFunction documentation
Note: not tested
The key to remove duplicate pattern in codes is to abstract the common part to one place and then find a way to pass the different part of "code pieces" as parameters to execute, for languages in which function is first class citizen(JavaScript, Python), you can always wrap the "code pieces" as functions. But it's not applicable for Java because method in Java is not a value, one way to resolve it is to define interfaces, and then pass the instance of a class which implements the interface as parameters, with lambda expression in Java 8 it can be more simpler.
Take the code in question as example, the common pattern is:
iterate the list and process each item
accumulate the result of each item and return
Then we can define two interfaces:
#FunctionalInterface
public interface ItemHandler<T, R> {
/**
* Takes input item of type T, then returns result of type R
*/
R handle(T t);
}
And another interface to accumulate the result:
#FunctionalInterface
public interface ItemResultAccumulator<T> {
T accumulate(T t1, T t2);
}
and then your code could be refactored as(I removed all exception handling and null checking code, to make the code less verbose to view):
public class MyClass implements MyInterface {
private static final ItemResultAccumulator<Integer> ADDER = (t1, t2) -> t1 + t2;
#Override
public Integer myInterfaceMethod(String inputStr) {
return processList(getListByString(inputStr), s -> s.length(), ADDER);
}
#Override
public Integer myInterfaceOtherMethod(String inputStr) {
return processList(getListByString(inputStr), s -> {
System.out.println(s);
return Integer.valueOf(1);
}, ADDER);
}
private Integer processList(List<String> list, ItemHandler<String, Integer> handler, ItemResultAccumulator<Integer> accumulator) {
Integer result = 0;
if (list != null && list.size() > 0) {
for (String item : list) {
result = accumulator.accumulate(result, handler.handle(item));
}
}
return result;
}
private List<String> getListByString(String inputStr) {
// Your logic to generate list by input
return Lists.newArrayList(inputStr.split(","));
}
}
This is a little of my thinking of this problem, hope this could be helpful:-)
I have this code in Modula-2,
PROCEDURE Prune(typeExp: TypeExp): TypeExp;
BEGIN
CASE typeExp.^class OF
| VarType:
IF typeExp^.instance = NIL THEN
RETURN typeExp;
ELSE
typeExp^.instance = Prune(typeExp^.instance);
RETURN typeExp^.instance;
END;
| OperType: RETURN typeExp;
END;
END Prune;
I have several problems when I try to convert this code into java. I can create an instance and judge if its instance is null and then choose what to return. But I don't really know what to do with the case 2, which is the instance might be a new Opentype(); because only one value can be returned in this case.
public TypeExp Prune(TypeExp typeExp){
TypeExp r = new VarType();
if (r.instance == null) {
return r;
}
else {
r.instance = Prune(r.instance);
return r.instance;
}
}
The second issue is I don't think I can call the function Prune() inside itself, so what can I do? Thanks in advance.
I dont really know Modula-2, but it might be something like this:
public TypeExp Prune(TypeExp typeExp) {
if (typeExp instanceof VarType) {
if (typeExp.instance == null) {
return typeExp;
}
else {
typeExp.instance = Prune(typeExp.instance);
return typeExp.instance;
}
} else if (typeExp instanceof OperType) {
return typeExp;
}
//if typeExp is not an instance of VarType or OperType
return null;
}
The Modula code does not return in all code paths. Thats not possible in Java. I inserted return null in those cases. Thats probably wrong for your application though.
Below example not same as your func, but I think you can modify to your needs. It hides your return types behind Type class => you can return objects of two classes.
Main
package com.type;
public class Main {
public static void main(String[] args) {
Type first = new FirstType();
Type second = new SecondType();
System.out.println(func(first).getTypeName());
System.out.println(func(first).getTypeName());
System.out.println(func(second).getTypeName());
}
public static Type func(Type type) {
if(type instanceof FirstType) {
type.setTypeName("First");
} else {
type.setTypeName("Second");
// something here
}
return type;
}
}
Type
package com.type;
public class Type {
private String typeName;
public Type() {}
public String getTypeName() {
return typeName;
}
public void setTypeName(String typeName) {
this.typeName = typeName;
}
}
FirstType
package com.type;
public class FirstType extends Type {
}
SecondType
package com.type;
public class SecondType extends Type {
}
In this Java class, note how use of the constructor has been disallowed and replaced with an interface driven builder that guides instantiation and does validation
public class Position implements Serializable {
private BigDecimal capital;
private BigDecimal tolerableRiskInPercentOfCapitalPerTrade;
private Direction direction;
private BigDecimal pricePerUnit;
private BigDecimal stopLossPricePerUnit;
private Position(){}
public final BigDecimal getTotalTolerableRiskPerTrade() {
return capital.multiply(tolerableRiskInPercentOfCapitalPerTrade.divide(new BigDecimal(100)));
}
public final BigDecimal getStopLossPerUnitLoss() {
if (direction.equals(Direction.LONG)){
return pricePerUnit.subtract(stopLossPricePerUnit);
} else {
return stopLossPricePerUnit.subtract(pricePerUnit);
}
}
public final BigDecimal getStopLossTotalLoss() {
return getStopLossPerUnitLoss().multiply(getUnitsToBuy());
}
public final BigDecimal getUnitsToBuy() {
BigDecimal result = getTotalTolerableRiskPerTrade().divide(getStopLossPerUnitLoss(), 0, BigDecimal.ROUND_DOWN);
if (capital.compareTo(result.multiply(pricePerUnit)) != 1){
return new BigDecimal(0);
} else {
return result;
}
}
public final BigDecimal getTotal() {
return getUnitsToBuy().multiply(pricePerUnit);
}
public static ICapital builder(){
return new Builder();
}
public interface ICapital {
ITolerableRiskInPercentOfCapitalPerTrade capital(final BigDecimal capital);
}
public interface ITolerableRiskInPercentOfCapitalPerTrade {
IDirection tolerableRiskInPercentOfCapitalPerTrade(final BigDecimal tolerableRiskInPercentOfCapitalPerTrade);
}
public interface IDirection {
IPricePerUnit direction(final Direction direction);
}
public interface IPricePerUnit {
IStopLossPricePerUnit pricePerUnit(final BigDecimal pricePerUnit);
}
public interface IStopLossPricePerUnit {
IBuild stopLossPricePerUnit(final BigDecimal stopLossPricePerUnit);
}
public interface IBuild {
Position build();
}
private static class Builder implements ICapital, ITolerableRiskInPercentOfCapitalPerTrade, IDirection, IPricePerUnit, IStopLossPricePerUnit, IBuild {
private final Position instance = new Position();
#Override
public Position build() {
return instance;
}
#Override
public ITolerableRiskInPercentOfCapitalPerTrade capital(final BigDecimal capital) {
basicValidate(capital);
instance.capital = capital;
return this;
}
#Override
public IDirection tolerableRiskInPercentOfCapitalPerTrade(final BigDecimal tolerableRiskInPercentOfCapitalPerTrade) {
basicValidate(tolerableRiskInPercentOfCapitalPerTrade);
if (tolerableRiskInPercentOfCapitalPerTrade.compareTo(new BigDecimal(100)) != -1) {
throw new IllegalArgumentException("riskInPercent must be lower than 100");
}
instance.tolerableRiskInPercentOfCapitalPerTrade = tolerableRiskInPercentOfCapitalPerTrade;
return this;
}
#Override
public IPricePerUnit direction(final Direction direction) {
if (direction==null) {
throw new IllegalArgumentException("argument can't be null");
}
instance.direction = direction;
return this;
}
#Override
public IStopLossPricePerUnit pricePerUnit(final BigDecimal pricePerUnit) {
basicValidate(pricePerUnit);
instance.pricePerUnit = pricePerUnit;
return this;
}
#Override
public IBuild stopLossPricePerUnit(final BigDecimal stopLossPricePerUnit) {
basicValidate(stopLossPricePerUnit);
if (instance.direction.equals(Direction.LONG) && instance.pricePerUnit.compareTo(stopLossPricePerUnit) != 1) {
throw new IllegalArgumentException("price must be higher than stopLossPrice");
}
if (instance.direction.equals(Direction.SHORT) && stopLossPricePerUnit.compareTo(instance.pricePerUnit) != 1) {
throw new IllegalArgumentException("stopLossPrice must be higher than price");
}
instance.stopLossPricePerUnit = stopLossPricePerUnit;
return this;
}
}
protected static void basicValidate(final BigDecimal bigDecimal) {
if (bigDecimal == null) {
throw new IllegalArgumentException("argument can't be null");
}
if (!(bigDecimal.signum() > 0)) {
throw new IllegalArgumentException("argument must have positive signum");
}
}
}
resulting in instantiation like this
Position.builder()
.capital(new BigDecimal(10000))
.tolerableRiskInPercentOfCapitalPerTrade(new BigDecimal(2))
.direction(Direction.LONG)
.pricePerUnit(new BigDecimal(25))
.stopLossPricePerUnit(new BigDecimal(24))
.build();
Trying to port code between languages isn't easy and identical functionality can't and shouldn't be expected. That said, are there any ways of emulating similar functionality in JavaScript? (vanilla or through some modules/libraries if necessary)
There are a few ways to do this.
One option is to do it almost exactly the same way: With a builder object that has methods to specify details and a build method (or similar) that you call to get the final object. The resulting call to build the object would look almost exactly the same (modulo type names and such).
Another option is to take advantage of JavaScript's object initializer syntax (aka "object literals") to have an "options" object that you pass into a constructor for the Position, like this:
function Position(options) {
if (/*...the options aren't valid...*/) {
throw new Error(/*...*/);
}
this.capital = options.capital;
// ...
}
Usage:
var p = new Position({
capital: 10000,
tolerableRiskInPercentOfCapitalPerTrade: 2,
direction: Direction.LONG,
pricePerUnit: 25,
stopLossPricePerUnit: 24
});
Inside the constructor, if you're going to use the data from options directly as properties on the new instance, you can use a function top copy them over:
function applyOptions(instance, options) {
Object.keys(options).forEach(function(key) {
instance[key] = options[key];
});
return instance;
}
Then:
function Position(options) {
if (/*...the options aren't valid...*/) {
throw new Error(/*...*/);
}
applyOptions(this, options);
}
(jQuery, if you use it, has an $.extend function that basically does this; Underscore, if you use it, has _.extend and _.extendOwn.)
But if you're going to be doing some manipulation of the options before storing them as properties on the new instance, a blind copy like that wouldn't be ideal.