I am new to Java. I am facing an issue now in which I couldn't find the easiest and cleanest way of solving it.
Suppose I have 3 parameters(string) passed to a function(could be a Hashmap too).I want to check if individual variable or combination of variables is not Null and act accordingly.
For example one way to do this is using if-else this way
if(a!=null && b == null && c == null) {
//doSomething
}
else if(a==null && b!= null && c == null ) {
//doSomething
}
else if(a==null && b0= null && c != null) {
//doSomething
}
......
//Similarly combination of two variables
if(a!=null && b != null && c == null) {
//doSomething
}
else if(a!=null && b== null && c != null) {
//doSomething
}
else if(a==null && b!= null && c != null) {
//doSomething
}
......
//and so on
//Similarly combination of three variables
if(a!=null && b != null && c != null) {
//doSomething
}
....
How to achieve this kind of situation. I found similar question, but didn't make the code clean. Any help will be appreciated
Write these utility functions and you can compare n terms easily.
public static boolean areAllNull(Object... objects) {
return Stream.of(objects).allMatch(Objects::isNull);
}
public static boolean areAllNotNull(Object... objects) {
return Stream.of(objects).allMatch(Objects::nonNull);
}
you can use these functions for n comparisons.
if(areAllNotNull(a) && areAllNull(b,c)) {
//doSomething
}
else if(areAllNotNull(b) && areAllNull(a,c)) {
//doSomething
}
else if(areAllNotNull(c) && areAllNull(b,a)) {
//doSomething
}
This is my solution. Note, that you have multiple if...else in one single method. And then you add doSomething. This is going to be terrible to ready and later to realize.
What about to move one single condition into separate method and name it with relative name. Then, lets encapsulate it into Consumer and all of it into a predefined list. Later, if your doSomething will be huge, then you can move from single method to single class, not modifying client code.
This is class, to collect required variable for conditions:
final class Data {
private final String a;
private final String b;
private final String c;
}
Then define one Consumer per on if statement:
Consumer<Data> wonderfulConsumer = data -> {
if (a != null && b == null && c == null) {
// do something for wonderful consumer
}
};
Consumer<Data> badLuckConsumer = data -> {
if (a == null && b != null && c == null) {
// do something for bad luck consumer
}
};
Note, all these consumers could be modified separately (even be in the different classes).
Then in the client code, define list of all known consumers: List<Consumer<Data>> consumers = Arrays.asList(wonderfulConsumer, badLuckConsumer).
And finally your method will be like this and you do not need to change it when you decide to modify or add consumers.
Data data = new Data(a, b, c);
consumers.forEach(consumer -> consumer.accept(data));
If I had to do this , i will do it in the same way that you have done.
but if you dont like that and if you think it is not readable you can do it in this way, i expect lot of negative comments to this answer because this is a bad solution.
public static void yourMethod(Object a,Object b,Object c)
{
int evaluation = howManyNotNull(a,b,c);
if(evaluation == 0) // all are nulls
{
// your code
}
else if(evaluation == 1) // only one is not null
{
if(a!=null)
{
}
else if(b!=null)
{
}
else
{
// c not null
}
}
else if(evaluation == 2) // two variables are not null but other one is null
{
if(a==null)
{
}
else if(b == null)
{
}
else
{
// c is null, a and b not null
}
}
else
{
// all abc not null
}
}
private static int howManyNotNull(Object a, Object b, Object c)
{
return (a==null?0:1) + (b==null?0:1) + (c==null?0:1);
}
There is extended version of this , assign 3 prime values for a, b , c (example :a=2,b=3,c=5), then use a supportive method like this
private static int convertAvailabilityToInt(Object a, Object b, Object c)
{
return (a==null?1:2) * (b==null?1:3) * (c==null?1:5);
}
if the answer is 1 ,then all are not null .
You can use for example a 3 digit string simulating 3 flags.
You first set it to "000".
Then you check each variable for null, if it is not you will replace the 0 with 1.
Then you could use switch cases to treat each case.
You are doing everything right but you have to remember that primitive data types cannot be null. For example string is not null, but empty string "", or int cannot be null, its by default sets to 0. In conclusion Objects like Map , ArrayList or Integer.. you can check for null, but primitive data types cannot be null, so you cannot check them for it. For deeper understanding just learn about primitive and advanced data types.
I hope I got your problem right :)
Related
I have a little problem with this snippet of code:
#Override
public int compareTo(EventResponse o) {
int compare1 = startTime.compareTo(o.startTime);
if (compare1 == 0 && o.myProviderId != null && o.providerId != null) {
return o.providerId.compareTo(o.myProviderId) != 0 ? -1 : 0;
} else {
return compare1;
}
}
I have EventResponse class which i have created that implements Comparable interface, o.myProviderId is ID of currently signed in user (into application) and o.providerId is ID of user that is assigned to particular object (EventResponse).
What I need to achieve is if there are two objects with the same startTime to show objects assigned to me first and then objects assigned to some other provider/s.
This code snippet should (and I think it did in the past) do the trick but I get error message stating: "Comparison method violates its general contract".
Please help!
The violation of the contract often means that the comparator is not providing the correct or consistent value when comparing objects.
For example :
if (compare1 == 0 && o.myProviderId != null && o.providerId != null) {
return o.providerId.compareTo(o.myProviderId) != 0 ? -1 : 0;
}
So, what happens when o.providerId.compareTo(o.myProviderId) gives you 1 or -1. In both scenario you are going to return -1 isn't it ?
Instead, why not simply return what gets return from compareTo ?
if (compare1 == 0 && o.myProviderId != null && o.providerId != null) {
return o.providerId.compareTo(o.myProviderId);
}
So today my data structures final had an exam question that asked this:
"Consider the BinaryTree class and add two recursive methods (independent from each other) named compBT to compare two binary trees. If the two binary trees are structurally identical (i.e., they look the same when the objects stored in the nodes are ignored), each of the two methods returns true; otherwise, each returns false. The first method should be an instance method and the second method should be a class method. Do not access the underlying data structure directly. Note: each method should not take more than 6 lines and be properly indented."
I was able to produce this for the class method:
public static boolean compareTrees(BinaryTree t1, BinaryTree t2) {
if (t1 == null && t2 == null) return true;
if ((t1 == null && t2 != null) || (t1 != null && t2 == null)) return false;
return compareTrees(t1.left, t2.left) && compareTrees(t1.right, t2.right);
}
I felt pretty confident about this answer, but writing the instance method had me totally stumped, especially since it had to be independent from the class method. All I was able to produce was the following:
public boolean compareTrees(BinaryTree t) {
if (t == null) return false;
return (compareTrees(this.left) && (t.left)) && (compareTrees(this.right) && compareTrees(t.right));
}
I know the method is incorrect since it will always return false because there is only one base case which will always be met. My thought process behind that particular base case is that if the parameter is null, then return false since there is a structural inequality because the caller cannot be null (only non-null references can call instance methods). But I didn't know what else to do from there.
Can anyone chime in? I thought this problem was pretty interesting.
Edit: adding in BinaryTree class.
Here's what the BinaryTree class looked like:
class BinaryTree {
public int value;
public BinaryTree left;
public BinaryTree right;
public BinaryTree(int x) { value = x;}
}
For instance method, all that changes is that check is before recursion, no in it:
public boolean compareTrees(BinaryTree other) {
if (left == null) != (other.left == null) return false;
if (right == null) != (other.right == null) return false;
if (left != null && !left.compareTrees(other.left)) return false;
if (right != null && !right.compareTrees(other.right)) return false;
return true;
}
I think you've recognized the basic problem. In your static method, you can pass null for both child trees when you call the method recursively. But in your instance method, you can only do that for the parameter. You can't do that for the instance method, since you can't call an instance method on null.
Well, if you can't call the instance method recursively on a null child, you have to handle the null child case before the recursive call. That's the key here, the realization that you will have to rearrange your logic. So your logic will need to be something like this:
If the parameter is null, return false (like you already did)
If the instance's left child is null, then:
2.1 If the parameter's left child is not null, return false
2.2 If the parameter's left child is null, keep going with step 4
If the instance's left child is not null, then call recursively on the left child (it doesn't matter if the parameter's left child is null, because that will be caught be #1), and return false if the recursive call returns false
4-5. Same steps for the right child
If we've gotten this far, and no check has failed, then we can return true
So the code looks something like this:
public boolean compareTrees(BinaryTree t) {
if (t == null) return false;
if (this.left == null) {
if (t.left != null) {
return false;
}
}
else if (!this.left.compareTrees(t.left)) {
return false;
}
if (this.right == null) {
if (t.right != null) {
return false;
}
}
else if (!this.right.compareTrees(t.right)) {
return false;
}
return true;
}
EDIT: I just now noticed the requirement that the method not be more than 6 lines. So I guess my answer won't work. On the other hand, I could make it work by compressing a bunch of stuff onto a few lines.
public boolean compareTrees(BinaryTree t) {
if (t == null) return false;
if (this.left == null && t.left != null) return false;
if (this.left != null && !this.left.compareTrees(t.left)) return false;
if (this.right == null && t.right != null) return false;
if (this.right != null && !this.right.compareTrees(t.right)) return false;
return true;
}
I could make it even shorter by combining the last two lines into one. But
if your professor is going to reward compressed, harder-to-read code such as this, and fail cleaner code like I had in my earlier example, shame on him.
More: OK, if your professor measures code quality by a smaller number of lines, this should make him ecstatic, even though all my colleagues would blast it in a code review:
public boolean compareTrees(BinaryTree t) {
return !((t == null) || (this.left == null && t.left != null) || (this.left != null && !this.left.compareTrees(t.left)) || (this.right == null && t.right != null) || (this.right != null && !this.right.compareTrees(t.right)) );
}
I’m using Java 6. I have two Boolean objects, a and b. How do I compare the two in terms of their value? I have come up with this, but it seems really long and messy …
(a == null && b == null) || (a != null && b != null && a.booleanValue().equals(b.booleanValue()))
I like Apache’s StringUtils.equals(a, b) method for comparing strings, but there doesn’t seem to be an equivalent method for BooleanUtils.
You can use the following for any two Objects including two Boolean
a == null ? b == null : a.equals(b);
This works for Java 1.0+
you can use the compareTo in the class boolean.. it is avaliable since 1.5
take a look to this snippet
private static int compare(Boolean a, Boolean b) {
// if (a == null || b == null) {
// return -1;
// }else {
// return a.compareTo(b);
// }
return (a == null || b == null) ? -1 : a.compareTo(b);
}
the return line is doing the same as the commented one...
Often in java I have to get a value of a property of an object which is deep in this object. For example, if I'm sure that all my sub-objects are not null, I can do that :
public function getDeepValue(A a) {
String value = a.getB().getC().getListeD().get(0).getE().getValue();
return value;
}
But in case of sub objects of the parent can be null, I have to test every object.
To do that, I see 2/3 solutions :
First, step by step :
public function getDeepValue(A a) {
if(a == null){
return null;
}
B b = a.getB();
if(b == null) {
return null;
}
C c = b.getC();
if(c == null){
return null;
}
List<D> ds = c.getListeD();
if(ds == null || ds.size() == 0){
return null;
}
D d = ds.get(0);
if(d == null) {
return null;
}
E e = d.getE()
if(e == null){
return null;
}
return e.getValue();
}
Second, test all in one if block, soooo dirty :
public function getDeepValue(A a) {
if(a != null && a.getB() != null && a.getB().getC() != null && a.getB().getC().getListeD() != null && a.getB().getC().getListeD().size() > 0 && a.getB().getC().getListeD().get(0) != null && a.getB().getC().getListeD().get(0).getE() != null){
return a.getB().getC().getListeD().get(0).getE().getValue();
}
return null;
}
Third solution, using a try catch block :
public function getDeepValue(A a) {
try {
return a.getB().getC().getListeD().get(0).getE().getValue();
} catch(NullPointerException e) {
return null;
} catch(IndexOutOfBoundsException e) {
return null;
}
}
Solution 1 seems not too bad but needs a lot of code. It is generally the solution I use.
Solution 2 is for me really dirty...
In paper, I realy like solution 3, but is it a good solution in term of performances ?
Is there any others acceptables solutions ?
Thanks for help, I hope my english is not too bad..
Regards
Solution #3 looks simple, but it can potentially hide a whole host of problems. It might be an adequate solution if you have full access to all of the classes in the chain and you know what's going on in each method and you can guarantee those methods won't cause problems with your try/catch and you're never going to change them... that's a lot of conditions to make it a worthwhile solution, but I can conceive that it's possibly a useful sufficient one.
Solution #2 looks horrid to me, especially if one or more of the get methods is a bottleneck (such as a slow database query or using a blocking network connection). The earlier in the chain such a potential bottleneck, the worse it would potentially be, as you're calling it over and over again. This of course depends on the implementation of the methods in question (even if one of them is slow, the result could be cached, for example), but you shouldn't need to know that in your client code. Even with efficient or trivial implementations, you've still got the overhead of repeated method calls you oughtn't need.
Solution #1 is the best of the three, but it's likely not the best possible. This solution takes more lines of code than the other two, but it doesn't repeat itself and it isn't going to be tripped up by the implementations of the other methods. (Note: If you do not have access to the classes in the chain for refactoring, I would use this solution.)
A better solution than #1 would be to refactor the classes so that the client code doesn't need to know about this chain at all. Something along these lines:
class Client {
public Mumble getDeepValue(A a) { return a == null ? null : a.getDeepValue(); }
}
class A {
private B b;
public Mumble getDeepValue() { return b == null ? null : b.getDeepValue(); }
}
class B {
private C c;
public Mumble getDeepValue() { return c == null ? null : c.getDeepValue(); }
}
class C {
private List<D> ds;
public Mumble getDeepValue() {
D d = ds == null || ds.size() == 0 ? null : ds.get(0);
return d == null ? null : d.getDeepValue();
}
}
class D {
private E e;
public Mumble getDeepValue() { return e == null ? null : e.getMumble(); }
}
class E {
private Mumble m;
public Mumble getMumble() { return m; }
}
As you can see, the longest chain any of these classes has is to access the public members of an element of a collection that is a private member of the class. (Essentially ds.get(0).getDeepValue()) The client code doesn't know how deep the rabbit hole goes, only that A exposes a method which returns a Mumble. Client doesn't even need to know that the classes B, C, D, E, or List exist anywhere!
Additionally, if I were designing this system from the ground up, I would take a good long look at whether it could be restructured such that the actual Mumble object wasn't so deep. If I could reasonably get away with storing the Mumble within A or B, I'd recommend doing it. Depending on the application, that may not be possible however.
in terms of performance solution 3 is the best one. In addition It is neat and easy to understand , For example looking at a loop example:
int[] b = somevalue;
for(int i=0;i<b.length;i++){
//do something
}
in this case for every iteration we execute the condition. However, there is another approach for it which uses try and catch
int[] b = somevalue;
try{
for(int i=0;;i++){
//do something
}
}catch(IndexOutOfBoundException e){
// do something
}
on the second solution,the loop keeps going until we reach the end of the loop which then it throws IndexOutOfBoundException as soon as we reach the end of the array. meaning we don't check for the condition no more. thus faster.
Can I simplify this java if construct? It seems too verbose to me, I'd like to have it shorter.
A is persistent Object, which will be null if it's context is accessed first time. Than A is instatniated and given content, and if this fails, some backup content is given to A.
if (A == null) {
A = staticGetMethod();
if (A == null) A = new BackupAContent() { ... };
}
Update: Or you could simply remove the nesting as it will still behave the same way.
if (A == null) {
A = staticGetMethod();
}
if (A == null) {
new BackupAContent() { ... };
}
Should work:
if (A == null && (A = staticGetMethod()) == null) {
new BackupAContent() { ... };
}
Put your building logic in factory method
if (objA == null) {
objA = getAInstance();
}
encapsulate the code suggested by Charles into a method to implement Factory_method_pattern
You can use a ternary operator instead of the if statements:
a = a ? a : staticGetMethod();
a = a ? a : new BackupAContent();
That said, I'd stick with what you've got, to be honest -- except that I would add a block for the second conditional rather than putting the statement inline with it.
This is Charles Goodwin's code with a slight change:
if (A == null && (A = staticGetMethod()) == null) {
new BackupAContent() { ... };
}
I used an AND instead of an OR
I think this is the best way to do it:
if(A == null)
{
if((A = staticGetMethod()) == null) A = new BackupAContent() { ... };
}