Java ArrayList contains method - java

#Override
public boolean contains(Object object) {
if (object != null) {
for (E element : a) {
if (object.equals(element)) {
return true;
}
}
} else {
for (E element : a) {
if (element == null) {
return true;
}
}
}
return false;
}
I am learning java and I am looking into the source code to find out how certain methods are being written. I would like to ask why is there a need to write
else {
for (E element : a) {
if (element == null) {
return true;
}
}
}
Thank you

Yes there is.
If object is null, object.equals(element) will throw a NullPointerException
So the case where object is null is handled in a separate loop.

Input argument can be null or not null.
If it's null then we need to iterate through all list elements and return true if there is null in the array.
And we have to use == operator, because equals will throw NullPointerException.

I would like to ask why is there a need to write
else {
[...]
Because otherwise, the method would always return false in the event that the condition of the if statement (object != null) is not satisfied, but that is inconsistent with the method's contract / documentation. Many Java List implementation can contain the value null as an element, and when they do, contains(null) must return true for them.
That is handled in a separate branch because when object is null, any attempt to invoke a method on it, such as equals() will cause a NullPointerException to be thrown. The approach in the if block therefore cannot be applied in that case.

List is a collection that allows insertion of null referenced objects into it.
the algorithm meant to tell you that if you have at least null in the list and you ask/search a null object later then it will return true at the 1st match....

because .equals() comparison method cannot be invoked on null and if you would invoke then null.equals(SOMETHING); will throw a NullPointerException. So here old traditional way comes to the rescue! use == comparison operator.

Many methods in Collections Framework interfaces are defined in terms of the equals method. For example, the specification for the contains(Object o) method says: "returns true if and only if this collection contains at least one element e such that (o==null ? e==null : o.equals(e))." This specification should not be construed to imply that invoking Collection.contains with a non-null argument o will cause o.equals(e) to be invoked for any element e. Implementations are free to implement optimizations whereby the equals invocation is avoided, for example, by first comparing the hash codes of the two elements. (The Object.hashCode() specification guarantees that two objects with unequal hash codes cannot be equal.) More generally, implementations of the various Collections Framework interfaces are free to take advantage of the specified behavior of underlying Object methods wherever the implementor deems it appropriate.
Refer:https://docs.oracle.com/javase/7/docs/api/java/util/Collection.html

There is a need to write else { ... because the if condition holds true only if the arg 'object' is not null.

In this case your contains() method implemented to check if object value is null or not, if it is null return true otherwise false. Implementing this method give you a opportunity to check any object(passing object as a parameter) value(using if condition or any other condition). Later on when you want to check values is there or not if it is have value you can do manipulation on object.
In ArrayList contains():
The ArrayList.contains(Object) method returns true if this list contains the specified element.
ArrayList<Integer> listObj = new ArrayList<Integer>();
listObj.add(1);
listObj.add(2);
System.out.println("Contains : "+listObj.contains(1));
This method more important check element and do somework if it is true. As a example,
if(listObj.contains(2)){
int index=arrlist.indexOf(2);
listObj.remove(index);
}
What is happening here is that the value(object) pass as the parameter is not a null value,
public boolean contains(Object object) {
if (object != null) {
then go through the ArrayList element,
for (E element : a) {
is equal to pass value,
if (object.equals(element)) {
return true
Otherwise(if object is null) go with the else block.
Throws:
ClassCastException - if the type of the specified element is incompatible with this list.
NullPointerException - if the specified element is null and this list does not permit null elements.
read more
Let's say object is a String:
This contains() method also in String class. Little bit different scenario but concept is same.
when you wish to check if one String contains a specific substring.
String word= "Hey there how are you";
if(word.contains("you")){
System.out.println("I am fine!");
}

Related

How do I change the Java Set's retainall method to use the equals method instead of the == operator?

I am trying to test whether two HashSets of Strings contain identical Strings. The retainAll() method of Java Sets (which, as I understand it, implements the Collection interface) is a good way to check the intersection of two Sets. However, this method seems to test for equality using the == style check for whether they are references to the same memory object, rather than using the String's equals() method to check whether the contents are the same. Is there a way to get something the works like retainAll but that uses the equals() method?
I am trying to write code that checks whether a String contains a substring over a certain length from a certain other String. My strategy was to create a HashSet of each String containing all substrings of that length, then check whether the Sets contain Strings in common.
My current solution was to create my own static method that does what I want the retainAll method to do.
static boolean containsEqualElement(Set SetOne, Set SetTwo) {
Iterator it = SetOne.iterator();
while (it.hasNext()) {
Object thisComp = it.next();
Iterator it2 = SetTwo.iterator();
while (it2.hasNext()) {
if (it2.next().equals(thisComp)) {
return true;
}
}
}
return false;
}
I'm not sure how the efficiency of this method compares to the retainAll method.
This statement from your question:
However, this method seems to test for equality using the == style check for whether they are references to the same memory object, rather than using the String's equals() method to check whether the contents are the same
is wrong. retainAll does use contains, which in turn uses equals.
I don't fully understand your use case, but I think you might find the Collections.disjoint method more useful than retainAll. From the docs:
Returns true if the two specified collections have no elements in common.
You could use it like this:
if (!Collections.disjoint(setOne, setTwo)) {
// sets have at least one element in common
}
I'm proposing you use this method because retainAll modifies the set on which it's invoked on. Actually, it removes all the elements from this collection that are not contained in the argument collection. And from your code, it doesn't seem like you want this behavior.
Actually retainsAll use contains that itself use equals, at least the standard version. Maybe you actually used an IdentityHashMap instead that would indeed use the memory reference for equality, but that would be because you asked for it.
public boolean [More ...] retainAll(Collection<?> c) {
boolean modified = false;
Iterator<E> e = iterator();
while (e.hasNext()) {
if (!c.contains(e.next())) {
e.remove();
modified = true;
}
}
return modified;
}
public boolean [More ...] contains(Object o) {
Iterator<E> e = iterator();
if (o==null) {
while (e.hasNext())
if (e.next()==null)
return true;
} else
while (e.hasNext()
if (o.equals(e.next()))
return true;
}
return false;
}
Next time, please consider using the debugger to double check (even code from the JDK) or google it (like HashSet.retainAll code source) you would find something like that: http://grepcode.com/file/repository.grepcode.com/java/root/jdk/openjdk/6-b14/java/util/HashSet.java
This is what I did to respond to your question.
If you check OpenJDK9 source code, you can see that retainAll() uses AbstractCollection.contains(Object o):
public boolean retainAll(Collection<?> c) {
Objects.requireNonNull(c);
boolean modified = false;
Iterator<E> it = iterator();
while (it.hasNext()) {
if (!c.contains(it.next())) {
it.remove();
modified = true;
}
}
return modified;
}
Documentation of contains() says:
Returns true if this collection contains the specified element. More formally, returns true if and only if this collection contains at least one element e such that (o==null ? e==null : o.equals(e)).
Hence retainAll() is based on equals() check, which is what you want.

what must be hashcode of null objects in Java?

According to a comment from this post, hascode of null objects can throw NPE or a value of zero. This is implementation specific. but within the same implementation, why does
Objects.hashcode and hascode(instance) return different values. for ex:
public class EqualsTesting {
public static void main(String[] args){
String p1 =null;
String p2 = null;
System.out.println(Objects.hashCode(p1));
System.out.println(p2.hashCode());
}
}
Output:
0
Exception in thread "main" java.lang.NullPointerException
at BinaryTrees.EqualsTesting.main(EqualsTesting.java:14)
If this is the case, will this not affect the key look-up in HashMap where null Key-value pairs are allowed. (It might either hash to bucket 0 or throw a NPE)
How would you calculate hashCode of an object that doesn't even exists? When p2 is null, invoking any method on it will throw a NPE. That isn't giving you any particular value of a hashCode.
Objects.hashCode() is just a wrapper method, which performs a pre-check for null values, and for reference that is not null, it returns the same value as p2.hashCode() as in this case. Here's the source code of the method:
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}
If you will search around, you'll notice that HashMap has a special handling for null keys. null values are fine as you don't compute hash code for them in a HashMap. This is the reason why null keys work fine in HashMap. As to why Objects.hashCode works fine, take a look at Rohit's answer.
As the javadoc says:
Objects.hashCode(Object o)
Returns the hash code of a non-null argument and 0 for a null
argument.
p2.hashCode() throws a NullPointerException because you are trying to access a method of a null object.
According to a comment from this post, hascode of null objects can throw NPE or a value of zero.
That is not true. (And it is not what #Bohemian's comment is saying!)
What happens in HashMap and HashSet is that they treat null as a special case. Instead of calling hashcode() on the null object (which would NPE!!), they use zero in as a hard-coded alternative hashcode.
I stress ... this is special case behaviour of HashMap and HashSet ... not hashcode().
As your example shows, if you do attempt to call the hashcode() method on null, you will get an NPE. The JLS says that that is what will happen ... and it happens whenever you try to invoke any instance method on null.
(On the other hand, the Objects.hashCode(obj) method does deal with the case where obj is null as a special case. And that's the whole point of the static method!)
The hash code of null is 0 (see Objects.hash())
public static int hashCode(Object a[]) {
if (a == null)
return 0;
int result = 1;
for (Object element : a)
result = 31 * result + (element == null ? 0 : element.hashCode());
return result;
}
0 is hard coded value for null in Hashmap. You can see the following actual implementations done in HashMap and Objects java classes.
from HashMap.java
static final int hash(Object key) {
int h;
return (key == null) ? 0 : (h = key.hashCode()) ^ (h >>> 16);
}
from Object.java
public static int hashCode(Object o) {
return o != null ? o.hashCode() : 0;
}

Does java.util.List.isEmpty() check if the list itself is null? [duplicate]

This question already has answers here:
What is a NullPointerException, and how do I fix it?
(12 answers)
Closed 5 years ago.
Does java.util.List.isEmpty() check if the list itself is null, or do I have to do this check myself?
For example:
List<String> test = null;
if (!test.isEmpty()) {
for (String o : test) {
// do stuff here
}
}
Will this throw a NullPointerException because test is null?
You're trying to call the isEmpty() method on a null reference (as List test = null;). This will surely throw a NullPointerException. You should do if(test!=null) instead (checking for null first).
The method isEmpty() returns true, if an ArrayList object contains no elements; false otherwise (for that the List must first be instantiated that is in your case is null).
You may want to see this question.
I would recommend using Apache Commons Collections:
https://commons.apache.org/proper/commons-collections/apidocs/org/apache/commons/collections4/CollectionUtils.html#isEmpty-java.util.Collection-
which implements it quite ok and well documented:
/**
* Null-safe check if the specified collection is empty.
* <p>
* Null returns true.
*
* #param coll the collection to check, may be null
* #return true if empty or null
* #since Commons Collections 3.2
*/
public static boolean isEmpty(Collection coll) {
return (coll == null || coll.isEmpty());
}
No, java.util.List.isEmpty() doesn't check if a list is null.
If you are using the Spring framework you can use the CollectionUtils class to check if a list is empty or not. It also takes care of the null references. Following is the code snippet from Spring framework's CollectionUtils class.
public static boolean isEmpty(Collection<?> collection) {
return (collection == null || collection.isEmpty());
}
Even if you are not using Spring, you can go on and tweak this code to add in your AppUtil class.
This will throw a NullPointerException - as will any attempt to invoke an instance method on a null reference - but in cases like this you should make an explicit check against null:
if ((test != null) && !test.isEmpty())
This is much better, and clearer, than propagating an Exception.
Invoking any method on any null reference will always result in an exception. Test if the object is null first:
List<Object> test = null;
if (test != null && !test.isEmpty()) {
// ...
}
Alternatively, write a method to encapsulate this logic:
public static <T> boolean IsNullOrEmpty(Collection<T> list) {
return list == null || list.isEmpty();
}
Then you can do:
List<Object> test = null;
if (!IsNullOrEmpty(test)) {
// ...
}
In addition to Lion's answer, I can say that you better use if(CollectionUtils.isNotEmpty(test)){...}.
This also checks for null, so a manual check is not needed.
Yes, it will throw an Exception. Maybe you are used to PHP code, where empty($element) does also check for isset($element). In Java this is not the case.
You can memorize that easily, because the method is directly called on the list (the method belongs to the list). So if there is no list, then there is no method. And Java will complain that there is no list to call this method on.
You can use your own isEmpty (for multiple collection) method too. Add this to your Util class.
public static boolean isEmpty(Collection... collections) {
for (Collection collection : collections) {
if (null == collection || collection.isEmpty())
return true;
}
return false;
}

What should int compareTo() return when the parameter string is null?

It is said that when input parameter is null, compareTo() should throw a NullPointerException. However, I am implementing a class which needs to compare fields with the type of String. These fields need not to be mandatory. I wonder in this case,
1) What should I return when the input is null? Should any not-null strings lexicographically bigger or smaller than null?
and
2) If this is considered bad practice, is there any supporting arguments? Should I force the user to use empty strings instead? If using empty string, won't that confuse the case in which the field is not applicable and the case in which the field is empty? And if exception must be thrown, then except from warning the user in the manual, what else could/shall I do?
EDIT: I might not express myself clearly here, but in the program I am implementing, the strings that could be null are all fields or a class, which should not be null. In other words, the objects comparedTo() uses could not be null, just their private fields could be. So in this case, I believe if I implement compareTo() properly, it would not violate the transitive requirement since classes with null fields would be considered the same always. Am I right or am I interpreting this wrong?
Thank you all for the answers!
From javadoc for Comparable
Note that null is not an instance of
any class, and e.compareTo(null)
should throw a NullPointerException
even though e.equals(null) returns
false.
Yes, there is no problem allowing null for instance fields - just make sure its sorting order is defined. Most natural would be putting it either before or after all real strings, but you could do anything here, just do it consistently. (For example, you could sort null like "null".)
Here is an example implementation for a single member:
class Example implements Comparable<Example> {
#Nullable
private String member;
// TODO: getter, setter, constructor, ...
public int compareTo(Example that) {
if(this.member == null)
if(that.member == null)
return 0; //equal
else
return -1; // null is before other strings
else // this.member != null
if(that.member == null)
return 1; // all other strings are after null
else
return this.member.compareTo(that.member);
}
}
Please note that the specification of Comparable.compareTo() only has a constraint for o.compareTo(null) (which should behave just like - null.compareTo(o), i.e. throw a NullPointerException), but not about how null fields are handled (it doesn't mention fields at all, so a class could return whatever it wants, as long as the antisymmetry, reflexivity and transitivity is ensured).
It would be a bad practice to not throw an exception because it violates the transitive antisymmetric nature of compareTo.
From Comparable.compareTo documentation:
The implementor must ensure
sgn(x.compareTo(y)) ==
-sgn(y.compareTo(x)) for all x and y. (This implies that x.compareTo(y) must
throw an exception iff y.compareTo(x)
throws an exception.)
The implementor must also ensure that
the relation is transitive:
(x.compareTo(y)>0 && y.compareTo(z)>0)
implies x.compareTo(z)>0.
Finally, the implementor must ensure
that x.compareTo(y)==0 implies that
sgn(x.compareTo(z)) ==
sgn(y.compareTo(z)), for all z.
More importantly, it's a bad idea to use compareTo on your objects to compare them with strings, for the same reason: sign(obj.compareTo(str)) != -sign(str.compareTo(obj)). Implement a custom Comparator and do whatever you want in it.
You need to decide if null is greater-than or less-than to a non-null value. You can design compareTo to meets the needs of your class's natural ordering, thus it is not bad practice.
Because the documentation of compareTo states that it should throw a NullPointerException, you should follow those guidelines so your implementation is consistent with the interface documentation. This also handles the questions of whether or not non-null strings are lexicographically smaller or bigger than null.
You have a couple of options on how to handle this. If empty and not-applicable are different, then you should probably wrap the string field in your own field class. For example, say you could create a type of MyField that might have an isApplicable method, which indicates if the field is applicable to this case (or something similar). Or you could rethink your design and be sure that an empty string and N/A really are two different things. If they are, you do need a way to differentiate between the two.
In addition to Paulo Ebermann's accepted answer, if you need to handle ASC/DESC order, you would do this. (We're assuming that NULLs always come before Non-NULLs in normal ascending order, otherwise for descending.)
final boolean sortAsc = false; // Suppose this TRUE/FALSE is for ASC/DESC
objects.sort(new Comparator<Example>() {
#Override
public int compare(Example e1, Example e2) {
if (e1.getMember() == null && e2.getMember() == null) {
return 0; // Both NULLs are equal
}
else if (e1.getMember() == null && e2.getMember() != null) {
return sortAsc ? -1 : 1; // NULLs should precede non-NULLs in ascending order, follow in descending order
}
else if (e1.getMember() != null && e2.getMember() == null) {
return sortAsc ? 1 : -1; // Non-NULLs should follow NULLs in ascending order, precede in descending order
} else {
// Both non-NULLs
return sortAsc ? e1.getMember().compareTo(e2.getMember())
: e2.getMember().compareTo(e1.getMember());
}
}
});

Best Practice in handling comparator

How to handle null objects, which comes in compareTo method. This always causes nullpointer exception. What a is best way to solve this issue.
public int compareTo(Object to) {
if (to == null) return Integer.MIN_VALUE;
// Now knowing it's not null, continue as before
}
You can check the object before you call "compareTo" method.
like this:
if(obj != null){
//TODO
}
From the fine documentation on Comparable:
Note that null is not an instance of any class, and e.compareTo(null) should throw a NullPointerException even though e.equals(null) returns false.
Don't put null in a sorted collection if you don't want to handle NullPointerExceptions.

Categories

Resources