How can I write a method to make this code reuseable? - java

I have the following code where the Binding.createStringBinding(...) part is going to be repeated many many times, the only difference is the method used, i.e. getA(), getB() , getC()
this.attributeA.bind(Bindings.createStringBinding(() -> {
if(webService.getLastValue() != null){
return webService.getLastValue().getA();
} else{
return "";
}
}, webService.lastValueProperty()));
this.attributeB.bind(Bindings.createStringBinding(() -> {
if(webService.getLastValue() != null){
return webService.getLastValue().getB();
} else{
return "";
}
}, webService.lastValueProperty()));
New:
This is the part of the code that I want to make reusable:
Bindings.createStringBinding(() -> {
if(webService.getLastValue() != null){
return webService.getLastValue().getB();
} else{
return "";
}
}, webService.lastValueProperty())
How can I make this reusable? Perhaps making this a function ?

Maybe something like this:
private Binding createBinder(final Supplier<String> lambda) {
return Bindings.createStringBinding(() -> {
if(webService.getLastValue() != null){
return lambda.get();
} else{
return "";
}
}
}
called like
this.attributeA.bind(createBinder(() -> webService.getLastValue().getA()), webService.lastValueProperty());
this.attributeB.bind(createBinder(() -> webService.getLastValue().getB()), webService.lastValueProperty());

A slight variation on #Joshua's answer. Here ObjectTest is the type returned by webService.getLastValue().
private void makeBinding(StringProperty property, Function<ObjectTest, String> propertyAccessor) {
property.bind( Bindings.createStringBinding(() -> {
ObjectTest lastValue = webService.getLastValue();
if (lastValue == null) {
return "" ;
} else return propertyAccessor.apply(lastValue);
}, webService.lastValueProperty()) );
}
And now you do
makeBinding(attributeA, ObjectTest::getA);
makeBinding(attributeB, ObjectTest::getB);
etc

Let's suppose attributeA and attributeB both implement the Property<String> interface, and that methods getA, getB, etc. all return a String. With this in mind, you could do:
BiConsumer<Property<String>, Function<ObjectTest, String>> binder =
(property, getter) ->
property.bind(Bindings.createStringBinding(() -> {
if (webService.getLastValue() != null) {
return getter.apply(webService.getLastValue());
} else {
return "";
}
}, webService.lastValueProperty()));
This code creates a BiConsumer (which is a consumer that takes 2 arguments).
The first argument is an instance of Property<String> (as suggested by #James_D's comment) that is implemented by attributeA and attributeB.
The second argument is a Function<ObjectTest, String>, which is a function that takes an instance of ObjectTest and returns a String. Here I'm using it to represent a generic getter method over the ObjectTest class (more specifically, ObjectTest::getA and ObjectTest::getB).
If you want, you could rewrite the `BiConsumer' in a more java8 friendly way:
BiConsumer<Property<String>, Function<ObjectTest, String>> binder =
(property, getter) ->
property.bind(Bindings.createStringBinding(
() -> Optional.ofNullable(webService.getLastValue())
.map(getter).orElse(""),
webService.lastValueProperty()));
To use it:
binder.accept(this.attributeA, ObjectTest::getA);
binder.accept(this.attributeB, ObjectTest::getB);
The code above assumes that methods getA, getB, etc. return a String.
You might want to further read about Optional and BiConsumer in the javadocs.

Related

How to fix "unexpected return value" when using lambda?

When I want to use lambda to call a method in another Service.java and then use it as the condition to decide return value. It always said "unexpected return value" in lambda. How can I return it?
public SortOrder transform(SortOrder sort, String abc) {
if (sort == null) {
return SortOrder.A;
} else if (sort.equals(SortOrder.B) && abc != null) {
return AnotherService.getString(abc)
.map(l -> l.ifPresent(m -> {
if (m.getName().equals("name")) {
return SortOrder.C; //ERROR: unexpected return value
}
return sort; //ERROR: unexpected return value
}));
} else {
return sort;
}
return sort;
}
The function Optional.ifPresent accepts a consumer, which isn't allowed to return a value at all. The lambda passed to ifPresent must have void return type.
You're probably best off not using a lambda for that part, and instead writing if (l.isPresent()) { ... }.
If you insist on using the functional style, you could write l -> l.filter(m -> m.getName().equals("name")).map(l -> SortOrder.C).orElse(sort).

Use Java lambda instead of 'if else'

With Java 8, I have this code:
if(element.exist()){
// Do something
}
I want to convert to lambda style,
element.ifExist(el -> {
// Do something
});
with an ifExist method like this:
public void ifExist(Consumer<Element> consumer) {
if (exist()) {
consumer.accept(this);
}
}
But now I have else cases to call:
element.ifExist(el -> {
// Do something
}).ifNotExist(el -> {
// Do something
});
I can write a similar ifNotExist, and I want they are mutually exclusive (if the exist condition is true, there is no need to check ifNotExist, because sometimes, the exist() method takes so much workload to check), but I always have to check two times. How can I avoid that?
Maybe the "exist" word make someone misunderstand my idea. You can imagine that I also need some methods:
ifVisible()
ifEmpty()
ifHasAttribute()
Many people said that this is bad idea, but:
In Java 8 we can use lambda forEach instead of a traditional for loop. In programming for and if are two basic flow controls. If we can use lambda for a for loop, why is using lambda for if bad idea?
for (Element element : list) {
element.doSomething();
}
list.forEach(Element::doSomething);
In Java 8, there's Optional with ifPresent, similar to my idea of ifExist:
Optional<Elem> element = ...
element.ifPresent(el -> System.out.println("Present " + el);
And about code maintenance and readability, what do you think if I have the following code with many repeating simple if clauses?
if (e0.exist()) {
e0.actionA();
} else {
e0.actionB();
}
if (e1.exist()) {
e0.actionC();
}
if (e2.exist()) {
e2.actionD();
}
if (e3.exist()) {
e3.actionB();
}
Compare to:
e0.ifExist(Element::actionA).ifNotExist(Element::actionB);
e1.ifExist(Element::actionC);
e2.ifExist(Element::actionD);
e3.ifExist(Element::actionB);
Which is better? And, oops, do you notice that in the traditional if clause code, there's a mistake in:
if (e1.exist()) {
e0.actionC(); // Actually e1
}
I think if we use lambda, we can avoid this mistake!
As it almost but not really matches Optional, maybe you might reconsider the logic:
Java 8 has a limited expressiveness:
Optional<Elem> element = ...
element.ifPresent(el -> System.out.println("Present " + el);
System.out.println(element.orElse(DEFAULT_ELEM));
Here the map might restrict the view on the element:
element.map(el -> el.mySpecialView()).ifPresent(System.out::println);
Java 9:
element.ifPresentOrElse(el -> System.out.println("Present " + el,
() -> System.out.println("Not present"));
In general the two branches are asymmetric.
It's called a 'fluent interface'. Simply change the return type and return this; to allow you to chain the methods:
public MyClass ifExist(Consumer<Element> consumer) {
if (exist()) {
consumer.accept(this);
}
return this;
}
public MyClass ifNotExist(Consumer<Element> consumer) {
if (!exist()) {
consumer.accept(this);
}
return this;
}
You could get a bit fancier and return an intermediate type:
interface Else<T>
{
public void otherwise(Consumer<T> consumer); // 'else' is a keyword
}
class DefaultElse<T> implements Else<T>
{
private final T item;
DefaultElse(final T item) { this.item = item; }
public void otherwise(Consumer<T> consumer)
{
consumer.accept(item);
}
}
class NoopElse<T> implements Else<T>
{
public void otherwise(Consumer<T> consumer) { }
}
public Else<MyClass> ifExist(Consumer<Element> consumer) {
if (exist()) {
consumer.accept(this);
return new NoopElse<>();
}
return new DefaultElse<>(this);
}
Sample usage:
element.ifExist(el -> {
//do something
})
.otherwise(el -> {
//do something else
});
You can use a single method that takes two consumers:
public void ifExistOrElse(Consumer<Element> ifExist, Consumer<Element> orElse) {
if (exist()) {
ifExist.accept(this);
} else {
orElse.accept(this);
}
}
Then call it with:
element.ifExistOrElse(
el -> {
// Do something
},
el -> {
// Do something else
});
The problem
(1) You seem to mix up different aspects - control flow and domain logic.
element.ifExist(() -> { ... }).otherElementMethod();
^ ^
control flow method business logic method
(2) It is unclear how methods after a control flow method (like ifExist, ifNotExist) should behave. Should they be always executed or be called only under the condition (similar to ifExist)?
(3) The name ifExist implies a terminal operation, so there is nothing to return - void. A good example is void ifPresent(Consumer) from Optional.
The solution
I would write a fully separated class that would be independent of any concrete class and any specific condition.
The interface is simple, and consists of two contextless control flow methods - ifTrue and ifFalse.
There can be a few ways to create a Condition object. I wrote a static factory method for your instance (e.g. element) and condition (e.g. Element::exist).
public class Condition<E> {
private final Predicate<E> condition;
private final E operand;
private Boolean result;
private Condition(E operand, Predicate<E> condition) {
this.condition = condition;
this.operand = operand;
}
public static <E> Condition<E> of(E element, Predicate<E> condition) {
return new Condition<>(element, condition);
}
public Condition<E> ifTrue(Consumer<E> consumer) {
if (result == null)
result = condition.test(operand);
if (result)
consumer.accept(operand);
return this;
}
public Condition<E> ifFalse(Consumer<E> consumer) {
if (result == null)
result = condition.test(operand);
if (!result)
consumer.accept(operand);
return this;
}
public E getOperand() {
return operand;
}
}
Moreover, we can integrate Condition into Element:
class Element {
...
public Condition<Element> formCondition(Predicate<Element> condition) {
return Condition.of(this, condition);
}
}
The pattern I am promoting is:
work with an Element;
obtain a Condition;
control the flow by the Condition;
switch back to the Element;
continue working with the Element.
The result
Obtaining a Condition by Condition.of:
Element element = new Element();
Condition.of(element, Element::exist)
.ifTrue(e -> { ... })
.ifFalse(e -> { ... })
.getOperand()
.otherElementMethod();
Obtaining a Condition by Element#formCondition:
Element element = new Element();
element.formCondition(Element::exist)
.ifTrue(e -> { ... })
.ifFalse(e -> { ... })
.getOperand()
.otherElementMethod();
Update 1:
For other test methods, the idea remains the same.
Element element = new Element();
element.formCondition(Element::isVisible);
element.formCondition(Element::isEmpty);
element.formCondition(e -> e.hasAttribute(ATTRIBUTE));
Update 2:
It is a good reason to rethink the code design. Neither of 2 snippets is great.
Imagine you need actionC within e0.exist(). How would the method reference Element::actionA be changed?
It would be turned back into a lambda:
e0.ifExist(e -> { e.actionA(); e.actionC(); });
unless you wrap actionA and actionC in a single method (which sounds awful):
e0.ifExist(Element::actionAAndC);
The lambda now is even less 'readable' then the if was.
e0.ifExist(e -> {
e0.actionA();
e0.actionC();
});
But how much effort would we make to do that? And how much effort will we put into maintaining it all?
if(e0.exist()) {
e0.actionA();
e0.actionC();
}
If you are performing a simple check on an object and then executing some statements based on the condition then one approach would be to have a Map with a Predicate as key and desired expression as value
for example.
Map<Predicate<Integer>,Supplier<String>> ruleMap = new LinkedHashMap <Predicate<Integer>,Supplier<String>>(){{
put((i)-> i<10,()->"Less than 10!");
put((i)-> i<100,()->"Less than 100!");
put((i)-> i<1000,()->"Less than 1000!");
}};
We could later stream the following Map to get the value when the Predicate returns true which could replace all the if/else code
ruleMap.keySet()
.stream()
.filter((keyCondition)->keyCondition.test(numItems,version))
.findFirst()
.ifPresent((e)-> System.out.print(ruleMap.get(e).get()));
Since we are using findFirst() it is equivalent to if/else if /else if ......

Check if object is null after each method call

I have this simple fragment that I would like to reengineer in a more elegant way maybe with the latest JDK 8 features:
String x = methodCall();
if(x==null) {x=method2();}
if(x==null) {x=method3();}
if(x==null) {x=method4();}
// doing calculation with X
You can use Streams:
Optional<String> result= Stream.<Supplier<String>>of(this::method1, this::method2, this::method3)
.map(Supplier::get)
.filter(Objects::nonNull)
.findFirst();
System.out.println(result.isPresent());
The above code is equal to this (generated with Intellij Idea)
Optional<String> result = Optional.empty();
for (Supplier<String> stringSupplier : Arrays.<Supplier<String>>asList(this::method1, this::method2, this::method3)) {
String s = stringSupplier.get();
if (s != null) {
result = Optional.of(s);
break;
}
}
The question explicitly mentions Java 8, but also mentions the "latest features". As it isn't clear which the OP wants, this answer is with the latest features.
With Java 9 you can use the new Optional.or method to concisely implement this logic:
import static java.util.Optional.ofNullable;
...
String x = ofNullable(methodCall())
.or(() -> ofNullable(method2()))
.or(() -> ofNullable(method3()))
.or(() -> ofNullable(method4()))
.orElse(null);
Depending on what you are doing, you might want to omit the .orElse(null).
You can get rid of the if-block by using a designated method but besides that you won't get it more compact. Especially you will still need to check for null after each method.
Here is a method which uses Optional#ifPresent to apply a method if its not present:
public <V> void runIfNotPresent(V value, Runnable method) {
if (value == null) {
method.run();
}
}
Here's your code with using that method:
x = methodCall();
runIfNotPresent(x, this::method2);
runIfNotPresent(x, this::method3);
runIfNotPresent(x, this::method4);
// doing calculation with X
Note that you can't directly use Optional#isPresent (documentation) as its logic would be reversed. However that is also a very useful class and if you're using Java 9 then you might want to use Optional#or (documentation) as others already showed in their answers.
Alternatively you could write your own method to chain-apply methods
public <V> V applyAsLongAsNull(V value, Function<V, V>... methods) {
// Apply methods
for (Function<V, V> method : methods) {
if (value == null) {
value = method.apply(value);
} else {
// Stop as soon as value is not null
break;
}
}
return value;
}
You could then transform your methodX to a Function<V, V> which accepts a String value and returns a possibly different String value:
public String methodX(String value) {
// Do something with value
...
// Return value
return value;
}
Finally you would use it like:
String x = methodCall();
x = applyAsLongAsNull(x, this::method2, this::method3, this::method4);
// doing calculation with X

In Java, it is possible to take a line of code as a method argument?

I can't seem to find anything on google for this and I'm not sure it's possible. What I want to do, is pass a line of Java code as an argument to a method. Google only turns up results for passing cmd line arguments to methods, but I want to pass an actual line of code.
Basically I want to pass methodA to methodB except methodA isn't a method, but a line of code. Below is a full example of passing a method to a method using reflection.
public class Relation<T> {
protected Set<Pair<T,T>> pairs = null;
public Relation() {
this.pairs = new LinkedHashSet<Pair<T,T>>();
}
/* Next 2 methods are methods for sending methods to methods useing java.lang.reflect.Method */
public Method getMethod(String name) {
try { return Relation.class.getDeclaredMethod(name);
} catch (Exception e) {}
return null;
}
public boolean execute(Method method, Object... params) {
try { return (Boolean) method.invoke(this, params);
} catch (Exception e) {}
return false;
}
/* The method I reuse several times so I just put methods inside of it */
public boolean pairsTFIterator(Method method) {
for(Pair<T,T> x : pairs) {
boolean bool = false;
for(Pair<T,T> y : pairs) {
if(execute(method, x,y))
bool = true; break;
}
if(!bool) return false;
}
return true;
}
/* To be replaced by the line of code*/
public static <T> boolean isSymmetricPairs(Pair<T,T> a, Pair<T,T> b) {
return a.getFirst().equals(b.getSecond()) && a.getSecond().equals(b.getFirst()) ? true :false;
}
/* Method that calls others */
public boolean isSymmetric() {
return pairsTFIterator(getMethod("isSymmetricPairs"));
}
}
The above works fine and all, but I want to take it a step further and just forego methods like the "isSymmetricPairs" method by just putting that methods logic line directly in the "pairsTFIterator", like so:
public boolean isReflexive() {
return baseSetTFIterator(
a.getFirst().equals(b.getSecond()) && a.getSecond().equals(b.getFirst()) ? true :false
);
}
I'm pretty sure this is impossible, but if there is someway to do it, that would be great.
It sounds like what you are looking for are "first-class functions". Some languages treat functions just like a variable, in the sense that you can assign them to variables and pass them as arguments to other functions. Java 8 will be introducing the concept of lambda expressions which will support this type of functionality.
Also there are other JVM languages that provide this already, including Scala and Groovy to name two of the more popular ones.
Just to give you a flavor of what it looks like, in Groovy you can execute arbitrary functions on each element of a collection by calling the each() method and passing it a closure (a function essentially).
def list = [1, 2, 3, 4]
def printer = { x -> println x } // defines a closure that takes one arg and prints it
list.each(printer) // prints out the elements
def sum = 0
def summer = { x -> sum += x } // defines a closure that takes one arg and adds it to the sum variable
list.each(summer)
println sum // should be 1 + 2 + 3 + 4
Put you code in an anonymos inner class may satisfy your requirement:
interface PairFilter<T>{
boolean filter(Pair<T, T> a, Pair<T,T> b);
}
And in you iterator method:
public boolean pairsTFIterator(PairFilter filter) {
for(Pair<T,T> x : pairs) {
boolean bool = false;
for(Pair<T,T> y : pairs) {
if(filter.filter(x,y))
bool = true; break;
}
if(!bool) return false;
}
return true;
}
then call it:
pairsTFIterator(new PairFilter<T>(){
public boolean filter(Pair<T, T> a, Pair<T,T> b){
return a.getFirst().equals(b.getSecond()) && a.getSecond().equals(b.getFirst()) ? true :false;
}
});

Java: avoid checking for null in nested classes (Deep Null checking)

Imagine I have a class Family. It contains a List of Person. Each (class) Person contains a (class) Address. Each (class) Address contains a (class) PostalCode. Any "intermediate" class can be null.
So, is there a simple way to get to PostalCode without having to check for null in every step? i.e., is there a way to avoid the following daisy chaining code? I know there's not "native" Java solution, but was hoping if anyone knows of a library or something. (checked Commons & Guava and didn't see anything)
if(family != null) {
if(family.getPeople() != null) {
if(family.people.get(0) != null) {
if(people.get(0).getAddress() != null) {
if(people.get(0).getAddress().getPostalCode() != null) {
//FINALLY MADE IT TO DO SOMETHING!!!
}
}
}
}
}
No, can't change the structure. It's from a service I don't have control over.
No, I can't use Groovy and it's handy "Elvis" operator.
No, I'd prefer not to wait for Java 8 :D
I can't believe I'm the first dev ever to get sick 'n tired of writing code like this, but I haven't been able to find a solution.
You can use for:
product.getLatestVersion().getProductData().getTradeItem().getInformationProviderOfTradeItem().getGln();
optional equivalent:
Optional.ofNullable(product).map(
Product::getLatestVersion
).map(
ProductVersion::getProductData
).map(
ProductData::getTradeItem
).map(
TradeItemType::getInformationProviderOfTradeItem
).map(
PartyInRoleType::getGln
).orElse(null);
Your code behaves the same as
if(family != null &&
family.getPeople() != null &&
family.people.get(0) != null &&
family.people.get(0).getAddress() != null &&
family.people.get(0).getAddress().getPostalCode() != null) {
//My Code
}
Thanks to short circuiting evaluation, this is also safe, since the second condition will not be evaluated if the first is false, the 3rd won't be evaluated if the 2nd is false,.... and you will not get NPE because if it.
If, in case, you are using java8 then you may use;
resolve(() -> people.get(0).getAddress().getPostalCode());
.ifPresent(System.out::println);
:
public static <T> Optional<T> resolve(Supplier<T> resolver) {
try {
T result = resolver.get();
return Optional.ofNullable(result);
}
catch (NullPointerException e) {
return Optional.empty();
}
}
REF: avoid null checks
The closest you can get is to take advantage of the short-cut rules in conditionals:
if(family != null && family.getPeople() != null && family.people.get(0) != null && family.people.get(0).getAddress() != null && family.people.get(0).getAddress().getPostalCode() != null) {
//FINALLY MADE IT TO DO SOMETHING!!!
}
By the way, catching an exception instead of testing the condition in advance is a horrible idea.
I personally prefer something similar to:
nullSafeLogic(() -> family.people.get(0).getAddress().getPostalCode(), x -> doSomethingWithX(x))
public static <T, U> void nullSafeLogic(Supplier<T> supplier, Function<T,U> function) {
try {
function.apply(supplier.get());
} catch (NullPointerException n) {
return null;
}
}
or something like
nullSafeGetter(() -> family.people.get(0).getAddress().getPostalCode())
public static <T> T nullSafeGetter(Supplier<T> supplier) {
try {
return supplier.get();
} catch (NullPointerException n) {
return null;
}
}
Best part is the static methods are reusable with any function :)
You can get rid of all those null checks by utilizing the Java 8 Optional type.
The stream method - map() accepts a lambda expression of type Function and automatically wraps each function result into an Optional. That enables us to pipe multiple map operations in a row. Null checks are automatically handled under the neath.
Optional.of(new Outer())
.map(Outer::getNested)
.map(Nested::getInner)
.map(Inner::getFoo)
.ifPresent(System.out::println);
We also have another option to achieve the same behavior is by utilizing a supplier function to resolve the nested path:
public static <T> Optional<T> resolve(Supplier<T> resolver) {
try {
T result = resolver.get();
return Optional.ofNullable(result);
}
catch (NullPointerException e) {
return Optional.empty();
}
}
How to invoke new method? Look below:
Outer obj = new Outer();
obj.setNested(new Nested());
obj.getNested().setInner(new Inner());
resolve(() -> obj.getNested().getInner().getFoo())
.ifPresent(System.out::println);
Instead of using null, you could use some version of the "null object" design pattern. For example:
public class Family {
private final PersonList people;
public Family(PersonList people) {
this.people = people;
}
public PersonList getPeople() {
if (people == null) {
return PersonList.NULL;
}
return people;
}
public boolean isNull() {
return false;
}
public static Family NULL = new Family(PersonList.NULL) {
#Override
public boolean isNull() {
return true;
}
};
}
import java.util.ArrayList;
public class PersonList extends ArrayList<Person> {
#Override
public Person get(int index) {
Person person = null;
try {
person = super.get(index);
} catch (ArrayIndexOutOfBoundsException e) {
return Person.NULL;
}
if (person == null) {
return Person.NULL;
} else {
return person;
}
}
//... more List methods go here ...
public boolean isNull() {
return false;
}
public static PersonList NULL = new PersonList() {
#Override
public boolean isNull() {
return true;
}
};
}
public class Person {
private Address address;
public Person(Address address) {
this.address = address;
}
public Address getAddress() {
if (address == null) {
return Address.NULL;
}
return address;
}
public boolean isNull() {
return false;
}
public static Person NULL = new Person(Address.NULL) {
#Override
public boolean isNull() {
return true;
}
};
}
etc etc etc
Then your if statement can become:
if (!family.getPeople().get(0).getAddress().getPostalCode.isNull()) {...}
It's suboptimal since:
You're stuck making NULL objects for every class,
It's hard to make these objects generic, so you're stuck making a null-object version of each List, Map, etc that you want to use, and
There are potentially some funny issues with subclassing and which NULL to use.
But if you really hate your == nulls, this is a way out.
Although this post is almost five years old, I might have another solution to the age old question of how to handle NullPointerExceptions.
In a nutshell:
end: {
List<People> people = family.getPeople(); if(people == null || people.isEmpty()) break end;
People person = people.get(0); if(person == null) break end;
Address address = person.getAddress(); if(address == null) break end;
PostalCode postalCode = address.getPostalCode(); if(postalCode == null) break end;
System.out.println("Do stuff");
}
Since there is a lot of legacy code still in use, using Java 8 and Optional isn't always an option.
Whenever there are deeply nested classes involved (JAXB, SOAP, JSON, you name it...) and Law of Demeter isn't applied, you basically have to check everything and see if there are possible NPEs lurking around.
My proposed solution strives for readibility and shouldn't be used if there aren't at least 3 or more nested classes involved (when I say nested, I don't mean Nested classes in the formal context). Since code is read more than it is written, a quick glance to the left part of the code will make its meaning more clear than using deeply nested if-else statements.
If you need the else part, you can use this pattern:
boolean prematureEnd = true;
end: {
List<People> people = family.getPeople(); if(people == null || people.isEmpty()) break end;
People person = people.get(0); if(person == null) break end;
Address address = person.getAddress(); if(address == null) break end;
PostalCode postalCode = address.getPostalCode(); if(postalCode == null) break end;
System.out.println("Do stuff");
prematureEnd = false;
}
if(prematureEnd) {
System.out.println("The else part");
}
Certain IDEs will break this formatting, unless you instruct them not to (see this question).
Your conditionals must be inverted - you tell the code when it should break, not when it should continue.
One more thing - your code is still prone to breakage. You must use if(family.getPeople() != null && !family.getPeople().isEmpty()) as the first line in your code, otherwise an empty list will throw a NPE.
If you can use groovy for mapping it will clean up the syntax and codes looks cleaner. As Groovy co-exist with java you can leverage groovy for doing the mapping.
if(family != null) {
if(family.getPeople() != null) {
if(family.people.get(0) != null) {
if(people.get(0).getAddress() != null) {
if(people.get(0).getAddress().getPostalCode() != null) {
//FINALLY MADE IT TO DO SOMETHING!!!
}
}
}
}
}
instead you can do this
if(family?.people?[0]?.address?.postalCode) {
//do something
}
or if you need to map it to other object
somobject.zip = family?.people?[0]?.address?.postalCode
Not such a cool idea, but how about catching the exception:
try
{
PostalCode pc = people.get(0).getAddress().getPostalCode();
}
catch(NullPointerException ex)
{
System.out.println("Gotcha");
}
If it is rare you could ignore the null checks and rely on NullPointerException. "Rare" due to possible performance problem (depends, usually will fill in stack trace which can be expensive).
Other than that 1) a specific helper method that checks for null to clean up that code or 2) Make generic approach using reflection and a string like:
checkNonNull(family, "people[0].address.postalcode")
Implementation left as an exercise.
I was just looking for the same thing (my context: a bunch of automatically created JAXB classes, and somehow I have these long daisy-chains of .getFoo().getBar().... Invariably, once in a while one of the calls in the middle return null, causing NPE.
Something I started fiddling with a while back is based on reflection. I'm sure we can make this prettier and more efficient (caching the reflection, for one thing, and also defining "magic" methods such as ._all to automatically iterate on all the elements of a collection, if some method in the middle returns a collection). Not pretty, but perhaps somebody could tell us if there is already something better out there:
/**
* Using {#link java.lang.reflect.Method}, apply the given methods (in daisy-chain fashion)
* to the array of Objects x.
*
* <p>For example, imagine that you'd like to express:
*
* <pre><code>
* Fubar[] out = new Fubar[x.length];
* for (int i=0; {#code i<x.length}; i++) {
* out[i] = x[i].getFoo().getBar().getFubar();
* }
* </code></pre>
*
* Unfortunately, the correct code that checks for nulls at every level of the
* daisy-chain becomes a bit convoluted.
*
* <p>So instead, this method does it all (checks included) in one call:
* <pre><code>
* Fubar[] out = apply(new Fubar[0], x, "getFoo", "getBar", "getFubar");
* </code></pre>
*
* <p>The cost, of course, is that it uses Reflection, which is slower than
* direct calls to the methods.
* #param type the type of the expected result
* #param x the array of Objects
* #param methods the methods to apply
* #return
*/
#SuppressWarnings("unchecked")
public static <T> T[] apply(T[] type, Object[] x, String...methods) {
int n = x.length;
try {
for (String methodName : methods) {
Object[] out = new Object[n];
for (int i=0; i<n; i++) {
Object o = x[i];
if (o != null) {
Method method = o.getClass().getMethod(methodName);
Object sub = method.invoke(o);
out[i] = sub;
}
}
x = out;
}
T[] result = (T[])Array.newInstance(type.getClass().getComponentType(), n);
for (int i=0; i<n; i++) {
result[i] = (T)x[i];
}
return result;
} catch (NoSuchMethodException | IllegalAccessException | IllegalArgumentException | InvocationTargetException e) {
throw new RuntimeException(e);
}
}
and my favorite, the simple try/catch, to avoid nested null checks...
try {
if(order.getFulfillmentGroups().get(0).getAddress().getPostalCode() != null) {
// your code
}
} catch(NullPointerException|IndexOutOfBoundsException e) {}

Categories

Resources