I've got a problem with java's instanceof. Here's a gap of code that causes me trouble:
LinkedList<Double> currentSummary = summary.getFirst().getQuantiles();
...more code...
while (!currentSummary.isEmpty()){
if (currentSummary.getFirst() instanceof Double){
orderedSummary.add(new ComparableWrapper<Double, Float>(currentSummary.removeFirst(), currentEpsilon));
}
}
So, my problem is, that the if-condition won't become true. Those elements in currentSummary are either null or an Double-value. And I'm trying to reject elements that are null. At first I just added them and ran into NullPointerException later on, because of some (but not all!) elements being null.
An example element of currentSummary is e.g. [null, 0.09861866469135272, 10.137051035535745, 107.12083740100329, 371.4371264801424, 827.432799544501, 1206.251577083686].
Anybody got's an idea why instanceof won't work in that case? I tried it with currentSummary.getFirst() instanceof Object as well...
Thanks in advance!
I assume you want to remove the first entry at each iteration, in order to traverse the complete list. However, you remove the entry only when the instanceof condition is true. Therefore, it seems like the loop becomes infinite when it encounters the first null value (unless you dropped parts of the code, and we don't see the complete loop body)
Is it possible that due to auto-boxing/unboxing, the Double objects get unboxed to the primitive double, and therefore they are not instance of Double class.
If that is the case, would it be better if you check for non-null elements instead?
Why don't you just use a simple null check?
if (currentSummary.getFirst() != null){ ... }
It is possible, by using raw types (LinkedList instead of LinkedList<Double>), to add non-Double entries to your LinkedList<Double>. Those elements would fail the instanceof Double test. But those entries would pass an instanceof Object test.
Related
I have two ways of checking if a List is empty or not
if (CollectionUtils.isNotEmpty(listName))
and
if (listName != null && listName.size() != 0)
My arch tells me that the former is better than latter. But I think the latter is better.
Can anyone please clarify it?
You should absolutely use isEmpty(). Computing the size() of an arbitrary list could be expensive. Even validating whether it has any elements can be expensive, of course, but there's no optimization for size() which can't also make isEmpty() faster, whereas the reverse is not the case.
For example, suppose you had a linked list structure which didn't cache the size (whereas LinkedList<E> does). Then size() would become an O(N) operation, whereas isEmpty() would still be O(1).
Additionally of course, using isEmpty() states what you're actually interested in more clearly.
CollectionUtils.isNotEmpty checks if your collection is not null and not empty. This is better comparing to double check but only if you have this Apache library in your project. If you don't then use:
if(list != null && !list.isEmpty())
Unless you are already using CollectionUtils I would go for List.isEmpty(), less dependencies.
Performance wise CollectionUtils will be a tad slower. Because it basically follows the same logic but has additional overhead.
So it would be readability vs. performance vs. dependencies. Not much of a big difference though.
if (CollectionUtils.isNotEmpty(listName))
Is the same as:
if(listName != null && !listName.isEmpty())
In first approach listName can be null and null pointer exception will not be thrown. In second approach you have to check for null manually. First approach is better because it requires less work from you. Using .size() != 0 is something unnecessary at all, also i learned that it is slower than using .isEmpty()
If you have the Apache common utilities in your project rather use the first one. Because its shorter and does exactly the same as the latter one. There won't be any difference between both methods but how it looks inside the source code.
Also a empty check using
listName.size() != 0
Is discouraged because all collection implementations have the
listName.isEmpty()
function that does exactly the same.
So all in all, if you have the Apache common utils in your classpath anyway, use
if (CollectionUtils.isNotEmpty(listName))
in any other case use
if(listName != null && listName.isEmpty())
You will not notice any performance difference. Both lines do exactly the same.
Apache Commons' CollectionUtils.isNotEmpty(Collection) is a NULL-SAFE check
Returns TRUE is the Collection/List is not-empty and not-null
Returns FALSE if the Collection is Null
Example:
List<String> properties = new ArrayList();
...
if (CollectionUtils.isNotEmpty(properties)) {
// process the list
} else {
// list is null or empty
}
Refer:
https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/CollectionUtils.html#isNotEmpty(java.util.Collection)
isEmpty()
Returns true if this list contains no elements.
http://docs.oracle.com/javase/1.4.2/docs/api/java/util/List.html
A good example of where this matters in practice is the ConcurrentSkipListSet implementation in the JDK, which states:
Beware that, unlike in most collections, the size method is not a constant-time operation.
This is a clear case where isEmpty() is much more efficient than checking whether size()==0.
You can see why, intuitively, this might be the case in some collections. If it's the sort of structure where you have to traverse the whole thing to count the elements, then if all you want to know is whether it's empty, you can stop as soon as you've found the first one.
Use CollectionUtils.isEmpty(Collection coll)
Null-safe check if the specified collection is empty.
Null returns true.
Parameters:
coll - the collection to check, may be null
Returns:
true if empty or null
The org.apache.commons.collections4.CollectionUtils isEmpty() method is used to check any collections(List, Set, etc.) are empty or not. It checks for null as well as size of collections. The CollectionUtils isEmpty() is a static method, which accepts Collection as a parameter.
I would use the first one. It is clear to see right away what it does. I dont think the null check is necessary here.
table.column = ANY(ARRAY[ :canEmptyArrayParameter ]::BIGINT[])
It helps me to check empty parameter of array
this parameter can be Collections.emptyList();
To Check collection is empty, you can use method: .count(). Example:
DBCollection collection = mMongoOperation.getCollection("sequence");
if(collection.count() == 0) {
SequenceId sequenceId = new SequenceId("id", 0);
mMongoOperation.save(sequenceId);
}
Why does this throw a java.lang.NullPointerException?
List<String> strings = new ArrayList<>();
strings.add(null);
strings.add("test");
String firstString = strings.stream()
.findFirst() // Exception thrown here
.orElse("StringWhenListIsEmpty");
//.orElse(null); // Changing the `orElse()` to avoid ambiguity
The first item in strings is null, which is a perfectly acceptable value. Furthermore, findFirst() returns an Optional, which makes even more sense for findFirst() to be able to handle nulls.
EDIT: updated the orElse() to be less ambiguous.
The reason for this is the use of Optional<T> in the return. Optional is not allowed to contain null. Essentially, it offers no way of distinguishing situations "it's not there" and "it's there, but it is set to null".
That's why the documentation explicitly prohibits the situation when null is selected in findFirst():
Throws:
NullPointerException - if the element selected is null
As already discussed, the API designers do not assume that the developer wants to treat null values and absent values the same way.
If you still want to do that, you may do it explicitly by applying the sequence
.map(Optional::ofNullable).findFirst().flatMap(Function.identity())
to the stream. The result will be an empty optional in both cases, if there is no first element or if the first element is null. So in your case, you may use
String firstString = strings.stream()
.map(Optional::ofNullable).findFirst().flatMap(Function.identity())
.orElse(null);
to get a null value if the first element is either absent or null.
If you want to distinguish between these cases, you may simply omit the flatMap step:
Optional<String> firstString = strings.stream()
.map(Optional::ofNullable).findFirst().orElse(null);
System.out.println(firstString==null? "no such element":
firstString.orElse("first element is null"));
This is not much different to your updated question. You just have to replace "no such element" with "StringWhenListIsEmpty" and "first element is null" with null. But if you don’t like conditionals, you can achieve it also like:
String firstString = strings.stream()
.map(Optional::ofNullable).findFirst()
.orElseGet(()->Optional.of("StringWhenListIsEmpty"))
.orElse(null);
Now, firstString will be null if an element exists but is null and it will be "StringWhenListIsEmpty" when no element exists.
You can use java.util.Objects.nonNull to filter the list before find
something like
list.stream().filter(Objects::nonNull).findFirst();
The following code replaces findFirst() with limit(1) and replaces orElse() with reduce():
String firstString = strings.
stream().
limit(1).
reduce("StringWhenListIsEmpty", (first, second) -> second);
limit() allows only 1 element to reach reduce. The BinaryOperator passed to reduce returns that 1 element or else "StringWhenListIsEmpty" if no elements reach the reduce.
The beauty of this solution is that Optional isn't allocated and the BinaryOperator lambda isn't going to allocate anything.
Optional is supposed to be a "value" type. (read the fine print in javadoc:) JVM could even replace all Optional<Foo> with just Foo, removing all boxing and unboxing costs. A null Foo means an empty Optional<Foo>.
It is a possible design to allow Optional with null value, without adding a boolean flag - just add a sentinel object. (could even use this as sentinel; see Throwable.cause)
The decision that Optional cannot wrap null is not based on runtime cost. This was a hugely contended issue and you need to dig the mailing lists. The decision is not convincing to everybody.
In any case, since Optional cannot wrap null value, it pushes us in a corner in cases like findFirst. They must have reasoned that null values are very rare (it was even considered that Stream should bar null values), therefore it is more convenient to throw exception on null values instead of on empty streams.
A workaround is to box null, e.g.
class Box<T>
static Box<T> of(T value){ .. }
Optional<Box<String>> first = stream.map(Box::of).findFirst();
(They say the solution to every OOP problem is to introduce another type :)
This question is a bit hard to explain so please look at the increasingPath function in the code here. Now assuming the path does not exist, and arraylist pointPath with 0 size is returned.
However I have read that we must use Collections.emptyList, but how do I use it in this scenario, when I already have a probably empty list called pointPath ? If not to use Collections.emptyList then when to use it ?
I think what you're supposed to do is use Collections.EmptyList for comparisons and returning.
for example:
if (pointPath.equals(Collections.emptyList()){
return Collections.emptyList();
}
I don't think it changes how your program will execute, but it makes the code readable and self-documenting.
Simply check
if (pointPath.isEmpty()){
return Collections.emptyList();
}
The only difference from actually returning a your list that is accidentally empty is that Collections.emptyList() is immutable list. If that is not of any value to you, I'd return your real list. That way there is less code to read.
we use collections like ArrayList,hashmap & many more.
Number of times we have check condition like whether list is null or not.
We have many ways to chek whether our collection is null or not.
Different ways.
1. if(list==null)
2. if(list.size()==0)
3. if(list.isEmpty())
Also sometimes we also need to check whether list is not null , so we normally check it by these ways
1. if(list!=null)
2. if(list.size()>0)
3. if(!list.isEmpty())
Which is best condition or do we need to make some combination of
these considering performance of program execution?
Best combination would be
if(list!=null && !list.isEmpty()){
//Yeah ,do something
}
One for null check, and then any thing there or not check
1. if(list!=null)
You should make sure that is never the case!!
Read Effective Java 2nd Edition by Joshua Bloch
Item 43: Return empty arrays or collections, not nulls
[...] In summary, there is no reason ever to return null from an array- or
collection-valued method instead of returning an empty array or
collection. The null-return idiom is likely a holdover from the C
programming language, in which array lengths are returned separately
from actual arrays. In C, there is no advantage to allocating an array
if zero is returned as the length.
In short, let your methods return Collections.emptyList() instead of null and you've got one thing less to worry about.
2. if(list.size()>0)
3. if(!list.isEmpty())
That depends. For a simple collection such as ArrayList, they are equivalent. But what if your Collection is actually a live view of a Database query? Calling size() might me a very expensive operation, whereas isEmpty() will always be O(1). I'd say use isEmpty().
Also see Jon Skeet's answer here: https://stackoverflow.com/a/11152624/342852
In Java8 you can use Optional to handle null cases properly. For example, both lists animalsNull and animalWithNullElements would be properly handled by the function filterList:
List<String> animalsNull = null;
List<String> animalWithNullElements = new ArrayList<String>();
animalWithNullElements.add(0, null);
animalWithNullElements.add(1, "Guybrush Threepwood");
animalWithNullElements.add(2, null);
private static List<String> filterList(List<String> animals) {
return Optional.ofNullable(animals)
.orElseGet(Collections::emptyList)
.stream()
.filter(Objects::nonNull)
.collect(Collectors.toList());
}
It really depends on what you want to do. If you want to be sure that a list exist AND has some elements then you would use
if (list != null && !list.isEmpty())
If I may give some advice, while returning collections, return by default an empty collection. That way you will avoid nulls.
Number of times we have check condition like whether list is null or not.
For a start, a null collection and an empty collection are different things. If you need to test if a collection is null you need a different test to if you are trying to test if the collection is empty.
Secondly, if a collection could be either null or empty (and they "mean" the same thing, per your application design) then you have a problem in your design. You should most likely represent ... whatever it is you are trying to represent ... one way, and not either / both ways.
Thirdly, it is generally best to use an empty collection rather than a null, because you can treat an empty and non-empty collection uniformly. By contrast, a null always needs to be handled as a special case. (And if you forget to handle the null case, then you've got a potential for NullPointerExceptions.)
Having said that ...
Which is best condition or do we need to make some combination of these considering performance of program execution?
If you really need to deal with the case of a null, then you've no choice but to test for null.
For isEmpty() versus size() == 0:
the two predicates should give the same answer (unless you have an infinite lazy collection ...), but
in some cases isEmpty() could be faster, at least in theory.
The latter depends on the implementation of the collection type: specifically, on whether the size() method needs to count the collection elements. (I don't think that any of the standard collection classes have this property, but that's not to say that you won't find some class that does ...)
So the optimal predicate is most likely either:
c != null && !c.isEmpty()
or
!c.isEmpty()
depending on whether you (really) need to cater for nulls.
And the obvious corollary is that your application is likely to be more efficient ... as well as simpler and more robust ... if you don't use null to represent empty collections. (If you need immutable empty collection objects, you can get them for free from methods / statics defined by the Collections class.)
There is a useful util class called CollectionUtils from Apache commons-collections bundle. With using it the code will look like:
if(CollectionUtils.isEmpty(collection))
It looks nice and under the hood it has the same invocation:
public static boolean isEmpty(Collection coll) {
return coll == null || coll.isEmpty();
}
null means list is initialized with null. null list size or isEmpty will throw NullPointerException. But, not null list can be empty or size==0
(list!=null) != (list.size()==0)
size==0 and isEmpty is equivalent.
(list.size()==0) == list.isEmpty()
There can be multiple approaches to handle this:
1: If code makes sure that collection cannot be null by initializing it either in constructor or as field initializaiton then caller need not to ideally check for null everywhere. Only isEmpty check should suffice:
private List<Integer> numbers = new ArrayList<Integer>(); //or in constructor
// caller can then safely use
if(numbers.isEmpty)
2: Alternatively write a utility method to have null and empty check, no need for size check as it already happens inside isEmpty call. Use this utility method elsewhere in code.
public static boolean empty(Collection<?> col) {
return col == null || col.isEmpty();
}
It depends on your program structure. For example, I have a helper class called ArrayUtils, in which I have an API that looks like this:
public static <E> boolean isEmpty(final Collection<E> collection)
{
return collection == null || collection.isEmpty();
}
I use this one when I know that I may get a null list, but when I'm absolutely sure it's not null, I use only if ( collection.isEmpty ). Improves code readability, too.
collection.size() > 1 is redundant, because you have the other APIs at your disposal.
If it you are owner of the codebase, I would avoid using such logic at all.
Instead try to follow the model when your collection supplier can't return null but has a reference to Collections.emptyXXX or just regular empty container empty.
You can do it with two predicates as below :
public static final Predicate<String> NULL_OR_EMPTY = (in) -> null == in || "".equals(in);
public static final Predicate<List<String>> STRING_LIST_NULL_OR_EMPTY = (strList) -> strList.stream().filter(NULL_OR_EMPTY).collect(Collectors.toList()).size() > 0;
I have an arrayList called A, say, which is non-empty.
I create another arrayList, B, and put in some elements of A.
for(someobject obj : A){
if(some_condition_is_met)
B.add(obj);
}
Then I do some stuff with B (never modifying, shuffling, or deleting objects from it. I pick an element of B, say B.get(i).
Now, I want to find B.get(i)'s position in A.
I tried
for(someobject obj : A){
if(obj.equals(B.get(i))
return A.lastIndexOf(obj);
}
return null;
But this kept returning null. That is, "equals" doesn't match the objects.
SO in my frustration I tried:
return A.get(A.lastIndexOf(B.get(i));
which caused an ArrayINdexOutOfBounds exception.
Any ideas what I should do? I've got a feeling I'm missing something obvious.
One more point - this is an incredibly simplified explanation of what I'm doing. In the above example creating B might seem pointless, but it is necessary.
ANSWERS TO QUESTIONS:
1)The objects are custom objects. Ah,... I didn't override equals. That might be it.
2) I can be sure any object in B mst B in A because on creating B, first I remove all from it, just in case, then I add only object from A and I do not tamper with the objects once in B.
The principle of what you are trying to do should work. I could make the quibble that there is little point in doing the FOR loop to search through A to find an instance of the object from B, and then doing a lastIndexOf on it. lastIndexOf will iterate through A anyway. You are searching for something, and then when you find it you are just leaving it where it lies and searching for it all over again. (Admittedly, your first search is from the beginning of A while lastIndexOf will search from the end. So this is like looking for your car keys starting in the basement and working up to the attic. Then when you find them, you leave them there, and then go to the attic and start the search again working your way down to the basement.)
I suspect that the problem is not in the concept, but in the details. You might show the actual code. If the code is too complex, try simplifying it down to the essentials and see if the error still occurs.
One possibility: Do you really add the object from A to B directly? Or are you creating a new object for B that is a copy of the object from A? If the latter, then unless you override equals() it's not going to work, because the default equals() for a user-defined object just checks if they are the same instance, not "equivalent" objects.
Where are you getting i from in your second code block, and are you checking it against the size of B? i.e.
for(someobject obj : A){
if(obj.equals(B.get(i))
return A.lastIndexOf(obj);
}
return null;
What was the value of i, the size of B when you did return A.get(A.lastIndexOf(B.get(i)); and got the ArrayIndexOutOfBounds?
Do this simple test after you populate A and B, to check that they have the expected values ...
for (Object o : B)
{
System.out.println(A.lastIndexOf(o));
}
If you have problems at this stage, you likely have some problem constructing your objects. Also make sure you're not swallowing exceptions anywhere.
Override equals() and hashcode() methods in your object
#Override
public boolean equals(Object o) {
boolean result = false;
if (o instanceof Someobject ) {
Someobject other = (Someobject ) o;
result = attribute.equalsIgnoreCase(other.attribute);
}
return result;
}
#Override
public int hashCode() {
return attribute.hashCode();
}
It seems that B contains different objects from A. Are you sure, that equals method is correct in your objects? And you haven't modified objects in B (or A)?
Is it possible that some_condition_is_met is always false ? If so, this would perfectly explain the whole use case -- except for B.get(i) which would always return an IndexOutOfBoundsException no matter what i is.
So, after running the first loop, can you try a B.isEmpty() check ?
You need to make sure two things are happening here.
Write your objects equals and hashcode functions correctly.
Use .indexOf() instead
If you post some more code I am sure we can help more.
Did you implement equals() and hashcode() in the class being added to the list?
Sounds like the standard deep/shallow copy issue and exactly what are you comparing - addresses or values of the object in the ArrayList. Determine that and follow the advice of others about the equals and hashCode overrides