I need specific data for a report, then I gettin all information from a parent object
Object1
It has many attributes, object attributes
Object11, Object12, Object13, attr1, attr2...
The attributes has many attributes too
Object111, Object131, Object132,..
by now I got 5 level data attributes.
When I send information to my report it says, Error: cause:null
object1.getIdObject11().getIdObject111().getDescription;
It trows error because Object111 is null
I tried using
object1.getIdObject11().getIdObject111().getDescription==null?'':object1.getIdObject11().getIdObject111().getDescription;
but it only verify if description is null, and throws the same error
Then I tried to verify Object
if(object1.getIdObject11().getIdObject111() == null) {
var = object1.getIdObject11().getIdObject111().getDescription;
} else {
var = "";
}
But when Object11 is null, it throws same error.
I don't think its a good way doing this for each attribute (have to get like 30 attributes)
if(object1.getIdObject11()!=null) {
if(object1.getIdObject11().getIdObject111()!=null) {
if(object1.getIdObject11().getIdObject111().getIdObject1111()!=null) {
//...
}
}
}
I want to verify if is there a null object and set '' (blank) if it is, with no such a large code(because the gotten params are set inside a report, mixed with letter).
reportline1 = "Area: "+object1.getIdObject11().getIdObject111().getName;
You code breaks Demeter's law. That's why it's better to refactor the design itself.
As a workaround, you can use Optional
var = Optional.ofNullable(object1)
.map(o -> o.getIdObject11())
.map(o -> o.getIdObject111())
.map(o -> o.getDescription())
.orElse("")
The way I would probably do this to extend the functionality of the code easily in the future might take a bit of writing in the beginning but will be easily usable forever.
I would create a new method in your parent class called hasNull that returns a boolean like so:
public boolean hasNull()
{
boolean hasANull = false;
//Call another hasNull() inside of object11 which in turns calls hasNull() in object111 etc.
//If any of the calls return with a true/null value set hasANull to true
return hasANull;
}
This in turn checks to see if the current objects it contains are null. If one of the class variables is another custom class you created you can then add another hasNull into that one and keep going until you get to the lowest level where you can do a specific operation when the value is null such as set it to "".
After implementing this you will be able to just be able to use it like this any time you need it:
if (!object1.hasNull())
{
//Do whatever you want if there are no null values
}
else
{
//Do whatever you want if there is a null value
}
You can also make this a void method if you only want it to toggle the values on the lowest level, and do not need to do anything in either case.
I prefer the solution that gave dehasi.
But you can also do something like that:
getOrElse(() -> object1.getIdObject11().getIdObject111().getDescription(), "")
Where getOrElse is:
public static <T> T getOrElse(Supplier<T> getter, T elseValue) {
try {
return getter.get();
} catch (Exception e) {
// log or do something with it
}
return elseValue;
}
It may be controversial becaouse you use Exception to do this.
You can use this code to check if your object has a null attribute, the object is myclass;
for (Field f : myclass.getClass().getDeclaredFields()) {
f.setAccessible(true);
try {
if (Objects.isNull(f.get(myclass))) {
isLineContainsNull = true;
}
} catch (Exception e) {
log.error(e.getMessage());
}
}
Related
I can't figure out how to factor out this code.
private CompletionStage<Response<String>> foo(RequestContext rc) {
final Optional<String> campaignIdOpt = rc.request().parameter("campaignId").filter(s -> !s.isEmpty());
final Optional<String> creativeIdOpt = rc.request().parameter("creativeId").filter(s -> !s.isEmpty());
Optional<Uuid> campaignIdOptOfUuid = Optional.empty();
if (campaignIdOpt.isPresent()) {
try {
campaignIdOptOfUuid = Optional.of(UuidUtils.fromString(campaignIdOpt.get()));
} catch (IllegalArgumentException e) {
LOG.error(String.format("Invalid campaignId: %s", campaignIdOpt.get()), e);
return CompletableFuture.completedFuture(
Response.forStatus(Status.BAD_REQUEST.withReasonPhrase("Invalid campaignId provided.")));
}
}
Optional<Uuid> creativeIdOptOfUuid = Optional.empty();
if (creativeIdOpt.isPresent()) {
try {
creativeIdOptOfUuid = Optional.of(UuidUtils.fromString(creativeIdOpt.get()));
} catch (IllegalArgumentException e) {
LOG.error(String.format("Invalid creativeId: %s", creativeIdOpt.get()), e);
return CompletableFuture.completedFuture(
Response.forStatus(Status.BAD_REQUEST.withReasonPhrase("Invalid creativeId provided.")));
}
}
// Simplified, do something with Uuids.
return bar(campaignIdOptOfUuid, creativeIdOptOfUuid);
}
Basically, we very frequently need to parse Google protobuf Uuids from a query string to pass on to another service that will find (or not find). We need to pass along an empty optional if a parameter was not set or an empty string, as both cases mean, "Don't filter by this parameter." Finally, if the string doesn't parse at all, then we want to immediately return an error 400 (Bad Request), rather than pass along a non-sense param to the service.
So, codewise, I want a utility method that
takes an Optional<String>, and
returns an Optional<Uuid> if present, Optional.empty() otherwise, and
if an exception is thrown, return an error from the original context.
But obviously, I can't "double-return." What pattern do I use to achieve this though? I tried to create an encapsulator for both an Optional<Uuid> and a CompletionStage<Response<String>> but it was awkward. Is there some idiomatic way of doing this?
You can use a loop. A loop allows you to handle all elements equally, thus removing the code duplication, while still allowing to return immediately:
private CompletionStage<Response<String>> foo(RequestContext rc) {
String[] parameters = {"campaignId", "creativeId" };
List<Optional<Uuid>> uuids = new ArrayList<>(parameters.length);
for(String param: parameters) {
Optional<String> o1 = rc.request().parameter(param).filter(s -> !s.isEmpty());
Optional<Uuid> o2;
try {
o2 = o1.map(UuidUtils::fromString);
} catch(IllegalArgumentException e) {
LOG.error(String.format("Invalid %s: %s", param, o1.get()), e);
return CompletableFuture.completedFuture(
Response.forStatus(Status.BAD_REQUEST
.withReasonPhrase("Invalid "+param+ " provided.")));
}
uuids.add(o2);
}
// Simplified, do something with Uuids.
return bar(uuids.get(0), uuids.get(1));
}
Otherwise, you would need to create a method returning an object holding two alternative results (like Either); the JDK does not provide such a type yet. A method could simply throw on an erroneous condition but that would bring you back to square one when the common code is mostly the exception handling.
Note that calling Optional.map on an empty optional will already return an empty optional, without evaluating the provided function, so you don’t need to check via ifPresent, etc.
I'm developing a project in which i have a method to know if a JTextField is empty or not, but i was wondering if a way to implement that method just once and send several JTextFields components to check if they are empty or not exists, if so, could you please tell me how?, here's my sample code.
public static void Vacio(JTextField txt){
if(txt.getText().trim().equals(null)==true){/*Message*/}
}
Also i would like to know if i could improve the method using some Lambda Expressions, beforehand.
Use :
if(txt.getText().trim().length()==0)
//Do something
Your code will not work because a blank string("") is not a null String. I simply check if the trimmed length() of TextField is 0.
A sample function:
public boolean isEmpty(JTextField jtf)
{
try{
jtf.getText();
}catch(NullPointerException e){return true;}
if(jtf.getText().trim().length() == 0)
return true;
return false;
}
I cannot imagine how adding Lambda expressions can improve what you're trying to do (?).
Anyway, to check for an empty String I'd probably use:
field.getText().trim().isEmpty()
You don't need to check for null but you do need to catch NullPointerException in the event that the underlying document in the JTextField is null.
For the other part of your quesiton, if you really want to check multiple JTextFields in one method you could pass them as a variable length argument list:
public static void vacio(JTextField... fields) {
for(JTextField field : fields) {
try {
if( field.getText().trim().isEmpty() ) {
// do something
}
}
catch(NullPointerException ex) {
// handle exception (maybe log it?)
}
}
}
and call it like:
vacio(field1, field2, field3);
But, generally speaking, keeping functions brief and only doing one thing is usually better than trying to make a function do too much.
One final aside, your method is named Vacio but java naming conventions suggest you should compose method names using mixed case letters, beginning with a lower case letter and starting each subsequent word with an upper case letter.
Check explicitly for null and then compare with "".
public static void Vacio(JTextField txt){
String str = null;
try {
str = txt.getText();
}
catch (NullPointerException npe) {
System.out.println("The document is null!");
return;
}
if(str.trim().equals("")==true){/*Message*/}
}
In code we have got a lot of chain methods, for example obj.getA().getB().getC().getD(). I want to create helper class which will check if method getD() isn't null, but before that I need to check all previous getters. I can do it in this way:
try {
obj.getA().getB().getC().getD();
}
catch (NullPointerException e) {
// some getter is null
}
or (which is "silly")
if (obj!null && obj.getA()!=null && obj.getA().getB()!=null && ...) {
obj.getA().getB().getC().getD();
}
else {
// some getter is null
}
I don't want to check it every time using try{} catch() in my code. What is the best solution for this purpose?
I think that the best will be:
obj.getA().getB().getC().getD().isNull() - for this purpose I will need to change all of my getters, for example implement some interface which contains isNull() method.
NullObjectHelper.isNull(obj.getA().getB().getC().getD()); - this will be the best (I think so) but how to implement this?
As of Java 8 you can use methods like Optional.isPresent and Optional.orElse to handle null in getter chains:
boolean dNotNull = Optional.ofNullable(obj)
.map(Obj::getA)
.map(A::getB)
.map(B::getC)
.map(C::getD)
.isPresent();
While this is preferable to catching NullPointerException the downside of this approach is the object allocations for Optional instances.
It is possible to write your own static methods that perform similar operations without this overhead:
boolean dNotNull = Nulls.isNotNull(obj, Obj::getA, A::getB, B::getC, C::getD);
For a sample implementation, see the Nullifier type here.
No approach is likely to have greater runtime efficiency than nested if-not-null checks.
You can achieve the desired result with Option pattern. This enforces you to change a method signature, but basically if your method returns some type T, it guarantees it has some non-null value, and if it returnsOption<T> it means it either has value T, or null.
Java 7 had some feature called null safety, but it was removed from the final release. You could do:
obj?.getA()?.getB()?.getC()?.getD()
Moreover, Java 8 will add a feature called Optional so you would do it safely.
In fact, if you really want to use that now, try Null Object pattern. It means that instead of returning plain null you can return some sort of default value, which won't trigger NullPointerException. Though, you need add some changes to your getters
class Object {
A getA() {
// ...
return a == null ? A.NULL : a;
}
}
class A {
static A NULL = new A(); // some default behaviour
B getB() {
if (this == NULL) return B.NULL;
// ...
return b == null ? B.NULL : b;
}
}
EDIT: If you want utility to do it you can wrap it in some functional interface and then call it.
static boolean isNullResult(Callable call) throws Exception {
try {
return call.call() == null;
} catch (NullPointerException npe) {
return true;
}
}
Usage will be the following:
isNullResult(new Callable<Integer>() {
#Override
public Integer call() throws Exception {
return new A().getB().getC().getInt();
}
});
It won't require you to change existing functionality
As already stated, the true solution is refactoring.
In the meantime, you could just wrap your first workaround in a function:
static D getD(MyClass obj) {
try {
return obj.getA().getB().getC().getD();
}
catch (NullPointerException e) {
return null; // Or even better, some default D
}
}
At the caller site:
D d = getD(obj);
At least you don't have to trash the caller with try-catch blocks. You still need to handle the errors somehow, when some of the intermediate getX() call returns a null and so d becomes null. The best would be to return some default D in the wrapper function.
I don't see how the two options you list at the end of your question would help if any of the intermediate getX() returns a null; you will get a NullPointerException.
The structure that I have is:
Map<String, ArrayList<Bean>>
This Arraylist is modified (added/removed) from different locations within different threads.
At times, some bean inside the ArrayList is becoming null. How can I track when it becomes null? I want to track what makes the bean null, to fix the bug.
This happens when the scenario is tested with a huge data set.
Here's the exact code that's failing:
for (int i = 0; i < eventlogs.size(); i++) {
MessageEventLogBean msgEventLogBean = (MessageEventLogBean) eventlogs.get(i);
eventlogs.remove(i);
try {
logWriter.write(msgEventLogBean, context);
} catch (FusionException e) {
logger.error("Error While writing the event log bean ", e);
}
}
Instead of a standard list implementation, use an anonymous class that overrides the add method and adds special code to check if the added object is null, like this:
List<T> list = new ArrayList<T>() {
public boolean add(T e) {
if (e == null) {
throw new NullPointerException("Attempt to add null to list");
}
return super.add(e);
}
};
You should similarly override all "add" methods to be sure. When code adds a null, it will explode and you will see the exception in the log and be able to see who did it be examining the stacktrace.
EDITED
To be clear, it is impossible for an object in a List to "become null". You can add a null, or you can remove an object from the List, but an object already in the List will stay there until removed.
To be clear, the only way for a null to get in the list is by putting it there - ie adding it via one of the add() methods or the addAll() method. Concurrent modification issues can not cause this issue (you may get a ConcurrentModificationException, but that still won't put a null in there).
Code such as
Object o = list.get(1);
o = null;
has no effect because you're just nulling a copy of the reference to the object - list still a reference to the object.
However, depending on the design of the Bean objects, they might be mutable. While the reference to the Bean object would remain intact, it might be possible for some of the fields within the Bean to become null. To catch this, you would need to code the setters to explode when given a null argument, either by re-writing the class, or by overloading the setters via an anonymous class (similar to my initial suggestion above).
It's a bit of work, but you can create your own List interface implementation that delegates all methods to the ArrayList. In the accessor method where you would normally return the ArrayList, instead return your debug implementation with the ArrayList wrapped inside of it. Then just set a breakpoint on your set method, and you'll know exactly what code is calling set on the ArrayList.
Perhaps this is what you intended
private final Queue<MessageEventLogBean> eventlogs = new ConcurrentLinkedQueue<>();
// this loop stops when it runs out of objects.
MessageEventLogBean msgEventLogBean;
while ((msgEventLogBean = eventlogs.poll()) != null) {
try {
logWriter.write(msgEventLogBean, context);
} catch (FusionException e) {
logger.error("Error While writing the event log bean ", e);
}
}
or
// this loops until the thread is interrupted
private final BlockingQueue<MessageEventLogBean> eventlogs = new LinkedBlockingQueue<>();
while (true) {
MessageEventLogBean msgEventLogBean = eventlogs.take();
try {
logWriter.write(msgEventLogBean, context);
} catch (FusionException e) {
logger.error("Error While writing the event log bean ", e);
}
}
Both options are thread safe.
You can override the add() and set() methods for the list so that null is invalid and throws an exception.
List<MyType> list = new ArrayList<MyType>() {
public boolean add(MyType mt) {
if(mt == null) throw new IllegalArgumentException();
super.add(mt);
}
};
Consider the following code
String a = "hi"; // a => "hi"
String b = a; // a => "hi" and b => "hi"
a = null; // a => null and b => "hi"
String a is a reference to a String and when you assign null to it you change just the value of a and other references to the same object are unaffected.
A way to process every second entry, or why using remove(i) is unlikely to be what you want.
List<Integer> list = new ArrayList<>();
for(int i=0;i<10;i++) list.add(i);
for(int i=0;i<list.size();i++) {
System.out.println(list.get(i));
list.remove(i);
}
prints
0
2
4
6
8
I'm looking for a Google Collections method that returns the first result of a sequence of Suppliers that doesn't return null.
I was looking at using Iterables.find() but in my Predicate I would have to call my supplier to compare the result against null, and then have to call it again once the find method returned the supplier.
Given your comment to Calm Storm's answer (the desire not to call Supplier.get() twice), then what about:
private static final Function<Supplier<X>, X> SUPPLY = new Function<....>() {
public X apply(Supplier<X> in) {
// If you will never have a null Supplier, you can skip the test;
// otherwise, null Supplier will be treated same as one that returns null
// from get(), i.e. skipped
return (in == null) ? null : in.get();
}
}
then
Iterable<Supplier<X>> suppliers = ... wherever this comes from ...
Iterable<X> supplied = Iterables.transform(suppliers, SUPPLY);
X first = Iterables.find(supplied, Predicates.notNull());
note that the Iterable that comes out of Iterables.transform() is lazily-evaluated, therefore as Iterables.find() loops over it, you only evaluate as far as the first non-null-returning one, and that only once.
You asked for how to do this using Google Collections, but here's how you would do it without using Google Collections. Compare it to Cowan's answer (which is a good answer) -- which is easier to understand?
private static Thing findThing(List<Supplier<Thing>> thingSuppliers) {
for (Supplier<Thing> supplier : thingSuppliers) {
Thing thing = supplier.get();
if (thing != null) {
return thing;
}
}
// throw exception or return null
}
In place of the comment -- if this was the fault of the caller of your class, throw IllegalArgumentException or IllegalStateException as appropriate; if this shouldn't have ever happened, use AssertionError; if it's a normal occurrence your code that invokes this expects to have to check for, you might return null.
What is wrong with this?
List<Supplier> supplierList = //somehow get the list
Supplier s = Iterables.find(supplierList, new Predicate<Supplier>(){
boolean apply(Supplier supplier) {
return supplier.isSomeMethodCall() == null;
}
boolean equals(Object o) {
return false;
}
});
Are you trying to save some lines? The only optimisation I can think is to static import the find so you can get rid of "Iterables". Also the predicate is an anonymous inner class, if you need it in more than one place you can create a class and it would look as,
List<Supplier> supplierList = //somehow get the list
Supplier s = find(supplierList, new SupplierPredicateFinder());
Where SupplierPredicateFinder is another class.
UPDATE : In that case find is the wrong method. You actually need a custom function like this which can return two values. If you are using commons-collections then you can use a DefaultMapEntry or you can simply return an Object[2] or a Map.Entry.
public static DefaultMapEntry getSupplier(List<Supplier> list) {
for(Supplier s : list) {
Object heavyObject = s.invokeCostlyMethod();
if(heavyObject != null) {
return new DefaultMapEntry(s, heavyObject);
}
}
}
Replace the DefaultMapEntry with a List of size 2 or a hashmap of size 1 or an array of length 2 :)