indexOf can find null - java

This is my implementation of the indexOf method (custom arraylist class)
public int indexOf(String string) {
for(int i = 0; i < size; i++) {
if(strings[i].equalsIgnoreCase(string)){
return i;
}
}
return -1;
}
This is the code that should return null, but which doesn't. I don't understand why
public void indexOf_can_find_null() {
StringArrayList lst = list("1", "2", null, "3", "4", "3", "2", "1");
assertEquals(2, lst.indexOf(null));
}

This will never work. You cannot use the equalsIgnoreCase() to test for null.
The equalsIgnoreCase() method does a comparison on the the VALUES of the strings. A null string has no value. When you use null you are saying that this String object does not reference anything, hence it has no value, therefore nothing with a value can ever be equal to it. If you had a null object BEFORE calling equalsIgnoreCase(), then a NullReferenceException would be thrown, so it doesn't work in either direction.
If you used the == operator it would allow you to test the reference of the string, which null would work out, however this cannot be used for string comparison. If you really wanted this to work you'd need to combine the methods:
if(strings[i] != null && strings[i].equalsIgnoreCase(string))
return i;
else if(strings[i] == null && string == null)
return i;

Because of NullPointerException. When i=2, strings[i] is null, then strings[i].equalsIgnoreCase(string) will throw a NullPointerException.
PS: without the code of list(), this is just a wild guess

In your case, when i = 2, you'll have:
string[2].equalsIgnoreCase(string) evaluates to null.equalsIgnoreCase(string)
This will throw a null pointer exception as a null reference is used.

Related

java for loop that runs list executes only once

The for loop in the code below only executes once. I was looking at similiar questions but those have something that breaks it like editing the list in the loop while I dont.
public String getProfileList(JSONObject obj, String uuid) {
JSONObject profile = (JSONObject) obj.get("profiles");
#SuppressWarnings("unchecked")
ArrayList<String> list = new ArrayList<String>(profile.keySet());
System.out.println(list);
for (String object: list) {
System.out.println(object);
String isUUID = (String) ((JSONObject) profile.get(object)).get("mpm-data:uuid");
System.out.println(object + " == " + isUUID);
if (isUUID.equals(uuid)) {
System.out.println("TRUE");
return object;
}
}
System.out.println("no profile found.");
return null;
}
This code outputs this:
[5fb4acd48e7d422eabecd82e32fb03c6, 44d01181eae635d31f2cefe5e1f75cd4,e0e96e422659dfdc1ad16d53a37ee618, a3ae7136f900457290e99bd657db0385]
5fb4acd48e7d422eabecd82e32fb03c6
5fb4acd48e7d422eabecd82e32fb03c6 == null
For your console output you can see that isUUID is null. This means that when you attempt to call its method equals there is actually no object to call it to and you should be getting a NullPointerException. That's why it is best to do equals assertions with the part you know will not be null on the left side:
uuid.equals(isUUID) would be better.
Notice that if you do an equals assertion with a variable and a static string then it is best to do it like so:
"myCompareString".equals(myVariable), since "myCompareString" can never be null whereas myVariable can.
if (isUUID.equals(uuid)) will throw a nullPointerException when isuuid is null.
You should check if the data is right, and handle the exception.
And you can use StringUtils.equals(String str1, String str2) in commons-lang.jar, then you don't need to handle the null yourself, see http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/StringUtils.html
System.out.println(object + " == " + isUUID);
Code prints
5fb4acd48e7d422eabecd82e32fb03c6 == null and next statement you are using in if condition .If isUUID is null it should throw null pointer exception.Can you please check this point
if (isUUID.equals(uuid)) {
System.out.println("TRUE");
return object;
}

java find the smallest of two numbers coming from two different object types when one can be null

