Performance penalty when using Java varargs method with no arguments - java

Suggest the following Java class:
/** Utility class for working with DOM nodes.
*/
public class DomNodes {
public static boolean isElement(Node pNode, String pElementName, String... pAttributes) {
if (pNode.getNodeType() == Node.ELEMENT_NODE) {
final Element e = (Element) pNode;
final String uri = e.getNamespaceURI();
if (uri == null || uri.length() == 0) {
if (pElementName.equals(e.getLocalPart())) {
if (pAttributes == null || areAttributesMatching(pNode, pAttributes)) {
return true;
}
}
}
}
}
}
Now, suggest the following two uses of that class:
isElement(node, "foo");
isElement(node, "foo", "attribute0", value0, "attribute1", value1, "attribute2", value2);
It is obvious to me, that the second invocation depends on the construction of a string array. In other words, there is a small performance penalty for the construction of that array.
The first invocation, however, isn't obvious: The compiler could implement this by passing a newly constructed array with no elements. However, it might just as well pass the value null, or a constant array.
In the former case, I could help the compiler by adding a method
isElement(Node pNode, String pElementName). Question: Would you recommend that?

Related

Having trouble sorting leaves in ascending order for binary tree

So the original problem is Write the method chechkLeaves(), which should return true if the leaves of the tree are sorted in increasing order and false otherwise. You can assume that data for all internal nodes are null. You will find it useful to define additional recursive helper methods for this problem. 
Edit: My code is working now, but how can I modify the code so that I the val is passed in as a parameter rather than global variable?
static int val = 0;
static public boolean checkLeaves(Node root) {
// int val = 0;
if(root.data != 0 ) {
if(root.data > val) {
val = root.data;
return true;
} else {
return false;
}
} else {
return checkLeaves(root.left) && checkLeaves(root.right);
}
}
There isn't really a way for you to be able to do this traversal of the leaves with comparison without a global variable. This is something that can be accomplished with passing-by-reference, but Java doesn't have such a feature. So, you have two options:
Option 1) Stick with this static variable.
Option 2) Make val a parameter as an array, as such:
private static public boolean checkLeaves(Node root, int[] val) {
if (root.data != 0) {
if (root.data > val[0]) {
val[0] = root.data;
return true;
} else {
return false;
}
} else {
return checkLeaves(root.left, val) && checkLeaves(root.right, val);
}
}
And to call it:
checkLeaves(root, new int[] { Integer.MIN_VALUE });
By making it an array, you can emulate that "pass by reference" behavior. That is, updating the original value of the variable by having a reference to the original value. Everything in Java is pass-by-value, so the value of the variable is passed to the parameter, not the reference to it.
Note
I suggest you name your variables a little more descriptive. For example, instead of val, you could name it previousLeafValue or something.
Also, a good practice to follow is making everything as "private" as possible. In option 2 you can see my code have the method with a private access modifier. The same is true for your static variable. Make it a habit to make things private by habit, then expand their modifiers as needed.

Suspicious call to Collection.contains method in ArrayList