I'm trying to figure out the best way of grabbing the smallest of two numbers when the numbers are attributes inside of two different objects. Each, but not both, of the objects can be null, which can lead to null pointer exceptions. Each object has their own getValue() method, which will return a Long value. There's the basic if/else that I'd prefer not to do:
if (obj1 != null && obj2 != null) { // neither object is null
minValue = obj1.getValue() <= obj2.getValue() ? obj1.getValue() : obj2.getValue();
} else if (obj1 == null && obj2 != null) { // only obj1 is null
minValue = obj2.getValue();
} else { // only obj2 is null (they can't both be null, so we don't need an if for the situation where they're both null)
minValue = obj1.getValue();
}
I've tried some other things:
// can throw null pointer exception
Collections.min(Arrays.asList(obj1.getValue(), obj2.getValue()));
// while both objects have a getValue() method, they are of different types, so mapping doesn't work
Collections.min(Arrays.asList(obj1, obj2)
.filter(obj -> obj != null)
.map(obj -> obj.getValue()) // this line will fail since the methods correspond to different objects
.collect(Collectors.toList()));
I feel like this should be a fairly easy problem, but my brain's not allowing it to work. There's due to be some min function where you can bipass a situation where the object can be null?
long minValue = Math.min(obj1 == null ? Long.MAX_VALUE : obj1.getValue(),
obj2 == null ? Long.MAX_VALUE : obj2.getValue());
I am not sure I fully understand your question, but if I do, something like this could work:
if(obj1 == null)
minValue = obj2.getValue();
else if(obj2 == null)
minValue = obj1.getValue();
else minValue = obj1.getValue() < obj2.getValue() ? obj1.getValue() : obj2.getValue();
You could have a method that takes in your ObjType, does a null check and returns Long.MAX_VALUE, or the value if it's null.
public Long getVal(ObjType val)
{
if(val != null)
{
return val.getValue();
}
return Long.MAX_VALUE;
}
then do
Math.min(obj1, obj2);

How to check null on StringBuilder?