I am getting a warning that watchStore.contains(s) is a suspicious call to java.util.Collection#contains. How can I fix it? I want to use contains() to find a particular object with the matching serial number.
public Watch findWatchBySerialNumber(long srch) {
long s = srch;
Watch watch = null;
for(int i = 0; i < watchStore.size(); i++) {
watch = watchStore.get(i);
if(watchStore.contains(s)) {
System.out.print("item found");
return watch;
}
}
System.out.print("item not found");
return null; // watch is not found.
}
Presuming that Watch is the class, watchStore is a List<Watch>, and that a field serialNo exists on Watch...
public Optional<Watch> findWatchBySerialNumber(long serial) {
return watchStore.stream()
.filter(w -> w.getSerialNo() == serial)
.findFirst();
}
If you're not using Java 8, the code is close, but a bit more dangerous since you have the chance to return null. If you can use Guava's Optional, that'd be a better choice here.
public Watch findWatchBySerialNumber(long serial) {
for(Watch w : watchStore) {
if(w.getSerialNo() == serial) {
return w;
}
}
return null;
}
Your contains isn't going to work since your list doesn't contain Longs, it contains Watchs. This is also why the compiler sees it as dubious; contains accepts an Object but it will return false if what you're looking for doesn't have a comparable equals for what's in your list.
You have to iterate over the entirety of your collection to find it in this scenario, especially since you're looking for a specific property on those objects as opposed to a specific, easy-to-provide value.
please how can I fix that. I want to use the contain() to find a
particular object with the matching serial number.
In that case override Watch's equals() to use serialNumber field for comparison.
Then add constructor that accepts serialNumber.
public class Watch {
private final long serialNumber;
public Watch(long serialNumber) {
this.serialNumber = serialNumber;
}
#Override
public boolean equals(Object obj) {
return obj == this ||
(obj instanceof Watch && ((Watch)obj).serialNumber == serialNumber);
}
#Override
public int hashCode() {
return (int)serialNumber;
}
}
Replace if(watchStore.contains(s)){ with if(watchStore.contains(watchToFind)){ where Watch watchToFind = new Watch(s);
you can use contains method from org.apache.commons.lang.ArrayUtils package.
Checks if the value is in the given array.
The method returns false if a null array is passed in.
Parameters:
array the array to search through
valueToFind the value to find
Returns:
true if the array contains the object
long [] imageHashes= {12l,13l,14l,15l};
System.out.println(ArrayUtils.contains(imageHashes, 13l));

How to check multiple objects for nullity?

Often, I can see a code constructs like following:
if(a == null || b == null || c == null){
//...
}
I wonder if there is any widely used library (Google, Apache, etc.) to check against nullity for multiple objects at once, e.g.:
if(anyIsNull(a, b, c)){
//...
}
or
if(allAreNulls(a, b, c)){
//...
}
UPDATE:
I perfectly know how to write it by myself
I know it can be the result of the poor program structure but it's not a case here
Let's make it more challenging and replace original example with something like this:
if(a != null && a.getFoo() != null && a.getFoo().getBar() != null){
//...
}
UPDATE 2:
I've created a pull request for Apache Commons Lang library to fix this gap:
Issue: https://issues.apache.org/jira/browse/LANG-781
PR: https://github.com/apache/commons-lang/pull/108
These will be incorporated in commons-lang, version 3.5:
anyNotNull (Object... values)
allNotNull (Object... values)
In Java 8, you could use Stream.allMatch to check whether all of the values match a certain condition, such as being null. Not much shorter, but maybe a bit easier to read.
if (Stream.of(a, b, c).allMatch(x -> x == null)) {
...
}
And analogeously for anyMatch and noneMatch.
About your "more challenging example": In this case, I think there is no way around writing a lazy-evaluated conjunction of null-checks, like the one you have:
if (a != null && a.getFoo() != null && a.getFoo().getBar() != null) {
...
}
Any of the other approaches, using streams, lists, or var-arg methods, would try to evaluate a.getFoo() before a has been tested not to be null. You could use Optional with map and method pointers, that will be lazily evaluated one after the other, but whether this makes it any more readable is debatable and may vary from case to case (particularly for longer class names):
if (Optional.ofNullable(a).map(A::getFoo).map(B::getBar).isPresent()) {
...
}
Bar bar = Optional.ofNullable(a).map(A::getFoo).map(B::getBar).orElse(null);
Another alternative might be to try to access the innermost item, but I have a feeling that this is not considered good practice, either:
try {
Bar bar = a.getFoo().getBar();
...
catch (NullPointerException e) {
...
}
Particularly, this will also catch any other NPEs after accessing that element -- either that, or you have to put only the Bar bar = ... in the try and everything else in another if block after the try, nullifying any (questionable) gains in readability or brevity.
Some languages have a Safe Navigation Operator, but it seems like Java is not one of them. This way, you could use a notation like a?.getFoo()?.getBar() != null, where a?.getFoo() will just evaluate to null if a is null. You could emulate behavior like this with a custom function and a lambda, though, returning an Optional or just a value or null if you prefer:
public static <T> Optional<T> tryGet(Supplier<T> f) {
try {
return Optional.of(f.get());
} catch (NullPointerException e) {
return Optional.empty();
}
}
Optional<Bar> bar = tryGet(() -> a.getFoo().getBar(););
EDIT 2018: As of Apache Commons lang 3.5, there has been ObjectUtils.allNotNull() and ObjectUtils.anyNotNull().
No.
None of Apache Commons Lang (3.4), Google Guava (18) and Spring (4.1.7) provide such a utility method.
You'll need to write it on your own if you really, really need it. In modern Java code, I'd probably consider need for such a construct a code smell, though.
You could also use something like the following method. It allows you to pass as many parameters as you want:
public static boolean isAnyObjectNull(Object... objects) {
for (Object o: objects) {
if (o == null) {
return true;
}
}
return false;
}
You call it with as many parameters as you like:
isAnyObjectNull(a, b, c, d, e, f);
You could do something similar for areAllNull.
public static boolean areAllObjectsNull(Object... objects) {
for (Object o: objects) {
if (o != null) {
return false;
}
}
return true;
}
Note: you could also use the ternary operator instead of if (o == null). The two methods shown here have no error handling. Adjust it to your needs.
Objects.requireNonNull
It is possible with help of Objects class and its requireNonNull method.
public static void requireNonNull(Object... objects) {
for (Object object : objects) {
Objects.requireNonNull(object);
}
}
Apache commons-lang3 since version 3.11 has method ObjectUtils.allNull(Object... values)
ObjectUtils.allNull(obj1, obj2, obj3);
I was looking for a solution, but I don't have apache as a dependency yet and it felt silly to me to add it just for the allNonNull method. Here is my plain vanilla java solution using Predicate#and() / Predicate#or() like this:
private static boolean allNonNull(A a) {
Predicate<A> isNotNull = Objects::nonNull;
Predicate<A> hasFoo = someA -> someA.foo != null;
Predicate<A> hasBar = someA -> someA.foo.bar != null;
return Optional.ofNullable(a)
.filter(isNotNull.and(hasFoo.and(hasBar)))
.isPresent();
}
Note: for the anyNonNull, simply use the or() method instead of and().
When invoked, would give the following output:
System.out.println(isValid(new A(new Foo(new Bar())))); // true
System.out.println(isValid(new A(new Foo(null)))); // false
System.out.println(isValid(new A(null))); // false
System.out.println(isValid(null)); // false
Class definitions used:
public static class A {
public A(Foo foo) {
this.foo = foo;
}
Foo foo;
}
public static class Foo {
public Foo(Bar bar) {
this.bar = bar;
}
Bar bar;
}
public static class Bar { }
Simply as that:
Stream.of(a,b,c).allMatch(Objects::nonNull)
You can create a list of you objects and use yourList.contains(null) in it.
List < Object > obList = new ArrayList < Object > ();
String a = null;
Integer b = 2;
Character c = '9';
obList.add(a);
obList.add(b);
obList.add(c);
System.out.println("List is " + obList);
if (obList.contains(null)) {
System.out.println("contains null");
} else {
System.out.println("does not contains null");
}
DEMO

Does java have some convention to indicate that object is in empty state?

Of course, empty definition can differ. I'm used to PHP's empty though, which calls empty everything that evaluates to false. I'd like to call these things empty in my Java application:
null
String of zero length
0 Integer, Float or Double
false
Any array of zero length
Empty ArrayList or HashMap
Java has, for example, toString convention. Every object is granted to give you some string representation. In my Settings class I operate with HashMap<String, Object>. My empty method looks now like this:
public boolean empty(String name) {
Object val = settings.get(name);
if(val!=null) {
return false;
}
return true;
}
I'd like to extend it in a conventional manner, rather than if(val instanceof XXX) chain.
No, there is no standard convention for this in Java. Also, in Java there is no such thing as "evaluate to false" (except for booleans and Booleans, of course).
You will have to write a method (or rather, a series of overloaded methods for each type you need it for) which implements your notion of "empty". For example:
public static boolean isEmpty(String s) {
return (s == null) || (s.isEmpty());
}
public static boolean isEmpty(int i) {
return i == 0;
}
...
You could use overloading to describe all the "empty" objects:
public static boolean empty(Object o) {
return o == null;
}
public static boolean empty(Object[] array) {
return array == null || array.length == 0;
}
public static boolean empty(int[] array) { //do the same for other primitives
return array == null || array.length == 0;
}
public static boolean empty(String s) {
return s == null || s.isEmpty();
}
public static boolean empty(Number n) {
return n == null || n.doubleValue() == 0;
}
public static boolean empty(Collection<?> c) {
return c == null || c.isEmpty();
}
public static boolean empty(Map<?, ?> m) {
return m == null || m.isEmpty();
}
Examples:
public static void main(String[] args) {
Object o = null;
System.out.println(empty(o));
System.out.println(empty(""));
System.out.println(empty("as"));
System.out.println(empty(new int[0]));
System.out.println(empty(new int[] { 1, 2}));
System.out.println(empty(Collections.emptyList()));
System.out.println(empty(Arrays.asList("s")));
System.out.println(empty(0));
System.out.println(empty(1));
}
AFAIK there is no such convention. It's fairly common to see project specific utility classes with methods such as:
public static boolean isEmpty(String s) {
return s == null || s.isEmpty();
}
However I personally think its use is a bit of a code smell in Java. There's a lot of badly written Java around, but well written Java shouldn't need null checks everywhere, and you should know enough about the type of an object to apply type-specific definitions of "empty".
The exception would be if you were doing reflection-oriented code that worked with Object variables who's type you don't know at compile time. That code should be so isolated that it's not appropriate to have a util method to support it.
Python's duck-typing means the rules are sort of different.
How about creating an interface EmptinessComparable or something similar, and having all your classes implement that? So you can just expect that, and not have to ask instanceof every time.
Java does not, but Groovy does. Groovy runs on the Java VM alongside Java code and provides many shortcuts and convenient conventions such as this. A good approach is write foundation and crital project components in Java and use Groovy for less critical higher level components.
If you want to use the one approach, I would overload a utility method:
public class MyUtils {
public static boolean isEmpty(String s) {
return s == null || s.isEmpty();
}
public static boolean isEmpty(Boolean b) {
return b == null || !b;
}
// add other versions of the method for other types
}
Then your code always looks like:
if (MyUtils.isEmpty(something))
If the type you're checking isn't supported, you'll get a compiler error, and you can implement another version as you like.
There are ways to establish the notion of emptiness but it's not standardized across all Java classes. For example, the Map (implementation) provides the Map#containsKey() method to check if a key exists or not. The List and String (implementations) provide the isEmpty() method but the List or String reference itself could be null and hence you cannot avoid a null check there.
You could however come up with a utility class of your own that takes an Object and using instanceof adapts the empty checks accordingly.
public final class DataUtils {
public static boolean isEmpty(Object data) {
if (data == null) {
return false;
}
if (data instanceof String) {
return ((String) data).isEmpty();
}
if (data instanceof Collection) {
return ((Collection) data).isEmpty();
}
}
}
The Guava Libraries already contains Defaults class that do just that.
Calling defaultValue will return the default value for any primitive type (as specified by the JLS), and null for any other type.
You can use it like shown below:
import com.google.common.base.Defaults;
Defaults.defaultValue(Integer.TYPE); //will return 0
Below is example code on how to use it:
import com.google.common.base.Defaults;
public class CheckingFieldsDefault
{
public static class MyClass {
private int x;
private int y = 2;
}
public static void main() {
MyClass my = new MyClass();
System.out.println("x is defualt: " + (my.x == Defaults.defaultValue(box(my.x).TYPE)));
System.out.println("y is defualt: " + (my.y == Defaults.defaultValue(box(my.y).TYPE)));
}
private static <T extends Object> T box(T t) {
return t;
}
}

Final initialization in java can be postponed, how does this prevent against returning null inadvertently?

In the "hidden features of java" question, someone mentions that final initialization can be postponed and provides an example:
public Object getElementAt(int index) {
final Object element;
if (index == 0) {
element = "Result 1";
} else if (index == 1) {
element = "Result 22";
} else {
element = "Result 3";
}
return element;
}
The poster says:
It's too easy to miss a case and return null by accident. It doesn't make returning null impossible, just obvious that it's on purpose.
However I cannot wrap my head around what this means. How is this any different if element was not declared final? Wouldn't the else statement always ensure that null is not returned? I'm thinking this is more a cosmetic thing rather than actually effecting the way the code operates.
The way you posted the question, the poster seems to be saying that if you did:
Object element = null;
And then set it via the if methods, you could return null by accident (if you didn't construct your else statement correctly), so take advantage of the fact that final initialization can be differed to after declaration.
However, the example is superfluous, because the compiler guarantees that this variable will be set before being used because it is local.
More interesting would be a case like this:
public class SomeClass {
private final Object element;
public SomeClass(int index) {
if (index == 0) {
element = "Result 1";
} else if (index == 1) {
element = "Result 22";
} else {
element = "Result 3";
}
}
}
In that case the compiler will warn you if you never set element, rather than setting it to null for you, which is what would happen if it was not declared final.
In summary, what is interesting to know is that a final field or variable doesn't have to be set where it is declared (as you might be inclined to think). Final means that it can only be set to a given value once, not that it has to be set on the same line as it is declared.
Finals can only be set and never re-set. They are sometimes conflated with the concept of constants in java. More correctly they are immutable object references.
The catch is that if something is immutable, how and when do you set its initial value. The answer is that java checks that only one possible flow can assign a value to a final variable. That way you don't have to assign the value at declaration time.

Categories

Resources