I want to check for null or empty specifically in my code. Does empty and null are same for StringBuilder in Java?
For example:
StringBuilder state = new StringBuilder();
StringBuilder err= new StringBuilder();
success = executeCommand(cmd, state, err);
/* here executeCommand() returns empty or null in state, I cant make changes in <br/> executeCommand() so can I check it in my code somehow for state, if its null or empty? */<br/>
if (state == null) { //do blabla1 }
if (state.tostring().equals("")) { //do blabla2 }
Does above code make sense or how should I change it?
No, null and empty are different for StringBuilder.
StringBuilder nullBuilder = null;
if(nullBuilder == null) {
System.out.println("Builder is null");
}
&
StringBuilder emptyBuilder = new StringBuilder("");
if(emptyBuilder == null || emptyBuilder.toString().equals("")) {
System.out.println("Builder is empty");
}
In Java, null is a reference literal. If a variable is null then is not referring to anything.
So, if you have StringBuilder s = null, that means that s is of type StringBuilder but it is not referring to a StringBuilder instance.
If you have a non-null reference then you are free to call methods on the referred object. In the StringBuilder class, one such method is length(). In fact if you were to call length() using a null reference then the Java runtime will throw a NullPointerException.
Hence, this code is quite common:
If (s == null || s.length() == 0/*empty if the length is zero*/){
// do something
It relies on the fact that evaluation of || is from left to right and stops once it reaches the first true condition.
Null mean, there are no object in the heap for that reference variable. This is common to all java object, not specific to StringBuilder and Empty means, "".
In your code, you have created a StringBuilder object, so checking null is redundant. And, You can check empty by using isEmpty() method in from java String api
if(state.tostring().isEmpty()) {
//
}
And checking null is correct. Find the corrected version here
if (state == null) {
// ...bla 1
} else if (state.tostring().isEmpty()) {
//... bla 2
}
Your second if condition will throw NullPointerException, if the state is null. So if should be nested with if else
No. empty means, that there are no characters in the StringBuilder. null means that there is no StringBuilder object at all.
A variable is only null if it has a reference type (for example String, StringBuilder, Set, as a thumbrule: all capitalized types) and it is not initialised yet or has been set explicitly to null.
The below code may help you,
StringBuffer sb = new StringBuffer();
String str = sb.toString();
if(!"".equals(str)) {
System.out.println("String : " + str);
} else {
System.out.println("Empty Builder");
}
You can try like this
StringBuilder state = new StringBuilder();
if(StringUtils.isNotBlank(state .toString())){
//this will check for null, " ", ""
}

Confuse "==null" and "==" "" in java?

I have a simple issue related ==null and =="" ,i think everybody know this issue .
Here's an example:
#SuppressWarnings("unchecked")
public void reorderingCriteia() {
ListModelList<ReorderData> headerList = new ListModelList<ReorderData>();
List<String> headerId = new ArrayList<String>();
String userReorderSelection = Services.userPreferenceService().getUserPreference().getUserOption("PROCESS_CHECKLIST_COLUMN_REORDER");
if (userReorderSelection == null || userReorderSelection == "") {
int i = 0;
for (ReorderData rd : availableReorderList) {
headerList.add(rd);
headerId.add("" + i);
i++;
}
folderProcessModel.setHeaderList(headerList);
folderProcessModel.setHeaderId(headerId);
} else {
headerList = ReorderDialogViewModelNew.jsonStringToList("FOLDER_PERMIT_LIST_COLUMN_REORDER", userReorderSelection, false);
headerId = compHelper.intializeSequnce(headerList, folderProcessModel.getAvailableHeaders());
folderProcessModel.setHeaderList(headerList);
folderProcessModel.setHeaderId(headerId);
}
}
I have some questions:
Here this code use if (userReorderSelection == null || userReorderSelection == ""). Can i use this condition if (userReorderSelection == null) ?
What is the difference between two ?
== null checks for null reference.
== "" check for blank/empty string reference. Here you could use str.equals("") to check if the string is empty/blank or not. == is used for object reference checks. Or you can use the String.isEmpty() to check the same.
Also, if you use just if (userReorderSelection == null), then you'll only be checking if the userReorderSelection is null or not and it won't determine whether the String is empty or not.
As everyone replied:
"" checks for empty String.
null checks for null reference.
Use StringUtils from apache commons to eliminate two conditions. StringUtils.isEmpty(yourVariable) this condition will handle both cases.
"" --> indicates empty String in Java. Rather than using userReorderSelection == "" it is preferable to us
userReorderSelection.isEmpty() // But make sure that userReorderSelection is not null
null --> indicates Null references (can be reference of any object)
If you do not have this check it may result in NullPointerException if you try to use this reference. Empty String will not throw such exceptions.
== null checks to see if the object reference is null.
== "" checks to see if the object reference equals a blank string
str.equals ("") checks to see if your String object contains the empty string.
I guess what you want is
if (userReorderSelection == null || userReorderSelection.equals (""))

How to handle null in Pattern.compile?

How to handle null when using Pattern.compile? I'm using the following line to compare strings:
Pattern.compile(Pattern.quote(s2), Pattern.CASE_INSENSITIVE).matcher(s1).find()
There are some cases where s1 can be null and obviously it throws NullPointerException. I know this could be handled by another if condition to s1, but I would like to know is there's an alternate solution.
EDIT
Iterator iter = sampleList().iterator();
while (iter.hasNext()) {
SampleObj so = (SampleObj) iter.next();
if (!s1.equalsIgnoreCase("")) {
if (Pattern.compile(Pattern.quote(s1), Pattern.CASE_INSENSITIVE).matcher(so.getS1()).find())
match = true;
else
match = false;
}
if (!s3.equalsIgnoreCase("")) {
if (Pattern.compile(Pattern.quote(s3), Pattern.CASE_INSENSITIVE).matcher(so.getS3()).find())
match = true;
else
match = false;
}
}
s1 and s3 are inputs which are matched over iterator.
You have to check for null; e.g.,
if(s1 != null && Pattern.compile(Pattern.quote(s2), Pattern.CASE_INSENSITIVE).matcher(s1).find()))
Pattern.matcher() will always throw a NullPointerException when you pass in null, so: no, there is no other way, you'll have to check for null explicitly.
I use
String.valueOf(s1)
which results in having "null" instead of null.

Categories

Resources